use rusqlite::{Connection, Result, Row};
use std::sync::Arc;
use crate::data::models::model::{
    Model, ModelPhoto, Gender, ModelStatus, PhotoType, 
    Measurements, ContactInfo, SocialMedia, ModelQueryParams
};
use chrono::{DateTime, Utc};
use crate::infrastructure::database::Database;

/// 模特数据仓库
/// 遵循 Tauri 开发规范的仓库模式设计
#[derive(Clone)]
pub struct ModelRepository {
    database: Arc<Database>,
}

impl ModelRepository {
    /// 创建新的模特仓库实例
    pub fn new(database: Arc<Database>) -> Self {
        Self { database }
    }

    /// 创建模特
    pub fn create(&self, model: &Model) -> Result<()> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        
        let measurements_json = model.measurements.as_ref()
            .map(|m| serde_json::to_string(m))
            .transpose()
            .map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;
        
        let tags_json = serde_json::to_string(&model.tags)
            .map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;
        
        let contact_info_json = model.contact_info.as_ref()
            .map(|c| serde_json::to_string(c))
            .transpose()
            .map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;
        
        let social_media_json = model.social_media.as_ref()
            .map(|s| serde_json::to_string(s))
            .transpose()
            .map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;

        conn.execute(
            "INSERT INTO models (
                id, name, stage_name, gender, age, height, weight, measurements,
                description, tags, avatar_path, contact_info, social_media,
                status, rating, created_at, updated_at, is_active
            ) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18)",
            [
                &model.id as &dyn rusqlite::ToSql,
                &model.name,
                &model.stage_name,
                &serde_json::to_string(&model.gender).unwrap(),
                &model.age,
                &model.height,
                &model.weight,
                &measurements_json,
                &model.description,
                &tags_json,
                &model.avatar_path,
                &contact_info_json,
                &social_media_json,
                &serde_json::to_string(&model.status).unwrap(),
                &model.rating,
                &model.created_at.to_rfc3339(),
                &model.updated_at.to_rfc3339(),
                &model.is_active,
            ],
        )?;

        Ok(())
    }

    /// 根据ID获取模特
    /// 使用读写分离避免嵌套锁问题
    pub fn get_by_id(&self, id: &str) -> Result<Option<Model>> {
        println!("get_by_id 开始执行，model_id: {}", id);

        // 首先获取模特基本信息（使用只读连接）
        let model = {
            match self.database.try_get_read_connection() {
                Some(conn) => {
                    println!("get_by_id 使用只读连接获取基本信息");

                    let mut stmt = conn.prepare(
                        "SELECT id, name, stage_name, gender, age, height, weight, measurements,
                                description, tags, avatar_path, contact_info, social_media,
                                status, rating, created_at, updated_at, is_active
                         FROM models WHERE id = ?1"
                    )?;

                    let model_iter = stmt.query_map([id], |row| {
                        self.row_to_model(row)
                    })?;

                    let mut result = None;
                    for model in model_iter {
                        result = Some(model?);
                        break;
                    }
                    result
                },
                None => {
                    println!("get_by_id 只读连接被占用，使用基本方法");
                    // 如果只读连接被占用，使用不加载照片的基本方法
                    return self.get_basic_by_id(id);
                }
            }
        };

        // 如果找到模特，加载照片信息（此时已释放了基本信息查询的锁）
        if let Some(mut model) = model {
            println!("get_by_id 开始加载照片信息");
            model.photos = self.get_photos(&model.id)?;
            println!("get_by_id 执行完成");
            Ok(Some(model))
        } else {
            println!("get_by_id 未找到模特");
            Ok(None)
        }
    }

    /// 根据ID获取模特基本信息（不加载照片，避免死锁）
    pub fn get_basic_by_id(&self, id: &str) -> Result<Option<Model>> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();

        let mut stmt = conn.prepare(
            "SELECT id, name, stage_name, gender, age, height, weight, measurements,
                    description, tags, avatar_path, contact_info, social_media,
                    status, rating, created_at, updated_at, is_active
             FROM models WHERE id = ?1"
        )?;

        let model_iter = stmt.query_map([id], |row| {
            self.row_to_model(row)
        })?;

        for model in model_iter {
            let mut model = model?;
            // 不加载照片信息，避免死锁
            model.photos = Vec::new();
            return Ok(Some(model));
        }

        Ok(None)
    }

    /// 获取所有模特
    pub fn get_all(&self) -> Result<Vec<Model>> {
        println!("ModelRepository::get_all 开始执行");

        // 首先获取所有模特的基本信息
        let mut models = {
            let conn = self.database.get_connection();
            let conn = conn.lock().unwrap();
            println!("获取数据库连接成功");

            let mut stmt = conn.prepare(
                "SELECT id, name, stage_name, gender, age, height, weight, measurements,
                        description, tags, avatar_path, contact_info, social_media,
                        status, rating, created_at, updated_at, is_active
                 FROM models WHERE is_active = 1 ORDER BY created_at DESC"
            )?;
            println!("SQL 语句准备成功");

            let model_iter = stmt.query_map([], |row| {
                self.row_to_model(row)
            })?;
            println!("查询执行成功，开始处理结果");

            let mut models = Vec::new();
            for (index, model) in model_iter.enumerate() {
                println!("处理第 {} 个模特记录", index + 1);
                println!("开始解析模特数据...");
                let model = match model {
                    Ok(m) => {
                        println!("模特数据解析成功: {}", m.name);
                        m
                    },
                    Err(e) => {
                        println!("模特数据解析失败: {}", e);
                        return Err(e);
                    }
                };
                models.push(model);
                println!("第 {} 个模特记录处理完成", index + 1);
            }
            models
        }; // 释放数据库连接锁

        // 然后为每个模特加载照片信息（避免嵌套锁）
        for model in &mut models {
            println!("开始加载模特 {} 的照片信息", model.id);
            model.photos = match self.get_photos(&model.id) {
                Ok(photos) => {
                    println!("照片信息加载成功，共 {} 张照片", photos.len());
                    photos
                },
                Err(e) => {
                    println!("照片信息加载失败: {}，跳过照片加载", e);
                    // 暂时跳过照片加载，避免阻塞整个流程
                    Vec::new()
                }
            };
        }

        println!("ModelRepository::get_all 执行完成，返回 {} 个模特", models.len());
        Ok(models)
    }

    /// 根据查询参数搜索模特
    pub fn search(&self, params: &ModelQueryParams) -> Result<Vec<Model>> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        
        let mut query = String::from(
            "SELECT id, name, stage_name, gender, age, height, weight, measurements,
                    description, tags, avatar_path, contact_info, social_media,
                    status, rating, created_at, updated_at, is_active
             FROM models WHERE is_active = 1"
        );
        
        let mut query_params: Vec<Box<dyn rusqlite::ToSql>> = Vec::new();
        
        if let Some(ref name) = params.name {
            query.push_str(" AND (name LIKE ?1 OR stage_name LIKE ?1)");
            query_params.push(Box::new(format!("%{}%", name)));
        }
        
        if let Some(ref gender) = params.gender {
            query.push_str(&format!(" AND gender = ?{}", query_params.len() + 1));
            query_params.push(Box::new(serde_json::to_string(gender).unwrap()));
        }
        
        if let Some(min_age) = params.min_age {
            query.push_str(&format!(" AND age >= ?{}", query_params.len() + 1));
            query_params.push(Box::new(min_age));
        }
        
        if let Some(max_age) = params.max_age {
            query.push_str(&format!(" AND age <= ?{}", query_params.len() + 1));
            query_params.push(Box::new(max_age));
        }
        
        if let Some(min_height) = params.min_height {
            query.push_str(&format!(" AND height >= ?{}", query_params.len() + 1));
            query_params.push(Box::new(min_height));
        }
        
        if let Some(max_height) = params.max_height {
            query.push_str(&format!(" AND height <= ?{}", query_params.len() + 1));
            query_params.push(Box::new(max_height));
        }
        
        if let Some(ref status) = params.status {
            query.push_str(&format!(" AND status = ?{}", query_params.len() + 1));
            query_params.push(Box::new(serde_json::to_string(status).unwrap()));
        }
        
        if let Some(min_rating) = params.min_rating {
            query.push_str(&format!(" AND rating >= ?{}", query_params.len() + 1));
            query_params.push(Box::new(min_rating));
        }
        
        // 处理标签搜索
        if let Some(ref tags) = params.tags {
            for tag in tags {
                query.push_str(&format!(" AND tags LIKE ?{}", query_params.len() + 1));
                query_params.push(Box::new(format!("%\"{}\"", tag)));
            }
        }
        
        query.push_str(" ORDER BY created_at DESC");
        
        if let Some(limit) = params.limit {
            query.push_str(&format!(" LIMIT ?{}", query_params.len() + 1));
            query_params.push(Box::new(limit));
            
            if let Some(offset) = params.offset {
                query.push_str(&format!(" OFFSET ?{}", query_params.len() + 1));
                query_params.push(Box::new(offset));
            }
        }

        let mut stmt = conn.prepare(&query)?;
        let params_refs: Vec<&dyn rusqlite::ToSql> = query_params.iter().map(|p| p.as_ref()).collect();
        
        let model_iter = stmt.query_map(params_refs.as_slice(), |row| {
            self.row_to_model(row)
        })?;

        // 先收集所有模特基本信息
        let mut models = Vec::new();
        for model in model_iter {
            models.push(model?);
        }

        // 释放连接锁
        drop(stmt);
        drop(conn);

        // 为每个模特加载照片信息（避免嵌套锁）
        for model in &mut models {
            model.photos = match self.get_photos(&model.id) {
                Ok(photos) => photos,
                Err(e) => {
                    println!("search 加载模特 {} 的照片失败: {}，跳过照片加载", model.id, e);
                    Vec::new()
                }
            };
        }

        Ok(models)
    }

    /// 更新模特
    pub fn update(&self, model: &Model) -> Result<()> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        
        let measurements_json = model.measurements.as_ref()
            .map(|m| serde_json::to_string(m))
            .transpose()
            .map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;
        
        let tags_json = serde_json::to_string(&model.tags)
            .map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;
        
        let contact_info_json = model.contact_info.as_ref()
            .map(|c| serde_json::to_string(c))
            .transpose()
            .map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;
        
        let social_media_json = model.social_media.as_ref()
            .map(|s| serde_json::to_string(s))
            .transpose()
            .map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;

        conn.execute(
            "UPDATE models SET
                name = ?1, stage_name = ?2, gender = ?3, age = ?4, height = ?5, weight = ?6,
                measurements = ?7, description = ?8, tags = ?9, avatar_path = ?10,
                contact_info = ?11, social_media = ?12, status = ?13, rating = ?14,
                updated_at = ?15, is_active = ?16
             WHERE id = ?17",
            [
                &model.name as &dyn rusqlite::ToSql,
                &model.stage_name,
                &serde_json::to_string(&model.gender).unwrap(),
                &model.age,
                &model.height,
                &model.weight,
                &measurements_json,
                &model.description,
                &tags_json,
                &model.avatar_path,
                &contact_info_json,
                &social_media_json,
                &serde_json::to_string(&model.status).unwrap(),
                &model.rating,
                &model.updated_at.to_rfc3339(),
                &model.is_active,
                &model.id,
            ],
        )?;

        Ok(())
    }

    /// 删除模特（软删除）
    pub fn delete(&self, id: &str) -> Result<()> {
        println!("ModelRepository::delete 开始执行，ID: {}", id);

        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        println!("获取数据库连接成功");

        let rows_affected = conn.execute(
            "UPDATE models SET is_active = 0, updated_at = ?1 WHERE id = ?2",
            (Utc::now().to_rfc3339(), id),
        )?;

        println!("SQL执行成功，影响行数: {}", rows_affected);

        if rows_affected == 0 {
            println!("警告: 没有找到要删除的模特记录，可能已经被删除");
        } else {
            println!("模特删除成功");
        }

        Ok(())
    }

    /// 物理删除模特
    pub fn delete_permanently(&self, id: &str) -> Result<()> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        
        // 先删除照片记录
        conn.execute("DELETE FROM model_photos WHERE model_id = ?1", [id])?;
        
        // 删除模特记录
        conn.execute("DELETE FROM models WHERE id = ?1", [id])?;

        Ok(())
    }

    /// 获取模特照片
    /// 使用专用只读连接，避免与写操作的锁竞争
    pub fn get_photos(&self, model_id: &str) -> Result<Vec<ModelPhoto>> {
        println!("get_photos 开始执行，model_id: {}", model_id);

        // 使用专用的只读连接，避免与写操作竞争
        match self.database.get_best_read_connection() {
            Ok(conn) => {
                let photos = self.execute_photo_query(&conn, model_id)?;
                println!("get_photos 执行完成，返回 {} 张照片", photos.len());
                Ok(photos)
            },
            Err(e) => {
                println!("get_photos 无法获取只读数据库连接: {}", e);
                // 如果所有连接都被占用，返回空结果避免阻塞UI
                Ok(Vec::new())
            }
        }
    }

    /// 执行照片查询的具体实现
    fn execute_photo_query(&self, conn: &Connection, model_id: &str) -> Result<Vec<ModelPhoto>> {
        println!("get_photos 开始准备SQL语句");

        let mut stmt = conn.prepare(
            "SELECT id, model_id, file_path, file_name, file_size, photo_type,
                    description, tags, is_cover, created_at
             FROM model_photos WHERE model_id = ?1 ORDER BY created_at DESC"
        )?;
        println!("get_photos SQL 语句准备成功");

        let photo_iter = stmt.query_map([model_id], |row| {
            self.row_to_photo(row)
        })?;
        println!("get_photos 查询执行成功");

        let mut photos = Vec::new();
        for (index, photo_result) in photo_iter.enumerate() {
            match photo_result {
                Ok(photo) => {
                    photos.push(photo);
                    if index % 10 == 0 && index > 0 {
                        println!("get_photos 已处理 {} 张照片", index);
                    }
                },
                Err(e) => {
                    eprintln!("get_photos 处理第 {} 张照片时出错: {}", index, e);
                    return Err(e);
                }
            }
        }

        println!("get_photos 查询处理完成，共 {} 张照片", photos.len());
        Ok(photos)
    }

    /// 添加模特照片
    pub fn add_photo(&self, photo: &ModelPhoto) -> Result<()> {
        // 在函数外部处理 JSON 序列化，避免在持有锁时进行
        let tags_json = serde_json::to_string(&photo.tags)
            .map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;

        let photo_type_json = serde_json::to_string(&photo.photo_type)
            .map_err(|e| rusqlite::Error::ToSqlConversionFailure(Box::new(e)))?;

        // 使用优化的数据库访问模式
        self.database.execute(|conn| {
            conn.execute(
                "INSERT INTO model_photos (
                    id, model_id, file_path, file_name, file_size, photo_type,
                    description, tags, is_cover, created_at
                ) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10)",
                (
                    &photo.id,
                    &photo.model_id,
                    &photo.file_path,
                    &photo.file_name,
                    photo.file_size,
                    &photo_type_json,
                    &photo.description,
                    &tags_json,
                    photo.is_cover,
                    photo.created_at.to_rfc3339(),
                ),
            )?;

            Ok(())
        })
    }

    /// 删除模特照片
    pub fn delete_photo(&self, photo_id: &str) -> Result<()> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        
        conn.execute("DELETE FROM model_photos WHERE id = ?1", [photo_id])?;

        Ok(())
    }

    /// 设置封面照片
    pub fn set_cover_photo(&self, model_id: &str, photo_id: &str) -> Result<()> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        
        // 先取消所有封面照片
        conn.execute(
            "UPDATE model_photos SET is_cover = 0 WHERE model_id = ?1",
            [model_id],
        )?;
        
        // 设置新的封面照片
        conn.execute(
            "UPDATE model_photos SET is_cover = 1 WHERE id = ?1 AND model_id = ?2",
            (photo_id, model_id),
        )?;

        Ok(())
    }

    /// 将数据库行转换为模特对象
    fn row_to_model(&self, row: &Row) -> Result<Model> {
        let gender_str: String = row.get("gender")?;
        let gender: Gender = serde_json::from_str(&gender_str)
            .map_err(|e| rusqlite::Error::FromSqlConversionFailure(
                0,
                rusqlite::types::Type::Text,
                Box::new(e),
            ))?;

        let status_str: String = row.get("status")?;
        let status: ModelStatus = serde_json::from_str(&status_str)
            .map_err(|e| rusqlite::Error::FromSqlConversionFailure(
                0,
                rusqlite::types::Type::Text,
                Box::new(e),
            ))?;

        let measurements: Option<Measurements> = row.get::<_, Option<String>>("measurements")?
            .map(|s| serde_json::from_str(&s))
            .transpose()
            .map_err(|e| rusqlite::Error::FromSqlConversionFailure(
                0,
                rusqlite::types::Type::Text,
                Box::new(e),
            ))?;

        let tags_str: String = row.get("tags")?;
        let tags: Vec<String> = serde_json::from_str(&tags_str)
            .map_err(|e| rusqlite::Error::FromSqlConversionFailure(
                0,
                rusqlite::types::Type::Text,
                Box::new(e),
            ))?;

        let contact_info: Option<ContactInfo> = row.get::<_, Option<String>>("contact_info")?
            .map(|s| serde_json::from_str(&s))
            .transpose()
            .map_err(|e| rusqlite::Error::FromSqlConversionFailure(
                0,
                rusqlite::types::Type::Text,
                Box::new(e),
            ))?;

        let social_media: Option<SocialMedia> = row.get::<_, Option<String>>("social_media")?
            .map(|s| serde_json::from_str(&s))
            .transpose()
            .map_err(|e| rusqlite::Error::FromSqlConversionFailure(
                0,
                rusqlite::types::Type::Text,
                Box::new(e),
            ))?;

        let created_at_str: String = row.get("created_at")?;
        let created_at = DateTime::parse_from_rfc3339(&created_at_str)
            .map_err(|e| rusqlite::Error::FromSqlConversionFailure(
                0,
                rusqlite::types::Type::Text,
                Box::new(e),
            ))?
            .with_timezone(&Utc);

        let updated_at_str: String = row.get("updated_at")?;
        let updated_at = DateTime::parse_from_rfc3339(&updated_at_str)
            .map_err(|e| rusqlite::Error::FromSqlConversionFailure(
                0,
                rusqlite::types::Type::Text,
                Box::new(e),
            ))?
            .with_timezone(&Utc);

        Ok(Model {
            id: row.get("id")?,
            name: row.get("name")?,
            stage_name: row.get("stage_name")?,
            gender,
            age: row.get("age")?,
            height: row.get("height")?,
            weight: row.get("weight")?,
            measurements,
            description: row.get("description")?,
            tags,
            avatar_path: row.get("avatar_path")?,
            photos: Vec::new(), // 将在调用方法中填充
            contact_info,
            social_media,
            status,
            rating: row.get("rating")?,
            created_at,
            updated_at,
            is_active: row.get("is_active")?,
        })
    }

    /// 将数据库行转换为照片对象
    fn row_to_photo(&self, row: &Row) -> Result<ModelPhoto> {
        println!("row_to_photo 开始执行");

        let photo_type_str: String = row.get("photo_type")?;
        println!("row_to_photo 获取 photo_type: {}", photo_type_str);

        let photo_type: PhotoType = serde_json::from_str(&photo_type_str)
            .map_err(|e| {
                println!("row_to_photo photo_type 解析失败: {}", e);
                rusqlite::Error::FromSqlConversionFailure(
                    0,
                    rusqlite::types::Type::Text,
                    Box::new(e),
                )
            })?;
        println!("row_to_photo photo_type 解析成功");

        let tags_str: String = row.get("tags")?;
        let tags: Vec<String> = serde_json::from_str(&tags_str)
            .map_err(|e| rusqlite::Error::FromSqlConversionFailure(
                0,
                rusqlite::types::Type::Text,
                Box::new(e),
            ))?;

        let created_at_str: String = row.get("created_at")?;
        let created_at = DateTime::parse_from_rfc3339(&created_at_str)
            .map_err(|e| rusqlite::Error::FromSqlConversionFailure(
                0,
                rusqlite::types::Type::Text,
                Box::new(e),
            ))?
            .with_timezone(&Utc);

        Ok(ModelPhoto {
            id: row.get("id")?,
            model_id: row.get("model_id")?,
            file_path: row.get("file_path")?,
            file_name: row.get("file_name")?,
            file_size: row.get("file_size")?,
            photo_type,
            description: row.get("description")?,
            tags,
            is_cover: row.get("is_cover")?,
            created_at,
        })
    }
}
