use std::sync::{Arc, Mutex};

use async_trait::async_trait;
use penguin_downloader::core::PenguinCore;
use penguin_downloader::traits::{MetadataProvider, MusicProvider};
use tracing::debug;

use crate::localization::LocalizationManager;
use crate::plugin::PenguinPluginManager;
use crate::Result;

/// 运行时的线程安全引用，供插件在初始化期间使用。
///
/// 提供对核心下载器、本地化系统和插件系统的访问。
/// 所有可变状态均通过内部可变性（`Arc<Mutex<...>>`）保护。
#[async_trait]
pub trait PenguinRuntimeRef: Send + Sync {
    /// 返回底层 `PenguinCore` 的版本号。
    fn get_core_version(&self) -> i64 {
        self.core().lock().unwrap().get_version()
    }

    /// 返回核心的 `Arc<Mutex<PenguinCore>>` 克隆。
    fn core(&self) -> Arc<Mutex<PenguinCore>>;

    /// 返回本地化管理器的 `Arc<Mutex<LocalizationManager>>` 克隆。
    fn localization_manager(&self) -> Arc<Mutex<LocalizationManager>>;

    /// 返回插件管理器的 `Arc<Mutex<PenguinPluginManager>>` 克隆。
    fn plugin_manager(&self) -> Arc<Mutex<PenguinPluginManager>>;

    /// 注册指定语言的翻译文本。
    ///
    /// 这是一个便捷方法，内部会自动锁定本地化管理器。
    fn register_translations(&self, lang: &str, json_content: &str) -> Result<()> {
        self.localization_manager()
            .lock()
            .unwrap()
            .register_translations(lang, json_content)
    }

    /// 向核心注册一个音源提供者。
    async fn register_music_provider(
        &self,
        provider: Arc<dyn MusicProvider>,
    ) -> Result<()> {
        self.core()
            .lock()
            .unwrap()
            .register_music_provider(provider)
            .map_err(|e| crate::error::RuntimeError::Custom(e.to_string()))
    }

    /// 向核心注册一个元数据提供者。
    async fn register_metadata_provider(
        &self,
        provider: Arc<dyn MetadataProvider>,
    ) -> Result<()> {
        self.core()
            .lock()
            .unwrap()
            .register_metadata_provider(provider)
            .map_err(|e| crate::error::RuntimeError::Custom(e.to_string()))
    }
}

/// 聚合核心下载器、本地化管理器和插件管理器的主要运行时。
///
/// 三个组件均通过 `Arc<Mutex<...>>` 持有，以便同时支持直接访问（通过 `get_*` 方法）
/// 和 trait 方式的访问（通过 `PenguinRuntimeRef`）。
pub struct PenguinRuntime {
    core: Arc<Mutex<PenguinCore>>,
    localization_manager: Arc<Mutex<LocalizationManager>>,
    plugin_manager: Arc<Mutex<PenguinPluginManager>>,
}

impl PenguinRuntime {
    /// 创建一个新的运行时实例，核心、本地化和插件状态均为空。
    pub fn new() -> Self {
        debug!("creating new PenguinRuntime");
        Self {
            core: Arc::new(Mutex::new(PenguinCore::new())),
            localization_manager: Arc::new(Mutex::new(LocalizationManager::new())),
            plugin_manager: Arc::new(Mutex::new(PenguinPluginManager::new())),
        }
    }

    /// 返回核心的 `Arc<Mutex<PenguinCore>>` 克隆。
    pub fn get_core(&self) -> Arc<Mutex<PenguinCore>> {
        self.core.clone()
    }

    /// 返回本地化管理器的 `Arc<Mutex<LocalizationManager>>` 克隆。
    pub fn get_localization_manager(&self) -> Arc<Mutex<LocalizationManager>> {
        self.localization_manager.clone()
    }

    /// 返回插件管理器的 `Arc<Mutex<PenguinPluginManager>>` 克隆。
    pub fn get_plugin_manager(&self) -> Arc<Mutex<PenguinPluginManager>> {
        self.plugin_manager.clone()
    }
}

impl Default for PenguinRuntime {
    fn default() -> Self {
        Self::new()
    }
}

#[async_trait]
impl PenguinRuntimeRef for PenguinRuntime {
    fn core(&self) -> Arc<Mutex<PenguinCore>> {
        self.core.clone()
    }

    fn localization_manager(&self) -> Arc<Mutex<LocalizationManager>> {
        self.localization_manager.clone()
    }

    fn plugin_manager(&self) -> Arc<Mutex<PenguinPluginManager>> {
        self.plugin_manager.clone()
    }
}
