use std::sync::Arc;
use anyhow::Result;
use chrono::Utc;
use std::fs;

use crate::data::repositories::export_record_repository::ExportRecordRepository;
use crate::data::repositories::template_matching_result_repository::TemplateMatchingResultRepository;
use crate::data::models::export_record::{
    ExportRecord, ExportType, ExportFormat,
    CreateExportRecordRequest, ExportRecordQueryOptions, ExportRecordStatistics,
};

/// 导出记录服务
/// 遵循 Tauri 开发规范的业务逻辑设计原则
pub struct ExportRecordService {
    export_record_repository: Arc<ExportRecordRepository>,
    matching_result_repository: Arc<TemplateMatchingResultRepository>,
}

impl ExportRecordService {
    /// 创建新的导出记录服务实例
    pub fn new(
        export_record_repository: Arc<ExportRecordRepository>,
        matching_result_repository: Arc<TemplateMatchingResultRepository>,
    ) -> Self {
        Self {
            export_record_repository,
            matching_result_repository,
        }
    }

    /// 创建导出记录
    pub async fn create_export_record(
        &self,
        matching_result_id: String,
        export_type: ExportType,
        export_format: ExportFormat,
        file_path: String,
        metadata: Option<String>,
    ) -> Result<ExportRecord> {
        let request = CreateExportRecordRequest {
            matching_result_id,
            export_type,
            export_format,
            file_path,
            metadata,
        };

        let export_record = self.export_record_repository.create(request)
            .map_err(|e| anyhow::anyhow!("创建导出记录失败: {}", e))?;

        Ok(export_record)
    }

    /// 标记导出成功并更新匹配结果的导出次数
    pub async fn mark_export_success(
        &self,
        export_record_id: String,
        file_path: String,
        duration_ms: u64,
    ) -> Result<()> {
        // 获取导出记录
        let mut export_record = self.export_record_repository.get_by_id(&export_record_id)
            .map_err(|e| anyhow::anyhow!("获取导出记录失败: {}", e))?
            .ok_or_else(|| anyhow::anyhow!("导出记录不存在: {}", export_record_id))?;

        // 获取文件大小
        let file_size = match fs::metadata(&file_path) {
            Ok(metadata) => Some(metadata.len()),
            Err(_) => None,
        };

        // 标记导出成功
        export_record.mark_success(file_size, duration_ms);

        // 更新导出记录
        self.export_record_repository.update(&export_record)
            .map_err(|e| anyhow::anyhow!("更新导出记录失败: {}", e))?;

        // 增加匹配结果的导出次数
        self.matching_result_repository.increment_export_count(&export_record.matching_result_id)
            .map_err(|e| anyhow::anyhow!("更新导出次数失败: {}", e))?;

        println!("✅ 导出记录已更新: {} -> 成功", export_record_id);
        println!("📊 匹配结果导出次数已增加: {}", export_record.matching_result_id);

        Ok(())
    }

    /// 标记导出失败
    pub async fn mark_export_failed(
        &self,
        export_record_id: String,
        error_message: String,
        duration_ms: u64,
    ) -> Result<()> {
        // 获取导出记录
        let mut export_record = self.export_record_repository.get_by_id(&export_record_id)
            .map_err(|e| anyhow::anyhow!("获取导出记录失败: {}", e))?
            .ok_or_else(|| anyhow::anyhow!("导出记录不存在: {}", export_record_id))?;

        // 标记导出失败
        export_record.mark_failed(error_message.clone(), duration_ms);

        // 更新导出记录
        self.export_record_repository.update(&export_record)
            .map_err(|e| anyhow::anyhow!("更新导出记录失败: {}", e))?;

        println!("❌ 导出记录已更新: {} -> 失败: {}", export_record_id, error_message);

        Ok(())
    }

    /// 获取导出记录详情
    pub async fn get_export_record(&self, id: &str) -> Result<Option<ExportRecord>> {
        let export_record = self.export_record_repository.get_by_id(id)
            .map_err(|e| anyhow::anyhow!("获取导出记录失败: {}", e))?;

        Ok(export_record)
    }

    /// 查询导出记录列表
    pub async fn list_export_records(
        &self,
        options: ExportRecordQueryOptions,
    ) -> Result<Vec<ExportRecord>> {
        let export_records = self.export_record_repository.list(options)
            .map_err(|e| anyhow::anyhow!("查询导出记录列表失败: {}", e))?;

        Ok(export_records)
    }

