//! 插件系统模块
//! 
//! 支持插件加载、卸载、生命周期管理等功能

use anyhow::{Context, Result};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use chrono::{DateTime, Utc};

/// 插件元数据
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PluginManifest {
    /// 插件唯一标识
    pub id: String,
    /// 插件名称
    pub name: String,
    /// 插件描述
    pub description: String,
    /// 插件版本
    pub version: String,
    /// 作者
    pub author: String,
    /// 最低 ReadFlow 版本要求
    pub min_readflow_version: Option<String>,
    /// 插件入口点（WASM 文件路径）
    pub entry_point: Option<String>,
    /// 依赖的其他插件
    pub dependencies: Vec<String>,
    /// 插件配置项
    pub config_schema: Option<serde_json::Value>,
}

/// 插件状态
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum PluginStatus {
    /// 已禁用
    Disabled,
    /// 已启用
    Enabled,
    /// 加载中
    Loading,
    /// 运行中
    Running,
    /// 错误
    Error(String),
}

/// 插件信息
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PluginInfo {
    pub manifest: PluginManifest,
    pub path: PathBuf,
    pub status: PluginStatus,
    pub loaded_at: Option<DateTime<Utc>>,
    pub config: serde_json::Value,
}

/// 插件 trait - 定义插件接口
pub trait Plugin: Send + Sync {
    /// 获取插件 ID
    fn id(&self) -> &str;
    
    /// 插件初始化
    fn initialize(&mut self) -> Result<()> {
        Ok(())
    }
    
    /// 插件激活
    fn on_activate(&mut self) -> Result<()> {
        Ok(())
    }
    
    /// 插件停用
    fn on_deactivate(&mut self) -> Result<()> {
        Ok(())
    }
    
    /// 插件卸载
    fn on_uninstall(&mut self) -> Result<()> {
        Ok(())
    }
}

/// 插件管理器
pub struct PluginManager {
    /// 插件存储路径
    plugins_dir: PathBuf,
    /// 已加载的插件
    plugins: HashMap<String, PluginInfo>,
    /// 插件注册表
    registry: HashMap<String, Arc<dyn Plugin>>,
}

impl PluginManager {
    /// 创建插件管理器
    pub fn new(plugins_dir: &str) -> Result<Self> {
        let plugins_dir = PathBuf::from(plugins_dir);
        
        // 创建插件目录（如果不存在）
        if !plugins_dir.exists() {
            std::fs::create_dir_all(&plugins_dir)?;
        }
        
        Ok(Self {
            plugins_dir,
            plugins: HashMap::new(),
            registry: HashMap::new(),
        })
    }
    
    /// 获取插件目录
    pub fn plugins_dir(&self) -> &Path {
        &self.plugins_dir
    }
    
    /// 扫描插件目录
    pub fn scan_plugins(&mut self) -> Result<Vec<PluginManifest>> {
        let mut manifests = Vec::new();
        
        if !self.plugins_dir.exists() {
            return Ok(manifests);
        }
        
        for entry in std::fs::read_dir(&self.plugins_dir)? {
            let entry = entry?;
            let path = entry.path();
            
            if !path.is_dir() {
                continue;
            }
            
            let manifest_path = path.join("manifest.json");
            if !manifest_path.exists() {
                continue;
            }
            
            let manifest_content = std::fs::read_to_string(&manifest_path)?;
            let manifest: PluginManifest = serde_json::from_str(&manifest_content)?;
            
            manifests.push(manifest);
        }
        
        Ok(manifests)
    }
    
    /// 加载插件
    pub fn load_plugin(&mut self, plugin_id: &str) -> Result<()> {
        let plugin_path = self.plugins_dir.join(plugin_id);
        
        if !plugin_path.exists() {
            anyhow::bail!("插件目录不存在：{}", plugin_id);
        }
        
        let manifest_path = plugin_path.join("manifest.json");
        let manifest_content = std::fs::read_to_string(&manifest_path)?;
        let manifest: PluginManifest = serde_json::from_str(&manifest_content)?;
        
        // 检查依赖
        for dep in &manifest.dependencies {
            if !self.registry.contains_key(dep) {
                anyhow::bail!("插件 {} 依赖未满足：{}", plugin_id, dep);
            }
        }
        
        // 创建插件信息
        let plugin_info = PluginInfo {
            manifest: manifest.clone(),
            path: plugin_path,
            status: PluginStatus::Loading,
            loaded_at: None,
            config: serde_json::Value::Object(serde_json::Map::new()),
        };
        
        self.plugins.insert(plugin_id.to_string(), plugin_info);
        
        // TODO: 加载 WASM 插件
        // let wasm_path = plugin_path.join(&manifest.entry_point.unwrap_or_else(|| "plugin.wasm".to_string()));
        
        // 模拟加载成功
        if let Some(info) = self.plugins.get_mut(plugin_id) {
            info.status = PluginStatus::Enabled;
            info.loaded_at = Some(Utc::now());
        }
        
        Ok(())
    }
    
    /// 启用插件
    pub fn enable_plugin(&mut self, plugin_id: &str) -> Result<()> {
        if let Some(info) = self.plugins.get_mut(plugin_id) {
            info.status = PluginStatus::Enabled;
            // TODO: 调用插件 on_activate
        }
        Ok(())
    }
    
