use tauri::{command, AppHandle, Manager};
use serde::{Deserialize, Serialize};
use crate::infrastructure::monitoring::{PERFORMANCE_MONITOR, PerformanceReport};
use tracing::info;

/// 应用信息结构
#[derive(Debug, Serialize, Deserialize)]
pub struct AppInfo {
    pub name: String,
    pub version: String,
    pub platform: String,
}

/// 选择目录命令
/// 遵循 Tauri 开发规范的系统集成设计
#[command]
pub fn select_directory(app: AppHandle) -> Result<Option<String>, String> {
    use tauri_plugin_dialog::DialogExt;

    // 使用同步方式打开文件夹选择对话框
    let dialog = app.dialog().file().set_title("选择项目目录");

    // 创建一个简单的阻塞实现
    let (tx, rx) = std::sync::mpsc::channel();

    dialog.pick_folder(move |folder_path| {
        let _ = tx.send(folder_path);
    });

    // 等待结果，设置超时
    match rx.recv_timeout(std::time::Duration::from_secs(30)) {
        Ok(Some(path)) => {
            let path_str = path.to_string();
            Ok(Some(path_str))
        }
        Ok(None) => Ok(None),
        Err(_) => Err("对话框操作超时或失败".to_string()),
    }
}

/// 获取应用信息命令
#[command]
pub async fn get_app_info() -> Result<AppInfo, String> {
    Ok(AppInfo {
        name: "MixVideo Desktop".to_string(),
        version: env!("CARGO_PKG_VERSION").to_string(),
        platform: std::env::consts::OS.to_string(),
    })
}

/// 验证目录是否存在命令
#[command]
pub async fn validate_directory(path: String) -> Result<bool, String> {
    use std::path::Path;
    
    let path = Path::new(&path);
    Ok(path.exists() && path.is_dir())
}

/// 获取目录名称命令
#[command]
pub async fn get_directory_name(path: String) -> Result<String, String> {
    use std::path::Path;

    let path = Path::new(&path);
    match path.file_name() {
        Some(name) => Ok(name.to_string_lossy().to_string()),
        None => Err("无效的目录路径".to_string()),
    }
}

/// 获取数据库信息命令（调试用）
#[command]
pub async fn get_database_info() -> Result<String, String> {
    use crate::infrastructure::database::Database;
    Ok(Database::get_database_path_info())
}



/// 清理无效项目记录命令
/// 删除路径不存在的项目记录，解决 UNIQUE 约束冲突
#[command]
pub async fn cleanup_invalid_projects(app: AppHandle) -> Result<String, String> {
    let state = app.state::<crate::app_state::AppState>();

    // 获取项目仓库
    let repository_guard = state.get_project_repository().map_err(|e| e.to_string())?;

    if let Some(repository) = repository_guard.as_ref() {
        // 使用项目仓库获取所有项目
        let projects = repository.find_all_active().map_err(|e| e.to_string())?;

        let mut invalid_count = 0;

        // 检查每个项目的路径是否存在
        for project in projects {
            if !std::path::Path::new(&project.path).exists() {
                // 路径不存在，删除这个项目
                match repository.delete(&project.id) {
                    Ok(_) => {
                        invalid_count += 1;
                        println!("Deleted invalid project: {} (path: {})", project.name, project.path);
                    }
                    Err(e) => {
                        println!("Failed to delete invalid project {}: {}", project.id, e);
                    }
                }
            }
        }

        if invalid_count > 0 {
            Ok(format!("已清理 {} 个无效项目记录", invalid_count))
        } else {
            Ok("没有发现无效的项目记录".to_string())
        }
    } else {
        Err("项目仓库未初始化".to_string())
    }
}

/// 获取性能报告命令
#[command]
pub async fn get_performance_report() -> Result<PerformanceReport, String> {
    info!("生成性能报告");

    let report = PERFORMANCE_MONITOR.generate_report();

    info!(
        total_operations = report.total_operations,
        average_response_time_ms = report.average_response_time.as_millis(),
        error_rate = report.error_rate,
        "性能报告生成完成"
    );

    Ok(report)
}

