use rusqlite::{Result, Row};
use std::sync::Arc;
use chrono::{DateTime, Utc};
use crate::infrastructure::database::Database;

use crate::data::models::export_record::{
    ExportRecord, ExportType, ExportFormat, ExportStatus,
    CreateExportRecordRequest, ExportRecordQueryOptions, ExportRecordStatistics,
};

/// 导出记录数据库操作仓储
/// 遵循 Tauri 开发规范的数据访问层设计原则
pub struct ExportRecordRepository {
    database: Arc<Database>,
}

impl ExportRecordRepository {
    /// 创建新的导出记录仓储实例
    pub fn new(database: Arc<Database>) -> Self {
        Self { database }
    }

    /// 创建导出记录
    pub fn create(&self, request: CreateExportRecordRequest) -> Result<ExportRecord> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();

        // 生成唯一ID
        let id = uuid::Uuid::new_v4().to_string();
        
        // 获取项目ID和模板ID（从匹配结果中查询）
        let (project_id, template_id) = conn.query_row(
            "SELECT project_id, template_id FROM template_matching_results WHERE id = ?1",
            [&request.matching_result_id],
            |row| Ok((row.get::<_, String>(0)?, row.get::<_, String>(1)?))
        )?;

        let mut export_record = ExportRecord::new(
            id,
            request.matching_result_id,
            project_id,
            template_id,
            request.export_type,
            request.export_format,
            request.file_path,
        );

        if let Some(metadata) = request.metadata {
            export_record.set_metadata(metadata);
        }