    /// 删除导出记录
    pub async fn delete_export_record(&self, id: &str) -> Result<()> {
        self.export_record_repository.delete(id)
            .map_err(|e| anyhow::anyhow!("删除导出记录失败: {}", e))?;

        println!("🗑️ 导出记录已删除: {}", id);

        Ok(())
    }

    /// 获取项目的导出记录统计信息
    pub async fn get_project_export_statistics(
        &self,
        project_id: &str,
    ) -> Result<ExportRecordStatistics> {
        let statistics = self.export_record_repository.get_statistics(Some(project_id))
            .map_err(|e| anyhow::anyhow!("获取导出统计信息失败: {}", e))?;

        Ok(statistics)
    }

    /// 获取全局导出记录统计信息
    pub async fn get_global_export_statistics(&self) -> Result<ExportRecordStatistics> {
        let statistics = self.export_record_repository.get_statistics(None)
            .map_err(|e| anyhow::anyhow!("获取全局导出统计信息失败: {}", e))?;

        Ok(statistics)
    }

    /// 清理过期的导出记录
    pub async fn cleanup_expired_records(&self, days: u32) -> Result<u32> {
        let cutoff_date = Utc::now() - chrono::Duration::days(days as i64);
        
        // 查询过期的导出记录
        let options = ExportRecordQueryOptions {
            project_id: None,
            matching_result_id: None,
            template_id: None,
            export_type: None,
            export_status: None,
            limit: None,
            offset: None,
            search_keyword: None,
            sort_by: None,
            sort_order: None,
            date_range: Some(crate::data::models::export_record::DateRange {
                start_date: chrono::DateTime::from_timestamp(0, 0).unwrap_or_default(),
                end_date: cutoff_date,
            }),
        };

        let expired_records = self.list_export_records(options).await?;
        let count = expired_records.len() as u32;

        // 删除过期记录
        for record in expired_records {
            self.delete_export_record(&record.id).await?;
        }

        println!("🧹 已清理 {} 条过期导出记录（超过 {} 天）", count, days);

        Ok(count)
    }

    /// 验证文件是否存在
    pub async fn validate_export_file(&self, export_record_id: &str) -> Result<bool> {
        let export_record = self.get_export_record(export_record_id).await?
            .ok_or_else(|| anyhow::anyhow!("导出记录不存在: {}", export_record_id))?;

        let file_exists = fs::metadata(&export_record.file_path).is_ok();

        if !file_exists {
            println!("⚠️ 导出文件不存在: {}", export_record.file_path);
        }

        Ok(file_exists)
    }

    /// 获取匹配结果的所有导出记录
    pub async fn get_matching_result_exports(
        &self,
        matching_result_id: &str,
    ) -> Result<Vec<ExportRecord>> {
        let options = ExportRecordQueryOptions {
            project_id: None,
            matching_result_id: Some(matching_result_id.to_string()),
            template_id: None,
            export_type: None,
            export_status: None,
            limit: None,
            offset: None,
            search_keyword: None,
            sort_by: Some("created_at".to_string()),
            sort_order: Some("desc".to_string()),
            date_range: None,
        };

        self.list_export_records(options).await
    }

    /// 获取项目的导出记录
    pub async fn get_project_exports(
        &self,
        project_id: &str,
        limit: Option<u32>,
        offset: Option<u32>,
    ) -> Result<Vec<ExportRecord>> {
        let options = ExportRecordQueryOptions {
            project_id: Some(project_id.to_string()),
            matching_result_id: None,
            template_id: None,
            export_type: None,
            export_status: None,
            limit,
            offset,
            search_keyword: None,
            sort_by: Some("created_at".to_string()),
            sort_order: Some("desc".to_string()),
            date_range: None,
        };

        self.list_export_records(options).await
    }

    /// 重新导出（基于现有导出记录）
    pub async fn re_export(
        &self,
        export_record_id: &str,
        new_file_path: String,
    ) -> Result<ExportRecord> {
        let original_record = self.get_export_record(export_record_id).await?
            .ok_or_else(|| anyhow::anyhow!("原始导出记录不存在: {}", export_record_id))?;

        // 创建新的导出记录
        let new_record = self.create_export_record(
            original_record.matching_result_id,
            original_record.export_type,
            original_record.export_format,
            new_file_path,
            original_record.metadata,
        ).await?;

        println!("🔄 基于记录 {} 创建了新的导出记录: {}", export_record_id, new_record.id);

        Ok(new_record)
    }
}
