use tauri::command;
use std::path::Path;
use anyhow::{Result, anyhow};
use reqwest;
use tokio::fs;
use tokio::io::AsyncWriteExt;

/// 从URI下载图片到本地文件
#[command]
pub async fn download_image_from_uri(uri: String, file_path: String) -> Result<(), String> {
    println!("🔽 开始下载图片: {} -> {}", uri, file_path);

    // 验证URI格式
    if !uri.starts_with("http://") && !uri.starts_with("https://") {
        return Err("无效的图片URI格式".to_string());
    }

    // 验证文件路径
    let path = Path::new(&file_path);
    if let Some(parent) = path.parent() {
        if !parent.exists() {
            if let Err(e) = std::fs::create_dir_all(parent) {
                return Err(format!("创建目录失败: {}", e));
            }
        }
    }

    // 下载图片
    match download_image_internal(&uri, &file_path).await {
        Ok(_) => {
            println!("✅ 图片下载成功: {}", file_path);
            Ok(())
        }
        Err(e) => {
            eprintln!("❌ 图片下载失败: {}", e);
            Err(format!("下载失败: {}", e))
        }
    }
}

/// 获取默认下载目录
#[command]
pub async fn get_default_download_directory() -> Result<String, String> {
    // 尝试获取用户下载目录
    if let Some(download_dir) = dirs::download_dir() {
        Ok(download_dir.to_string_lossy().to_string())
    } else {
        // 如果获取失败，使用当前目录
        match std::env::current_dir() {
            Ok(current_dir) => Ok(current_dir.to_string_lossy().to_string()),
            Err(e) => Err(format!("获取目录失败: {}", e))
        }
    }
}

/// 检查图片URI是否有效
#[command]
pub async fn validate_image_uri(uri: String) -> Result<bool, String> {
    if !uri.starts_with("http://") && !uri.starts_with("https://") {
        return Ok(false);
    }

    // 发送HEAD请求检查资源是否存在
    match reqwest::Client::new().head(&uri).send().await {
        Ok(response) => {
            let is_valid = response.status().is_success();
            let content_type = response.headers()
                .get("content-type")
                .and_then(|ct| ct.to_str().ok())
                .unwrap_or("");
            
            // 检查是否为图片类型
            let is_image = content_type.starts_with("image/");
            
            Ok(is_valid && is_image)
        }
        Err(_) => Ok(false)
    }
}

/// 获取图片信息
#[command]
pub async fn get_image_info(uri: String) -> Result<ImageInfo, String> {
    if !uri.starts_with("http://") && !uri.starts_with("https://") {
        return Err("无效的图片URI格式".to_string());
    }

    match get_image_info_internal(&uri).await {
        Ok(info) => Ok(info),
        Err(e) => Err(format!("获取图片信息失败: {}", e))
    }
}

/// 图片信息结构
#[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct ImageInfo {
    pub content_type: String,
    pub content_length: Option<u64>,
    pub last_modified: Option<String>,
    pub is_valid: bool,
}

/// 内部下载实现
async fn download_image_internal(uri: &str, file_path: &str) -> Result<()> {
    // 创建HTTP客户端
    let client = reqwest::Client::builder()
        .timeout(std::time::Duration::from_secs(30))
        .build()
        .map_err(|e| anyhow!("创建HTTP客户端失败: {}", e))?;

    // 发送GET请求
    let response = client
        .get(uri)
        .send()
        .await
        .map_err(|e| anyhow!("请求失败: {}", e))?;

    // 检查响应状态
    if !response.status().is_success() {
        return Err(anyhow!("HTTP错误: {}", response.status()));
    }

    // 检查内容类型
    let content_type = response.headers()
        .get("content-type")
        .and_then(|ct| ct.to_str().ok())
        .unwrap_or("");

    if !content_type.starts_with("image/") {
        return Err(anyhow!("不是有效的图片类型: {}", content_type));
    }

    // 获取响应字节
    let bytes = response
        .bytes()
        .await
        .map_err(|e| anyhow!("读取响应数据失败: {}", e))?;

    // 写入文件
    let mut file = fs::File::create(file_path)
        .await
        .map_err(|e| anyhow!("创建文件失败: {}", e))?;

    file.write_all(&bytes)
        .await
        .map_err(|e| anyhow!("写入文件失败: {}", e))?;

    file.flush()
        .await
        .map_err(|e| anyhow!("刷新文件失败: {}", e))?;

    println!("📁 文件已保存: {} ({} bytes)", file_path, bytes.len());
    Ok(())
}

/// 内部获取图片信息实现
async fn get_image_info_internal(uri: &str) -> Result<ImageInfo> {
    let client = reqwest::Client::builder()
        .timeout(std::time::Duration::from_secs(10))
        .build()
        .map_err(|e| anyhow!("创建HTTP客户端失败: {}", e))?;

    let response = client
        .head(uri)
        .send()
        .await
        .map_err(|e| anyhow!("请求失败: {}", e))?;

    let is_valid = response.status().is_success();
    
    let content_type = response.headers()
        .get("content-type")
        .and_then(|ct| ct.to_str().ok())
        .unwrap_or("unknown")
        .to_string();

    let content_length = response.headers()
        .get("content-length")
        .and_then(|cl| cl.to_str().ok())
        .and_then(|cl| cl.parse().ok());

    let last_modified = response.headers()
        .get("last-modified")
        .and_then(|lm| lm.to_str().ok())
        .map(|lm| lm.to_string());

    Ok(ImageInfo {
        content_type: content_type.clone(),
        content_length,
        last_modified,
        is_valid: is_valid && content_type.starts_with("image/"),
    })
}
