use anyhow::{Result, anyhow};
use rusqlite::{params, Row};
use std::sync::Arc;
use tracing::info;

use crate::data::models::watermark::{
    WatermarkTemplate, WatermarkCategory, WatermarkType
};
use crate::infrastructure::database::Database;

/// 水印模板数据访问层
/// 遵循 Tauri 开发规范的数据访问层设计
pub struct WatermarkTemplateRepository {
    database: Arc<Database>,
}

impl WatermarkTemplateRepository {
    pub fn new(database: Arc<Database>) -> Self {
        Self { database }
    }

    /// 创建水印模板
    pub fn create(&self, template: &WatermarkTemplate) -> Result<()> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        conn.execute(
            "INSERT INTO watermark_templates (
                id, name, file_path, thumbnail_path, category, watermark_type,
                file_size, width, height, description, tags, is_active,
                created_at, updated_at
            ) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14)",
            params![
                template.id,
                template.name,
                template.file_path,
                template.thumbnail_path,
                serde_json::to_string(&template.category)?,
                serde_json::to_string(&template.watermark_type)?,
                template.file_size as i64,
                template.width.map(|w| w as i32),
                template.height.map(|h| h as i32),
                template.description,
                serde_json::to_string(&template.tags)?,
                template.is_active,
                template.created_at.format("%Y-%m-%d %H:%M:%S").to_string(),
                template.updated_at.format("%Y-%m-%d %H:%M:%S").to_string(),
            ],
        )?;

        info!(template_id = %template.id, template_name = %template.name, "水印模板创建成功");
        Ok(())
    }

    /// 根据ID获取水印模板
    pub fn get_by_id(&self, id: &str) -> Result<Option<WatermarkTemplate>> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        let mut stmt = conn.prepare(
            "SELECT id, name, file_path, thumbnail_path, category, watermark_type,
                    file_size, width, height, description, tags, is_active,
                    created_at, updated_at
             FROM watermark_templates 
             WHERE id = ?1"
        )?;

        let template_iter = stmt.query_map([id], |row| {
            Self::row_to_template(row)
        })?;

        for template in template_iter {
            return Ok(Some(template?));
        }

        Ok(None)
    }

    /// 获取所有水印模板
    pub fn get_all(&self) -> Result<Vec<WatermarkTemplate>> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        let mut stmt = conn.prepare(
            "SELECT id, name, file_path, thumbnail_path, category, watermark_type,
                    file_size, width, height, description, tags, is_active,
                    created_at, updated_at
             FROM watermark_templates 
             ORDER BY created_at DESC"
        )?;

        let template_iter = stmt.query_map([], |row| {
            Self::row_to_template(row)
        })?;

        let mut templates = Vec::new();
        for template in template_iter {
            templates.push(template?);
        }

        Ok(templates)
    }

    /// 根据分类获取水印模板
    pub fn get_by_category(&self, category: &WatermarkCategory) -> Result<Vec<WatermarkTemplate>> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        let category_str = serde_json::to_string(category)?;
        
        let mut stmt = conn.prepare(
            "SELECT id, name, file_path, thumbnail_path, category, watermark_type,
                    file_size, width, height, description, tags, is_active,
                    created_at, updated_at
             FROM watermark_templates 
             WHERE category = ?1 AND is_active = 1
             ORDER BY created_at DESC"
        )?;

        let template_iter = stmt.query_map([category_str], |row| {
            Self::row_to_template(row)
        })?;

        let mut templates = Vec::new();
        for template in template_iter {
            templates.push(template?);
        }

        Ok(templates)
    }

    /// 根据类型获取水印模板
    pub fn get_by_type(&self, watermark_type: &WatermarkType) -> Result<Vec<WatermarkTemplate>> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        let type_str = serde_json::to_string(watermark_type)?;
        
        let mut stmt = conn.prepare(
            "SELECT id, name, file_path, thumbnail_path, category, watermark_type,
                    file_size, width, height, description, tags, is_active,
                    created_at, updated_at
             FROM watermark_templates 
             WHERE watermark_type = ?1 AND is_active = 1
             ORDER BY created_at DESC"
        )?;

        let template_iter = stmt.query_map([type_str], |row| {
            Self::row_to_template(row)
        })?;

        let mut templates = Vec::new();
        for template in template_iter {
            templates.push(template?);
        }

        Ok(templates)
    }

    /// 搜索水印模板
    pub fn search(&self, query: &str) -> Result<Vec<WatermarkTemplate>> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;

        let search_pattern = format!("%{}%", query);

        let mut stmt = conn.prepare(
            "SELECT id, name, file_path, thumbnail_path, category, watermark_type,
                    file_size, width, height, description, tags, is_active,
                    created_at, updated_at
             FROM watermark_templates 
             WHERE (name LIKE ?1 OR description LIKE ?1 OR tags LIKE ?1) 
                   AND is_active = 1
             ORDER BY created_at DESC"
        )?;

        let template_iter = stmt.query_map([search_pattern], |row| {
            Self::row_to_template(row)
        })?;

        let mut templates = Vec::new();
        for template in template_iter {
            templates.push(template?);
        }

        Ok(templates)
    }

    /// 更新水印模板
    pub fn update(&self, template: &WatermarkTemplate) -> Result<()> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        let rows_affected = conn.execute(
            "UPDATE watermark_templates SET 
                name = ?2, file_path = ?3, thumbnail_path = ?4, category = ?5,
                watermark_type = ?6, file_size = ?7, width = ?8, height = ?9,
                description = ?10, tags = ?11, is_active = ?12, updated_at = ?13
             WHERE id = ?1",
            params![
                template.id,
                template.name,
                template.file_path,
                template.thumbnail_path,
                serde_json::to_string(&template.category)?,
                serde_json::to_string(&template.watermark_type)?,
                template.file_size as i64,
                template.width.map(|w| w as i32),
                template.height.map(|h| h as i32),
                template.description,
                serde_json::to_string(&template.tags)?,
                template.is_active,
                template.updated_at.format("%Y-%m-%d %H:%M:%S").to_string(),
            ],
        )?;

        if rows_affected == 0 {
            return Err(anyhow!("水印模板不存在: {}", template.id));
        }

        info!(template_id = %template.id, "水印模板更新成功");
        Ok(())
    }

    /// 删除水印模板
    pub fn delete(&self, id: &str) -> Result<()> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        let rows_affected = conn.execute(
            "DELETE FROM watermark_templates WHERE id = ?1",
            [id],
        )?;

        if rows_affected == 0 {
            return Err(anyhow!("水印模板不存在: {}", id));
        }

        info!(template_id = %id, "水印模板删除成功");
        Ok(())
    }

    /// 软删除水印模板（设置为非活跃状态）
    pub fn soft_delete(&self, id: &str) -> Result<()> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        let rows_affected = conn.execute(
            "UPDATE watermark_templates SET is_active = 0, updated_at = datetime('now') WHERE id = ?1",
            [id],
        )?;

        if rows_affected == 0 {
            return Err(anyhow!("水印模板不存在: {}", id));
        }

        info!(template_id = %id, "水印模板软删除成功");
        Ok(())
    }

    /// 获取模板统计信息
    pub fn get_stats(&self) -> Result<serde_json::Value> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        // 总数统计
        let total_count: i64 = conn.query_row(
            "SELECT COUNT(*) FROM watermark_templates WHERE is_active = 1",
            [],
            |row| row.get(0),
        )?;

        // 按分类统计
        let mut category_stats = std::collections::HashMap::new();
        let mut stmt = conn.prepare(
            "SELECT category, COUNT(*) FROM watermark_templates 
             WHERE is_active = 1 GROUP BY category"
        )?;
        
        let category_iter = stmt.query_map([], |row| {
            Ok((row.get::<_, String>(0)?, row.get::<_, i64>(1)?))
        })?;

        for result in category_iter {
            let (category, count) = result?;
            category_stats.insert(category, count);
        }

        // 按类型统计
        let mut type_stats = std::collections::HashMap::new();
        let mut stmt = conn.prepare(
            "SELECT watermark_type, COUNT(*) FROM watermark_templates 
             WHERE is_active = 1 GROUP BY watermark_type"
        )?;
        
        let type_iter = stmt.query_map([], |row| {
            Ok((row.get::<_, String>(0)?, row.get::<_, i64>(1)?))
        })?;

        for result in type_iter {
            let (watermark_type, count) = result?;
            type_stats.insert(watermark_type, count);
        }

        // 总文件大小
        let total_size: i64 = conn.query_row(
            "SELECT COALESCE(SUM(file_size), 0) FROM watermark_templates WHERE is_active = 1",
            [],
            |row| row.get(0),
        )?;

        Ok(serde_json::json!({
            "total_templates": total_count,
            "by_category": category_stats,
            "by_type": type_stats,
            "total_size": total_size
        }))
    }

    /// 检查模板名称是否已存在
    pub fn name_exists(&self, name: &str, exclude_id: Option<&str>) -> Result<bool> {
        if !self.database.has_pool() {
            return Err(anyhow!("连接池未启用，无法安全执行数据库操作"));
        }

        let conn = self
            .database
            .acquire_from_pool()
            .map_err(|e| anyhow!("获取连接池连接失败: {}", e))?;
        
        let count: i64 = if let Some(id) = exclude_id {
            conn.query_row(
                "SELECT COUNT(*) FROM watermark_templates WHERE name = ?1 AND id != ?2 AND is_active = 1",
                [name, id],
                |row| row.get(0)
            )?
        } else {
            conn.query_row(
                "SELECT COUNT(*) FROM watermark_templates WHERE name = ?1 AND is_active = 1",
                [name],
                |row| row.get(0)
            )?
        };

        Ok(count > 0)
    }

    /// 将数据库行转换为WatermarkTemplate对象
    fn row_to_template(row: &Row) -> rusqlite::Result<WatermarkTemplate> {
        let category_str: String = row.get("category")?;
        let category: WatermarkCategory = serde_json::from_str(&category_str)
            .map_err(|e| rusqlite::Error::InvalidColumnType(
                row.as_ref().column_index("category").unwrap(),
                format!("Invalid category: {}", e),
                rusqlite::types::Type::Text
            ))?;

        let type_str: String = row.get("watermark_type")?;
        let watermark_type: WatermarkType = serde_json::from_str(&type_str)
            .map_err(|e| rusqlite::Error::InvalidColumnType(
                row.as_ref().column_index("watermark_type").unwrap(),
                format!("Invalid watermark_type: {}", e),
                rusqlite::types::Type::Text
            ))?;

        let tags_str: String = row.get("tags")?;
        let tags: Vec<String> = serde_json::from_str(&tags_str)
            .map_err(|e| rusqlite::Error::InvalidColumnType(
                row.as_ref().column_index("tags").unwrap(),
                format!("Invalid tags: {}", e),
                rusqlite::types::Type::Text
            ))?;

        let created_at_str: String = row.get("created_at")?;
        let created_at = chrono::DateTime::parse_from_str(&created_at_str, "%Y-%m-%d %H:%M:%S")
            .map_err(|e| rusqlite::Error::InvalidColumnType(
                row.as_ref().column_index("created_at").unwrap(),
                format!("Invalid created_at: {}", e),
                rusqlite::types::Type::Text
            ))?
            .with_timezone(&chrono::Utc);

        let updated_at_str: String = row.get("updated_at")?;
        let updated_at = chrono::DateTime::parse_from_str(&updated_at_str, "%Y-%m-%d %H:%M:%S")
            .map_err(|e| rusqlite::Error::InvalidColumnType(
                row.as_ref().column_index("updated_at").unwrap(),
                format!("Invalid updated_at: {}", e),
                rusqlite::types::Type::Text
            ))?
            .with_timezone(&chrono::Utc);

        Ok(WatermarkTemplate {
            id: row.get("id")?,
            name: row.get("name")?,
            file_path: row.get("file_path")?,
            thumbnail_path: row.get("thumbnail_path")?,
            category,
            watermark_type,
            file_size: row.get::<_, i64>("file_size")? as u64,
            width: row.get::<_, Option<i32>>("width")?.map(|w| w as u32),
            height: row.get::<_, Option<i32>>("height")?.map(|h| h as u32),
            description: row.get("description")?,
            tags,
            is_active: row.get("is_active")?,
            created_at,
            updated_at,
        })
    }
}
