use tauri::State;
use anyhow::Result;

use crate::app_state::AppState;
use crate::data::models::gemini_analysis::{AnalyzeImageRequest, AnalyzeImageResponse};
use crate::data::models::outfit_search::{
    SearchRequest, SearchResponse, LLMQueryRequest, LLMQueryResponse,
    OutfitSearchGlobalConfig, SearchResult, ProductInfo, SearchFilterBuilder
};
use crate::infrastructure::gemini_service::{GeminiService, GeminiConfig};

/// 分析服装图像
/// 遵循 Tauri 开发规范的命令接口设计原则
#[tauri::command]
pub async fn analyze_outfit_image(
    _state: State<'_, AppState>,
    request: AnalyzeImageRequest,
) -> Result<AnalyzeImageResponse, String> {
    // 创建Gemini服务
    let config = GeminiConfig::default();
    let mut gemini_service = GeminiService::new(Some(config))
        .map_err(|e| format!("Failed to create GeminiService: {}", e))?;

    // 执行图像分析
    let analysis_result = gemini_service
        .analyze_outfit_image(&request.image_path)
        .await
        .map_err(|e| {
            eprintln!("Failed to analyze outfit image: {}", e);
            format!("图像分析失败: {}", e)
        })?;

    // 解析JSON结果
    let parsed_result: serde_json::Value = serde_json::from_str(&analysis_result)
        .map_err(|e| format!("Failed to parse analysis result: {}", e))?;

    // 构建响应
    Ok(AnalyzeImageResponse {
        result: parsed_result,
        analysis_time_ms: 1500, // 这里应该记录实际的分析时间
        analyzed_at: chrono::Utc::now(),
    })
}

/// 搜索相似服装
#[tauri::command]
pub async fn search_similar_outfits(
    _state: State<'_, AppState>,
    request: SearchRequest,
) -> Result<SearchResponse, String> {
    let start_time = std::time::Instant::now();

    // 创建Gemini服务实例用于获取访问令牌
    let config = GeminiConfig::default();
    let mut gemini_service = GeminiService::new(Some(config))
        .map_err(|e| format!("Failed to create GeminiService: {}", e))?;

    // 执行直接的 Vertex AI Search 搜索
    let search_results = execute_vertex_ai_search(&mut gemini_service, &request).await
        .map_err(|e| {
            eprintln!("搜索失败: {}", e);
            format!("搜索失败: {}", e)
        })?;

    let search_time_ms = start_time.elapsed().as_millis() as u64;

    Ok(SearchResponse {
        results: search_results.results,
        total_size: search_results.total_size,
        next_page_token: search_results.next_page_token,
        search_time_ms,
        searched_at: chrono::Utc::now(),
    })
}

/// LLM问答
#[tauri::command]
pub async fn ask_llm_outfit_advice(
    _state: State<'_, AppState>,
    request: LLMQueryRequest,
) -> Result<LLMQueryResponse, String> {
    // 创建Gemini服务
    let config = GeminiConfig::default();
    let mut gemini_service = GeminiService::new(Some(config))
        .map_err(|e| format!("Failed to create GeminiService: {}", e))?;

    // 执行LLM问答
    let answer = gemini_service
        .ask_outfit_advice(&request.user_input)
        .await
        .map_err(|e| {
            eprintln!("Failed to get LLM outfit advice: {}", e);
            format!("LLM问答失败: {}", e)
        })?;

    // 构建响应
    Ok(LLMQueryResponse {
        answer,
        related_results: vec![], // 暂时返回空的相关结果
        response_time_ms: 1000,
        responded_at: chrono::Utc::now(),
    })
}

/// 获取搜索建议
#[tauri::command]
pub async fn get_outfit_search_suggestions(
    _state: State<'_, AppState>,
    query: String,
) -> Result<Vec<String>, String> {
    // 基于查询生成搜索建议
    let suggestions = generate_search_suggestions(&query);
    Ok(suggestions)
}

