use std::sync::{Arc, Mutex};
use crate::data::repositories::project_repository::ProjectRepository;
use crate::data::repositories::material_repository::MaterialRepository;
use crate::data::repositories::model_repository::ModelRepository;
use crate::data::repositories::model_dynamic_repository::ModelDynamicRepository;
use crate::data::repositories::video_generation_repository::VideoGenerationRepository;
use crate::data::repositories::conversation_repository::ConversationRepository;
use crate::data::repositories::outfit_photo_generation_repository::OutfitPhotoGenerationRepository;
use crate::infrastructure::database::Database;
use crate::infrastructure::performance::PerformanceMonitor;
use crate::infrastructure::event_bus::EventBusManager;

/// 应用全局状态管理
/// 遵循 Tauri 开发规范的状态管理模式
pub struct AppState {
    pub database: Mutex<Option<Arc<Database>>>,
    pub project_repository: Mutex<Option<ProjectRepository>>,
    pub material_repository: Mutex<Option<MaterialRepository>>,
    pub model_repository: Mutex<Option<ModelRepository>>,
    pub model_dynamic_repository: Mutex<Option<ModelDynamicRepository>>,
    pub video_generation_repository: Mutex<Option<VideoGenerationRepository>>,
    pub conversation_repository: Mutex<Option<Arc<ConversationRepository>>>,
    pub outfit_photo_generation_repository: Mutex<Option<OutfitPhotoGenerationRepository>>,
    pub performance_monitor: Mutex<PerformanceMonitor>,
    pub event_bus_manager: Arc<EventBusManager>,
}

impl AppState {
    pub fn new() -> Self {
        Self {
            database: Mutex::new(None),
            project_repository: Mutex::new(None),
            material_repository: Mutex::new(None),
            model_repository: Mutex::new(None),
            model_dynamic_repository: Mutex::new(None),
            video_generation_repository: Mutex::new(None),
            conversation_repository: Mutex::new(None),
            outfit_photo_generation_repository: Mutex::new(None),
            performance_monitor: Mutex::new(PerformanceMonitor::new()),
            event_bus_manager: Arc::new(EventBusManager::new()),
        }
    }

    /// 初始化数据库连接
    /// 遵循安全第一原则，确保数据库初始化的安全性
    /// 默认使用连接池模式以提高并发性能
    pub fn initialize_database(&self) -> anyhow::Result<()> {
        println!("开始初始化数据库连接...");

        // 暂时使用单连接模式，避免锁竞争问题
        // TODO: 在解决 SQLite 锁问题后重新启用连接池
        let database = Arc::new(Database::new()?);
        println!("使用单连接模式初始化数据库");

        // 连接池模式代码（暂时注释）
        /*
        let database = match Database::new_with_pool() {
            Ok(db) => {
                println!("连接池模式初始化成功");
                Arc::new(db)
            },
            Err(e) => {
                eprintln!("连接池模式初始化失败: {}, 回退到单连接模式", e);
                Arc::new(Database::new()?)
            }
        };
        */

        let project_repository = ProjectRepository::new(database.clone())?;
        let material_repository = MaterialRepository::new(database.clone())?;
        let model_repository = ModelRepository::new(database.clone());
        let model_dynamic_repository = ModelDynamicRepository::new(database.clone());
        let video_generation_repository = VideoGenerationRepository::new(database.clone());
        let conversation_repository = Arc::new(ConversationRepository::new(database.clone()));

        // 初始化数据库表
        model_dynamic_repository.init_tables()?;
        video_generation_repository.init_tables()?;
        conversation_repository.initialize_tables()?;

        // 初始化穿搭图片相关表
        let outfit_image_repository = crate::data::repositories::outfit_image_repository::OutfitImageRepository::new(database.clone());
        outfit_image_repository.init_tables()?;

        // 初始化穿搭照片生成相关表
        let outfit_photo_generation_repository = OutfitPhotoGenerationRepository::new(database.clone())?;

        *self.database.lock().unwrap() = Some(database.clone());
        *self.project_repository.lock().unwrap() = Some(project_repository);
        *self.material_repository.lock().unwrap() = Some(material_repository);
        *self.model_repository.lock().unwrap() = Some(model_repository);
        *self.model_dynamic_repository.lock().unwrap() = Some(model_dynamic_repository);
        *self.video_generation_repository.lock().unwrap() = Some(video_generation_repository);
        *self.conversation_repository.lock().unwrap() = Some(conversation_repository);
        *self.outfit_photo_generation_repository.lock().unwrap() = Some(outfit_photo_generation_repository);

        println!("数据库初始化完成，连接池状态: {}",
                 if database.has_pool() { "已启用" } else { "未启用" });
        Ok(())
    }