/// 清理性能监控数据命令
#[command]
pub async fn cleanup_performance_data() -> Result<String, String> {
    info!("清理性能监控数据");

    PERFORMANCE_MONITOR.cleanup_old_snapshots();

    Ok("性能监控数据清理完成".to_string())
}

/// 记录自定义性能指标命令
#[command]
pub async fn record_performance_metric(name: String, value: f64) -> Result<(), String> {
    info!(metric_name = %name, value = value, "记录自定义性能指标");

    PERFORMANCE_MONITOR.record_metric(&name, value);

    Ok(())
}

/// 选择文件命令
#[command]
pub fn select_file(app: AppHandle, filters: Option<Vec<(String, Vec<String>)>>) -> Result<Option<String>, String> {
    use tauri_plugin_dialog::DialogExt;

    let mut dialog = app.dialog().file().set_title("选择文件");

    // 添加文件过滤器
    if let Some(filter_list) = filters {
        for (name, extensions) in filter_list {
            let ext_refs: Vec<&str> = extensions.iter().map(|s| s.as_str()).collect();
            dialog = dialog.add_filter(&name, &ext_refs);
        }
    }

    // 创建一个简单的阻塞实现
    let (tx, rx) = std::sync::mpsc::channel();

    dialog.pick_file(move |file_path| {
        let _ = tx.send(file_path);
    });

    // 等待结果，设置超时
    match rx.recv_timeout(std::time::Duration::from_secs(30)) {
        Ok(Some(path)) => Ok(Some(path.to_string())),
        Ok(None) => Ok(None),
        Err(_) => Err("文件选择超时".to_string()),
    }
}

/// 打开文件所在目录命令
#[command]
pub async fn open_file_directory(file_path: String) -> Result<(), String> {
    use std::path::Path;
    use std::process::Command;

    let path = Path::new(&file_path);

    // 获取文件所在目录
    let directory = if path.is_file() {
        path.parent().ok_or("无法获取文件所在目录")?
    } else if path.is_dir() {
        path
    } else {
        return Err("文件路径不存在".to_string());
    };

    // 根据操作系统打开目录
    let result = if cfg!(target_os = "windows") {
        // Windows: 使用 explorer 并选中文件
        if path.is_file() {
            Command::new("explorer")
                .args(["/select,", &file_path])
                .spawn()
        } else {
            Command::new("explorer")
                .arg(directory)
                .spawn()
        }
    } else if cfg!(target_os = "macos") {
        // macOS: 使用 open 命令
        if path.is_file() {
            Command::new("open")
                .args(["-R", &file_path])
                .spawn()
        } else {
            Command::new("open")
                .arg(directory)
                .spawn()
        }
    } else {
        // Linux: 使用 xdg-open
        Command::new("xdg-open")
            .arg(directory)
            .spawn()
    };

    match result {
        Ok(_) => {
            info!("成功打开目录: {:?}", directory);
            Ok(())
        }
        Err(e) => {
            let error_msg = format!("打开目录失败: {}", e);
            tracing::error!("{}", error_msg);
            Err(error_msg)
        }
    }
}

/// 播放视频片段命令
#[command]
pub async fn play_video_segment(file_path: String, start_time: f64, end_time: f64) -> Result<(), String> {
    use std::path::Path;
    use std::process::Command;

    let path = Path::new(&file_path);

    // 检查文件是否存在
    if !path.exists() {
        return Err("视频文件不存在".to_string());
    }

    // 根据操作系统使用不同的播放器
    let result = if cfg!(target_os = "windows") {
        // Windows: 尝试使用系统默认播放器
        Command::new("cmd")
            .args(["/C", "start", "", &file_path])
            .spawn()
    } else if cfg!(target_os = "macos") {
        // macOS: 使用 open 命令
        Command::new("open")
            .arg(&file_path)
            .spawn()
    } else {
        // Linux: 使用 xdg-open
        Command::new("xdg-open")
            .arg(&file_path)
            .spawn()
    };

    match result {
        Ok(_) => {
            info!("成功启动视频播放: {} ({}s - {}s)", file_path, start_time, end_time);
            Ok(())
        }
        Err(e) => {
            let error_msg = format!("播放视频失败: {}", e);
            tracing::error!("{}", error_msg);
            Err(error_msg)
        }
    }
}