/// 基于分析结果生成搜索配置
#[tauri::command]
pub async fn generate_search_config_from_analysis(
    _state: State<'_, AppState>,
    _analysis_result: crate::data::models::gemini_analysis::OutfitAnalysisResult,
) -> Result<crate::data::models::outfit_search::SearchConfig, String> {
    // TODO: 实现基于分析结果生成搜索配置的逻辑
    // 暂时返回默认配置
    use crate::data::models::outfit_search::{SearchConfig, RelevanceThreshold};
    use std::collections::HashMap;

    Ok(SearchConfig {
        relevance_threshold: RelevanceThreshold::High,
        categories: vec![],
        environments: vec![],
        color_filters: HashMap::new(),
        design_styles: HashMap::new(),
        max_keywords: 10,
    })
}

/// 验证图像文件
#[tauri::command]
pub async fn validate_outfit_image(
    _state: State<'_, AppState>,
    image_path: String,
) -> Result<bool, String> {
    // 检查文件是否存在
    if !std::path::Path::new(&image_path).exists() {
        return Ok(false);
    }
    
    // 检查文件扩展名
    let valid_extensions = ["jpg", "jpeg", "png", "webp"];
    let extension = std::path::Path::new(&image_path)
        .extension()
        .and_then(|ext| ext.to_str())
        .map(|ext| ext.to_lowercase());
    
    match extension {
        Some(ext) if valid_extensions.contains(&ext.as_str()) => Ok(true),
        _ => Ok(false),
    }
}

/// 获取支持的图像格式
#[tauri::command]
pub async fn get_supported_image_formats(
    _state: State<'_, AppState>,
) -> Result<Vec<String>, String> {
    Ok(vec![
        "jpg".to_string(),
        "jpeg".to_string(),
        "png".to_string(),
        "webp".to_string(),
    ])
}

/// 获取默认搜索配置
#[tauri::command]
pub async fn get_default_search_config(
    _state: State<'_, AppState>,
) -> Result<crate::data::models::outfit_search::SearchConfig, String> {
    Ok(crate::data::models::outfit_search::SearchConfig::default())
}

/// 获取全局配置信息
#[tauri::command]
pub async fn get_outfit_search_config(
    _state: State<'_, AppState>,
) -> Result<OutfitSearchConfigInfo, String> {
    let config = OutfitSearchGlobalConfig::default();
    Ok(OutfitSearchConfigInfo {
        google_project_id: config.google_project_id,
        vertex_ai_app_id: config.vertex_ai_app_id,
        storage_bucket_name: config.storage_bucket_name,
        data_store_id: config.data_store_id,
    })
}

/// 配置信息（用于前端显示，不包含敏感信息）
#[derive(serde::Serialize)]
pub struct OutfitSearchConfigInfo {
    pub google_project_id: String,
    pub vertex_ai_app_id: String,
    pub storage_bucket_name: String,
    pub data_store_id: String,
}