        conn.execute(
            "INSERT INTO export_records (
                id, matching_result_id, project_id, template_id, export_type, export_format,
                file_path, file_size, export_status, export_duration_ms, error_message,
                metadata, created_at, updated_at, is_active
            ) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15)",
            rusqlite::params![
                &export_record.id,
                &export_record.matching_result_id,
                &export_record.project_id,
                &export_record.template_id,
                &serde_json::to_string(&export_record.export_type).unwrap(),
                &serde_json::to_string(&export_record.export_format).unwrap(),
                &export_record.file_path,
                &export_record.file_size,
                &serde_json::to_string(&export_record.export_status).unwrap(),
                &export_record.export_duration_ms,
                &export_record.error_message,
                &export_record.metadata,
                &export_record.created_at.to_rfc3339(),
                &export_record.updated_at.to_rfc3339(),
                &(export_record.is_active as i32),
            ],
        )?;

        Ok(export_record)
    }

    /// 根据ID获取导出记录
    pub fn get_by_id(&self, id: &str) -> Result<Option<ExportRecord>> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        
        let mut stmt = conn.prepare(
            "SELECT id, matching_result_id, project_id, template_id, export_type, export_format,
                    file_path, file_size, export_status, export_duration_ms, error_message,
                    metadata, created_at, updated_at, is_active
             FROM export_records WHERE id = ?1"
        )?;

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

        for result in result_iter {
            return Ok(Some(result?));
        }

        Ok(None)
    }

    /// 更新导出记录
    pub fn update(&self, export_record: &ExportRecord) -> Result<()> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        
        conn.execute(
            "UPDATE export_records SET 
                file_size = ?2, export_status = ?3, export_duration_ms = ?4, 
                error_message = ?5, metadata = ?6, updated_at = ?7
             WHERE id = ?1",
            rusqlite::params![
                &export_record.id,
                &export_record.file_size,
                &serde_json::to_string(&export_record.export_status).unwrap(),
                &export_record.export_duration_ms,
                &export_record.error_message,
                &export_record.metadata,
                &export_record.updated_at.to_rfc3339(),
            ],
        )?;
        
        Ok(())
    }

    /// 查询导出记录列表
    pub fn list(&self, options: ExportRecordQueryOptions) -> Result<Vec<ExportRecord>> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        
        let mut query = "SELECT id, matching_result_id, project_id, template_id, export_type, export_format,
                                file_path, file_size, export_status, export_duration_ms, error_message,
                                metadata, created_at, updated_at, is_active
                         FROM export_records WHERE is_active = 1".to_string();
        let mut params: Vec<String> = Vec::new();

        // 添加查询条件
        if let Some(project_id) = &options.project_id {
            query.push_str(" AND project_id = ?");
            params.push(project_id.clone());
        }

        if let Some(matching_result_id) = &options.matching_result_id {
            query.push_str(" AND matching_result_id = ?");
            params.push(matching_result_id.clone());
        }

        if let Some(template_id) = &options.template_id {
            query.push_str(" AND template_id = ?");
            params.push(template_id.clone());
        }

        if let Some(export_type) = &options.export_type {
            query.push_str(" AND export_type = ?");
            params.push(serde_json::to_string(export_type).unwrap());
        }

        if let Some(export_status) = &options.export_status {
            query.push_str(" AND export_status = ?");
            params.push(serde_json::to_string(export_status).unwrap());
        }

        if let Some(keyword) = &options.search_keyword {
            query.push_str(" AND (file_path LIKE ? OR error_message LIKE ?)");
            let search_pattern = format!("%{}%", keyword);
            params.push(search_pattern.clone());
            params.push(search_pattern);
        }

        // 添加日期范围过滤
        if let Some(date_range) = &options.date_range {
            query.push_str(" AND created_at >= ? AND created_at <= ?");
            params.push(date_range.start_date.to_rfc3339());
            params.push(date_range.end_date.to_rfc3339());
        }

        // 添加排序
        let sort_by = options.sort_by.as_deref().unwrap_or("created_at");
        let sort_order = options.sort_order.as_deref().unwrap_or("desc");
        query.push_str(&format!(" ORDER BY {} {}", sort_by, sort_order));

        // 添加分页
        if let Some(limit) = options.limit {
            query.push_str(&format!(" LIMIT {}", limit));
            if let Some(offset) = options.offset {
                query.push_str(&format!(" OFFSET {}", offset));
            }
        }

        let mut stmt = conn.prepare(&query)?;
        let param_refs: Vec<&dyn rusqlite::ToSql> = params.iter().map(|p| p as &dyn rusqlite::ToSql).collect();
        
        let export_record_iter = stmt.query_map(param_refs.as_slice(), |row| {
            self.row_to_export_record(row)
        })?;

        let mut export_records = Vec::new();
        for export_record in export_record_iter {
            export_records.push(export_record?);
        }

        Ok(export_records)
    }

    /// 删除导出记录（软删除）
    pub fn delete(&self, id: &str) -> Result<()> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        
        conn.execute(
            "UPDATE export_records SET is_active = 0, updated_at = ?2 WHERE id = ?1",
            rusqlite::params![id, Utc::now().to_rfc3339()],
        )?;
        
        Ok(())
    }

    /// 获取导出记录统计信息
    pub fn get_statistics(&self, project_id: Option<&str>) -> Result<ExportRecordStatistics> {
        let conn = self.database.get_connection();
        let conn = conn.lock().unwrap();
        
        let mut base_query = "FROM export_records WHERE is_active = 1".to_string();
        let mut params: Vec<String> = Vec::new();
        
        if let Some(pid) = project_id {
            base_query.push_str(" AND project_id = ?");
            params.push(pid.to_string());
        }

        // 总导出次数
        let total_exports: u32 = conn.query_row(
            &format!("SELECT COUNT(*) {}", base_query),
            params.iter().map(|p| p as &dyn rusqlite::ToSql).collect::<Vec<_>>().as_slice(),
            |row| row.get(0)
        )?;

        // 成功导出次数
        let mut success_params = params.clone();
        success_params.push("\"Success\"".to_string());
        let successful_exports: u32 = conn.query_row(
            &format!("SELECT COUNT(*) {} AND export_status = ?", base_query),
            success_params.iter().map(|p| p as &dyn rusqlite::ToSql).collect::<Vec<_>>().as_slice(),
            |row| row.get(0)
        )?;

        // 失败导出次数
        let failed_exports = total_exports - successful_exports;

        // 总文件大小
        let total_file_size: u64 = conn.query_row(
            &format!("SELECT COALESCE(SUM(file_size), 0) {} AND export_status = '\"Success\"'", base_query),
            params.iter().map(|p| p as &dyn rusqlite::ToSql).collect::<Vec<_>>().as_slice(),
            |row| row.get(0)
        ).unwrap_or(0);

        // 平均导出时长
        let average_export_duration_ms: u64 = conn.query_row(
            &format!("SELECT COALESCE(AVG(export_duration_ms), 0) {}", base_query),
            params.iter().map(|p| p as &dyn rusqlite::ToSql).collect::<Vec<_>>().as_slice(),
            |row| row.get(0)
        ).unwrap_or(0);

        // 导出类型统计
        let mut export_type_counts = std::collections::HashMap::new();
        let mut stmt = conn.prepare(&format!(
            "SELECT export_type, COUNT(*) {} GROUP BY export_type", base_query
        ))?;
        
        let type_iter = stmt.query_map(
            params.iter().map(|p| p as &dyn rusqlite::ToSql).collect::<Vec<_>>().as_slice(),
            |row| {
                let export_type: String = row.get(0)?;
                let count: u32 = row.get(1)?;
                Ok((export_type, count))
            }
        )?;

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

        Ok(ExportRecordStatistics {
            total_exports,
            successful_exports,
            failed_exports,
            total_file_size,
            average_export_duration_ms,
            export_type_counts,
        })
    }

    /// 将数据库行转换为导出记录实体
    fn row_to_export_record(&self, row: &Row) -> Result<ExportRecord> {
        let export_type_str: String = row.get("export_type")?;
        let export_type: ExportType = serde_json::from_str(&export_type_str)
            .unwrap_or(ExportType::default());

        let export_format_str: String = row.get("export_format")?;
        let export_format: ExportFormat = serde_json::from_str(&export_format_str)
            .unwrap_or(ExportFormat::default());

        let export_status_str: String = row.get("export_status")?;
        let export_status: ExportStatus = serde_json::from_str(&export_status_str)
            .unwrap_or(ExportStatus::default());

        let created_at_str: String = row.get("created_at")?;
        let updated_at_str: String = row.get("updated_at")?;
        let created_at = DateTime::parse_from_rfc3339(&created_at_str)
            .unwrap_or_else(|_| Utc::now().into())
            .with_timezone(&Utc);
        let updated_at = DateTime::parse_from_rfc3339(&updated_at_str)
            .unwrap_or_else(|_| Utc::now().into())
            .with_timezone(&Utc);

        // 正确处理 is_active 字段
        let is_active = match row.get::<_, rusqlite::types::Value>("is_active")? {
            rusqlite::types::Value::Integer(i) => i != 0,
            rusqlite::types::Value::Text(s) => s == "1" || s.to_lowercase() == "true",
            rusqlite::types::Value::Real(f) => f != 0.0,
            _ => true,
        };

        Ok(ExportRecord {
            id: row.get("id")?,
            matching_result_id: row.get("matching_result_id")?,
            project_id: row.get("project_id")?,
            template_id: row.get("template_id")?,
            export_type,
            export_format,
            file_path: row.get("file_path")?,
            file_size: row.get("file_size")?,
            export_status,
            export_duration_ms: row.get("export_duration_ms")?,
            error_message: row.get("error_message")?,
            metadata: row.get("metadata")?,
            created_at,
            updated_at,
            is_active,
        })
    }
}