    /// 初始化数据库连接（单连接模式，用于测试或特殊场景）
    pub fn initialize_database_single_mode(&self) -> anyhow::Result<()> {
        let database = Arc::new(Database::new()?);

        let project_repository = ProjectRepository::new(database.clone())?;
        let material_repository = MaterialRepository::new(database.clone())?;
        let model_repository = ModelRepository::new(database.clone());
        let model_dynamic_repository = ModelDynamicRepository::new(database.clone());
        let video_generation_repository = VideoGenerationRepository::new(database.clone());
        let conversation_repository = Arc::new(ConversationRepository::new(database.clone()));

        // 初始化数据库表
        model_dynamic_repository.init_tables()?;
        video_generation_repository.init_tables()?;
        conversation_repository.initialize_tables()?;

        // 初始化穿搭图片相关表
        let outfit_image_repository = crate::data::repositories::outfit_image_repository::OutfitImageRepository::new(database.clone());
        outfit_image_repository.init_tables()?;

        // 初始化穿搭照片生成相关表
        let outfit_photo_generation_repository = OutfitPhotoGenerationRepository::new(database.clone())?;

        *self.database.lock().unwrap() = Some(database.clone());
        *self.project_repository.lock().unwrap() = Some(project_repository);
        *self.material_repository.lock().unwrap() = Some(material_repository);
        *self.model_repository.lock().unwrap() = Some(model_repository);
        *self.model_dynamic_repository.lock().unwrap() = Some(model_dynamic_repository);
        *self.video_generation_repository.lock().unwrap() = Some(video_generation_repository);
        *self.conversation_repository.lock().unwrap() = Some(conversation_repository);
        *self.outfit_photo_generation_repository.lock().unwrap() = Some(outfit_photo_generation_repository);

        println!("数据库初始化完成，使用单连接模式");
        Ok(())
    }

    /// 获取项目仓库实例
    pub fn get_project_repository(&self) -> anyhow::Result<std::sync::MutexGuard<Option<ProjectRepository>>> {
        Ok(self.project_repository.lock().unwrap())
    }

    /// 获取素材仓库实例
    pub fn get_material_repository(&self) -> anyhow::Result<std::sync::MutexGuard<Option<MaterialRepository>>> {
        Ok(self.material_repository.lock().unwrap())
    }

    /// 获取模特仓库实例
    pub fn get_model_repository(&self) -> anyhow::Result<std::sync::MutexGuard<Option<ModelRepository>>> {
        Ok(self.model_repository.lock().unwrap())
    }

    /// 获取模特动态仓库实例
    pub fn get_model_dynamic_repository(&self) -> anyhow::Result<std::sync::MutexGuard<Option<ModelDynamicRepository>>> {
        Ok(self.model_dynamic_repository.lock().unwrap())
    }

    /// 获取视频生成仓库实例
    pub fn get_video_generation_repository(&self) -> anyhow::Result<std::sync::MutexGuard<Option<VideoGenerationRepository>>> {
        Ok(self.video_generation_repository.lock().unwrap())
    }

    /// 获取会话仓库实例
    pub fn get_conversation_repository(&self) -> anyhow::Result<Arc<ConversationRepository>> {
        let repo_guard = self.conversation_repository.lock().unwrap();
        repo_guard.as_ref()
            .ok_or_else(|| anyhow::anyhow!("会话仓库未初始化"))
            .map(|repo| repo.clone())
    }

    /// 获取数据库实例
    pub fn get_database(&self) -> Arc<Database> {
        // 使用全局静态数据库实例，确保整个应用只有一个数据库实例
        use std::sync::OnceLock;
        static DATABASE_INSTANCE: OnceLock<Arc<Database>> = OnceLock::new();

        DATABASE_INSTANCE.get_or_init(|| {
            // 只在第一次调用时初始化数据库
            Arc::new(Database::new().unwrap())
        }).clone()
    }

    /// 获取数据库连接
    pub fn get_connection(&self) -> anyhow::Result<std::sync::Arc<std::sync::Mutex<rusqlite::Connection>>> {
        let database = self.get_database();
        Ok(database.get_connection())
    }

    /// 用于测试的构造函数
    #[cfg(test)]
    pub fn new_with_database(_database: Arc<Database>) -> Self {
        let state = Self {
            database: Mutex::new(None),
            project_repository: Mutex::new(None),
            material_repository: Mutex::new(None),
            model_repository: Mutex::new(None),
            model_dynamic_repository: Mutex::new(None),
            video_generation_repository: Mutex::new(None),
            conversation_repository: Mutex::new(None),
            outfit_photo_generation_repository: Mutex::new(None),
            performance_monitor: Mutex::new(PerformanceMonitor::new()),
            event_bus_manager: Arc::new(EventBusManager::new()),
        };
        // 不直接存储database，而是在需要时返回传入的database
        state
    }
}

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