/// 生成搜索建议的辅助函数
fn generate_search_suggestions(query: &str) -> Vec<String> {
    let base_suggestions = vec![
        "休闲搭配".to_string(),
        "正式搭配".to_string(),
        "运动风格".to_string(),
        "街头风格".to_string(),
        "简约风格".to_string(),
        "复古风格".to_string(),
        "牛仔裤搭配".to_string(),
        "连衣裙搭配".to_string(),
        "外套搭配".to_string(),
        "夏季搭配".to_string(),
        "冬季搭配".to_string(),
        "约会搭配".to_string(),
        "工作搭配".to_string(),
        "聚会搭配".to_string(),
    ];
    
    if query.is_empty() {
        return base_suggestions;
    }
    
    // 基于查询过滤和排序建议
    let mut filtered_suggestions: Vec<String> = base_suggestions
        .into_iter()
        .filter(|suggestion| {
            suggestion.contains(query) || 
            query.chars().any(|c| suggestion.contains(c))
        })
        .collect();
    
    // 如果过滤后的建议太少，添加一些通用建议
    if filtered_suggestions.len() < 5 {
        filtered_suggestions.extend(vec![
            format!("{} 搭配", query),
            format!("{} 风格", query),
            format!("如何搭配 {}", query),
        ]);
    }
    
    // 限制建议数量
    filtered_suggestions.truncate(10);
    filtered_suggestions
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_generate_search_suggestions() {
        let suggestions = generate_search_suggestions("牛仔");
        assert!(suggestions.iter().any(|s| s.contains("牛仔")));
        assert!(suggestions.len() <= 10);
    }

    #[test]
    fn test_generate_search_suggestions_empty() {
        let suggestions = generate_search_suggestions("");
        assert!(!suggestions.is_empty());
        assert!(suggestions.len() <= 10);
    }

    #[test]
    fn test_outfit_search_config_info_serialization() {
        let config_info = OutfitSearchConfigInfo {
            google_project_id: "test-project".to_string(),
            vertex_ai_app_id: "test-app".to_string(),
            storage_bucket_name: "test-bucket".to_string(),
            data_store_id: "test-store".to_string(),
        };

        let serialized = serde_json::to_string(&config_info).unwrap();
        assert!(serialized.contains("test-project"));
    }

    #[test]
    fn test_search_request_creation() {
        use crate::data::models::outfit_search::{SearchConfig, RelevanceThreshold};

        let request = SearchRequest {
            query: "牛仔裤搭配".to_string(),
            config: SearchConfig {
                relevance_threshold: RelevanceThreshold::High,
                categories: vec!["上装".to_string(), "下装".to_string()],
                environments: vec!["Outdoor".to_string()],
                color_filters: std::collections::HashMap::new(),
                design_styles: std::collections::HashMap::new(),
                max_keywords: 10,
            },
            page_size: 9,
            page_offset: 0,
        };

        assert_eq!(request.query, "牛仔裤搭配");
        assert_eq!(request.page_size, 9);
        assert_eq!(request.config.categories.len(), 2);
    }

    #[test]
    fn test_search_filter_builder() {
        use crate::data::models::outfit_search::SearchConfig;

        let mut config = SearchConfig::default();
        config.categories = vec!["上装".to_string()];
        config.environments = vec!["Outdoor".to_string()];

        let filters = SearchFilterBuilder::build_filters(&config);
        assert!(filters.contains("上装") || filters.contains("Outdoor"));
    }

    #[test]
    fn test_query_keywords_builder() {
        use crate::data::models::outfit_search::SearchConfig;

        let mut config = SearchConfig::default();
        config.environments = vec!["Outdoor".to_string()];

        let keywords = SearchFilterBuilder::build_query_keywords(&config);
        assert!(keywords.contains(&"Outdoor".to_string()));
    }
}