    /// 禁用插件
    pub fn disable_plugin(&mut self, plugin_id: &str) -> Result<()> {
        if let Some(info) = self.plugins.get_mut(plugin_id) {
            info.status = PluginStatus::Disabled;
            // TODO: 调用插件 on_deactivate
        }
        Ok(())
    }
    
    /// 卸载插件
    pub fn uninstall_plugin(&mut self, plugin_id: &str) -> Result<()> {
        // 检查是否有其他插件依赖此插件
        for (id, info) in &self.plugins {
            if id != plugin_id && info.manifest.dependencies.contains(&plugin_id.to_string()) {
                anyhow::bail!("无法卸载插件 {}：插件 {} 依赖它", plugin_id, id);
            }
        }
        
        // 调用插件卸载回调
        if let Some(info) = self.plugins.get_mut(plugin_id) {
            info.status = PluginStatus::Disabled;
            // TODO: 调用插件 on_uninstall
        }
        
        // 从注册表移除
        self.registry.remove(plugin_id);
        
        // 从文件系统删除
        let plugin_path = self.plugins_dir.join(plugin_id);
        if plugin_path.exists() {
            std::fs::remove_dir_all(&plugin_path)?;
        }
        
        // 从内存移除
        self.plugins.remove(plugin_id);
        
        Ok(())
    }
    
    /// 获取所有插件
    pub fn get_all_plugins(&self) -> Vec<&PluginInfo> {
        self.plugins.values().collect()
    }
    
    /// 获取启用的插件
    pub fn get_enabled_plugins(&self) -> Vec<&PluginInfo> {
        self.plugins
            .values()
            .filter(|info| matches!(info.status, PluginStatus::Enabled | PluginStatus::Running))
            .collect()
    }
    
    /// 获取插件状态
    pub fn get_plugin_status(&self, plugin_id: &str) -> Option<&PluginStatus> {
        self.plugins.get(plugin_id).map(|info| &info.status)
    }
    
    /// 安装插件（从文件）
    pub fn install_plugin(&mut self, plugin_path: &Path) -> Result<String> {
        // 读取 manifest
        let manifest_path = plugin_path.join("manifest.json");
        let manifest_content = std::fs::read_to_string(&manifest_path)?;
        let manifest: PluginManifest = serde_json::from_str(&manifest_content)?;
        
        // 复制到插件目录
        let target_path = self.plugins_dir.join(&manifest.id);
        
        if target_path.exists() {
            anyhow::bail!("插件已安装：{}", manifest.id);
        }
        
        // 复制整个插件目录
        self.copy_dir_recursive(plugin_path, &target_path)?;
        
        // 加载插件
        self.load_plugin(&manifest.id)?;
        
        Ok(manifest.id.clone())
    }
    
    /// 递归复制目录
    fn copy_dir_recursive(&self, src: &Path, dst: &Path) -> Result<()> {
        std::fs::create_dir_all(dst)?;
        
        for entry in std::fs::read_dir(src)? {
            let entry = entry?;
            let src_path = entry.path();
            let dst_path = dst.join(entry.file_name());
            
            if src_path.is_dir() {
                self.copy_dir_recursive(&src_path, &dst_path)?;
            } else {
                std::fs::copy(&src_path, &dst_path)?;
            }
        }
        
        Ok(())
    }
    
    /// 导出插件列表为 JSON
    pub fn export_plugins(&self) -> Result<String> {
        let plugins: Vec<&PluginInfo> = self.get_all_plugins();
        let json = serde_json::to_string_pretty(&plugins)?;
        Ok(json)
    }
}

/// 插件配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PluginConfig {
    pub plugin_id: String,
    pub enabled: bool,
    pub settings: serde_json::Value,
}

/// 内置插件：主题切换
pub struct ThemePlugin {
    current_theme: String,
}

impl ThemePlugin {
    pub fn new() -> Self {
        Self {
            current_theme: "dark".to_string(),
        }
    }
    
    pub fn set_theme(&mut self, theme: &str) {
        self.current_theme = theme.to_string();
    }
    
    pub fn get_theme(&self) -> &str {
        &self.current_theme
    }
}

impl Plugin for ThemePlugin {
    fn id(&self) -> &str {
        "com.readflow.theme"
    }
}

/// 内置插件：快捷键
pub struct HotkeyPlugin {
    shortcuts: HashMap<String, String>,
}

impl HotkeyPlugin {
    pub fn new() -> Self {
        let mut shortcuts = HashMap::new();
        shortcuts.insert("open_file".to_string(), "Ctrl+O".to_string());
        shortcuts.insert("search".to_string(), "Ctrl+F".to_string());
        shortcuts.insert("bookmark".to_string(), "Ctrl+B".to_string());
        
        Self { shortcuts }
    }
    
    pub fn get_shortcut(&self, action: &str) -> Option<&String> {
        self.shortcuts.get(action)
    }
}

impl Plugin for HotkeyPlugin {
    fn id(&self) -> &str {
        "com.readflow.hotkey"
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[test]
    fn test_plugin_manager_creation() {
        let temp_dir = std::env::temp_dir().join("readflow_test_plugins");
        let manager = PluginManager::new(temp_dir.to_str().unwrap());
        assert!(manager.is_ok());
        
        // 清理
        let _ = std::fs::remove_dir_all(&temp_dir);
    }
    
    #[test]
    fn test_theme_plugin() {
        let mut plugin = ThemePlugin::new();
        assert_eq!(plugin.get_theme(), "dark");
        
        plugin.set_theme("light");
        assert_eq!(plugin.get_theme(), "light");
    }
}