/// 执行 Vertex AI Search 搜索
async fn execute_vertex_ai_search(
    _gemini_service: &mut GeminiService,
    request: &SearchRequest,
) -> Result<SearchResponse, anyhow::Error> {
    // 1. 获取访问令牌（通过直接调用API）
    let access_token = get_google_access_token().await?;

    // 2. 获取全局配置
    let global_config = OutfitSearchGlobalConfig::default();

    // 3. 构建搜索过滤器
    let search_filter = SearchFilterBuilder::build_filters(&request.config);

    // 4. 构建查询关键词
    let query_keywords = SearchFilterBuilder::build_query_keywords(&request.config);

    // 5. 组合查询字符串
    let enhanced_query = if query_keywords.is_empty() {
        request.query.clone()
    } else {
        format!("{} {}", request.query, query_keywords.join(" "))
    };

    // 6. 构建请求负载
    let mut payload = serde_json::json!({
        "query": enhanced_query,
        "relevanceThreshold": request.config.relevance_threshold.to_value().to_string(),
        "relevanceScoreSpec": {
            "returnRelevanceScore": true
        },
        "pageSize": request.page_size,
        "offset": request.page_offset
    });

    // 7. 添加过滤器（如果有）
    if !search_filter.is_empty() {
        payload["filter"] = serde_json::Value::String(search_filter);
    }

    // 8. 构建请求URL
    let search_url = format!(
        "https://discoveryengine.googleapis.com/v1beta/projects/{}/locations/global/collections/default_collection/engines/{}/servingConfigs/default_search:search",
        global_config.google_project_id,
        global_config.vertex_ai_app_id
    );

    // 9. 发送HTTP请求
    let client = reqwest::Client::new();
    let response = client
        .post(&search_url)
        .header("Authorization", format!("Bearer {}", access_token))
        .header("Content-Type", "application/json")
        .json(&payload)
        .send()
        .await?;

    let status = response.status();
    let response_text = response.text().await?;

    if !status.is_success() {
        return Err(anyhow::anyhow!("Vertex AI Search 请求失败: {} - {}", status, response_text));
    }

    // 10. 解析响应
    let vertex_response: serde_json::Value = serde_json::from_str(&response_text)?;

    // 11. 转换为我们的搜索结果格式
    let search_results = convert_vertex_response_to_search_results(&vertex_response, request)?;

    Ok(search_results)
}

/// 获取 Google 访问令牌
async fn get_google_access_token() -> Result<String, anyhow::Error> {
    let config = GeminiConfig::default();
    let client = reqwest::Client::new();

    let url = format!("{}/google/access-token", config.base_url);

    let response = client
        .get(&url)
        .header("Authorization", format!("Bearer {}", config.bearer_token))
        .send()
        .await?;

    let status = response.status();
    if !status.is_success() {
        let error_body = response.text().await.unwrap_or_default();
        return Err(anyhow::anyhow!("获取访问令牌失败: {} - {}", status, error_body));
    }

    let response_text = response.text().await?;
    let token_response: serde_json::Value = serde_json::from_str(&response_text)?;

    let access_token = token_response
        .get("access_token")
        .and_then(|v| v.as_str())
        .ok_or_else(|| anyhow::anyhow!("访问令牌响应中未找到 access_token 字段"))?;

    Ok(access_token.to_string())
}

/// 将 Vertex AI Search 响应转换为我们的搜索结果格式
fn convert_vertex_response_to_search_results(
    vertex_response: &serde_json::Value,
    request: &SearchRequest,
) -> Result<SearchResponse, anyhow::Error> {

    let mut results = Vec::new();

    // 解析 Vertex AI Search 响应
    if let Some(vertex_results) = vertex_response.get("results").and_then(|v| v.as_array()) {
        for vertex_result in vertex_results {
            if let Ok(search_result) = parse_vertex_result_to_search_result(vertex_result) {
                // 应用相关性阈值过滤
                if search_result.relevance_score >= request.config.relevance_threshold.to_value() {
                    results.push(search_result);
                }
            }
        }
    }

    let total_size = vertex_response
        .get("totalSize")
        .and_then(|v| v.as_u64())
        .unwrap_or(results.len() as u64) as usize;

    let next_page_token = vertex_response
        .get("nextPageToken")
        .and_then(|v| v.as_str())
        .map(|s| s.to_string());

    Ok(SearchResponse {
        results,
        total_size,
        next_page_token,
        search_time_ms: 0, // 将在调用方设置
        searched_at: chrono::Utc::now(),
    })
}

/// 解析单个 Vertex AI Search 结果为我们的搜索结果格式
fn parse_vertex_result_to_search_result(vertex_result: &serde_json::Value) -> Result<SearchResult, anyhow::Error> {

    // 获取文档数据
    let document = vertex_result
        .get("document")
        .ok_or_else(|| anyhow::anyhow!("Vertex result missing document field"))?;

    // 获取结构化数据
    let struct_data = document
        .get("structData")
        .ok_or_else(|| anyhow::anyhow!("Document missing structData field"))?;

    // 解析基本信息
    let id = document
        .get("id")
        .and_then(|v| v.as_str())
        .unwrap_or(&format!("result_{}", chrono::Utc::now().timestamp()))
        .to_string();

    // 从 structData 中提取信息
    let style_description = struct_data
        .get("style_description")
        .and_then(|v| v.as_str())
        .unwrap_or("时尚搭配")
        .to_string();

    let environment_tags = struct_data
        .get("environment_tags")
        .and_then(|v| v.as_array())
        .map(|arr| {
            arr.iter()
                .filter_map(|v| v.as_str())
                .map(|s| s.to_string())
                .collect()
        })
        .unwrap_or_else(|| vec!["日常".to_string()]);

    // 解析产品信息
    let products = struct_data
        .get("products")
        .and_then(|v| v.as_array())
        .map(|arr| {
            arr.iter()
                .filter_map(|v| parse_vertex_product_info(v).ok())
                .collect()
        })
        .unwrap_or_else(Vec::new);

    // 获取图片URL（可能在不同的字段中）
    let image_url = struct_data
        .get("uri")
        .or_else(|| struct_data.get("image_url"))
        .or_else(|| struct_data.get("url"))
        .and_then(|v| v.as_str())
        .unwrap_or("")
        .to_string();

    // 获取相关性评分
    let relevance_score = vertex_result
        .get("modelScores")
        .and_then(|scores| scores.get("relevance"))
        .and_then(|score| score.get("values"))
        .and_then(|values| values.as_array())
        .and_then(|arr| arr.first())
        .and_then(|v| v.as_f64())
        .unwrap_or(0.8);

    Ok(SearchResult {
        id,
        image_url,
        style_description,
        environment_tags,
        products,
        relevance_score,
    })
}

/// 解析 Vertex AI Search 中的产品信息
fn parse_vertex_product_info(value: &serde_json::Value) -> Result<ProductInfo, anyhow::Error> {
    use crate::data::models::gemini_analysis::ColorHSV;

    let category = value
        .get("category")
        .and_then(|v| v.as_str())
        .unwrap_or("服装")
        .to_string();

    let description = value
        .get("description")
        .and_then(|v| v.as_str())
        .unwrap_or("时尚单品")
        .to_string();

    let color_pattern = value
        .get("color_pattern")
        .and_then(|v| {
            let hue = v.get("Hue").or_else(|| v.get("hue")).and_then(|h| h.as_f64()).unwrap_or(0.0);
            let saturation = v.get("Saturation").or_else(|| v.get("saturation")).and_then(|s| s.as_f64()).unwrap_or(0.5);
            let value = v.get("Value").or_else(|| v.get("value")).and_then(|val| val.as_f64()).unwrap_or(0.8);
            Some(ColorHSV::new(hue, saturation, value))
        })
        .unwrap_or_else(|| ColorHSV::new(0.0, 0.5, 0.8));

    let design_styles = value
        .get("design_styles")
        .and_then(|v| v.as_array())
        .map(|arr| {
            arr.iter()
                .filter_map(|v| v.as_str())
                .map(|s| s.to_string())
                .collect()
        })
        .unwrap_or_else(|| vec!["时尚".to_string()]);

    Ok(ProductInfo {
        category,
        description,
        color_pattern,
        design_styles,
    })
}

/// 获取所有服装搜索相关的Tauri命令名称
pub fn get_outfit_search_command_names() -> Vec<&'static str> {
    vec![
        "analyze_outfit_image",
        "search_similar_outfits",
        "ask_llm_outfit_advice",
        "get_outfit_search_suggestions",
        "generate_search_config_from_analysis",
        "validate_outfit_image",
        "get_supported_image_formats",
        "get_default_search_config",
        "get_outfit_search_config",
    ]
}


