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

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

/// 分析服装图像
/// 遵循 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::{RelevanceThreshold, SearchConfig, ColorThresholds};
    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,
        debug_mode: false,
        custom_filters: Vec::new(),
        query_enhancement_enabled: true,
        color_thresholds: ColorThresholds::default(),
    })
}

/// 验证图像文件
#[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 generate_outfit_recommendations(
    _state: State<'_, AppState>,
    request: OutfitRecommendationRequest,
) -> Result<OutfitRecommendationResponse, String> {
    println!("🎨 收到穿搭方案生成请求: {:?}", request);

    // 创建Gemini服务
    let config = GeminiConfig::default();
    let mut gemini_service = GeminiService::new(Some(config))
        .map_err(|e| format!("Failed to create GeminiService: {}", e))?;

    // 生成穿搭方案
    let response = gemini_service
        .generate_outfit_recommendations(&request)
        .await
        .map_err(|e| {
            eprintln!("Failed to generate outfit recommendations: {}", e);
            format!("穿搭方案生成失败: {}", e)
        })?;

    println!("✅ 穿搭方案生成成功，共生成 {} 个方案", response.recommendations.len());
    Ok(response)
}

/// 获取默认搜索配置
#[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() {
        let mut suggestions = base_suggestions;
        suggestions.truncate(10);
        return 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::{RelevanceThreshold, SearchConfig, ColorThresholds};

        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,
                debug_mode: false,
                custom_filters: Vec::new(),
                query_enhancement_enabled: true,
                color_thresholds: ColorThresholds::default(),
            },
            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()));
    }

    #[test]
    fn test_convert_s3_to_cdn_url() {
        // 测试 s3://ap-northeast-2/modal-media-cache/ 转换
        let s3_url = "s3://ap-northeast-2/modal-media-cache/image.jpg";
        let expected = "https://cdn.roasmax.cn/image.jpg";
        assert_eq!(convert_s3_to_cdn_url(s3_url), expected);

        // 测试 gs://fashion_image_block/ 转换
        let gs_url = "gs://fashion_image_block/image.jpg";
        let expected = "https://storage.googleapis.com/fashion_image_block/image.jpg";
        assert_eq!(convert_s3_to_cdn_url(gs_url), expected);

        // 测试其他 gs:// 转换
        let gs_url = "gs://other-bucket/image.jpg";
        let expected = "https://storage.googleapis.com/other-bucket/image.jpg";
        assert_eq!(convert_s3_to_cdn_url(gs_url), expected);

        // 测试其他 s3:// 转换
        let s3_url = "s3://other-bucket/image.jpg";
        let expected = "https://cdn.roasmax.cn/other-bucket/image.jpg";
        assert_eq!(convert_s3_to_cdn_url(s3_url), expected);

        // 测试普通HTTP URL（不转换）
        let http_url = "https://example.com/image.jpg";
        assert_eq!(convert_s3_to_cdn_url(http_url), http_url);

        // 测试空字符串
        assert_eq!(convert_s3_to_cdn_url(""), "");
    }
}

/// 将S3/GS URL转换为CDN URL
fn convert_s3_to_cdn_url(s3_url: &str) -> String {
    if s3_url.starts_with("s3://ap-northeast-2/modal-media-cache/") {
        // 将 s3://ap-northeast-2/modal-media-cache/ 替换为 https://cdn.roasmax.cn/
        s3_url.replace(
            "s3://ap-northeast-2/modal-media-cache/",
            "https://cdn.roasmax.cn/",
        )
    } else if s3_url.starts_with("gs://fashion_image_block/") {
        // 将 gs://fashion_image_block/ 替换为 https://cdn.roasmax.cn/fashion_image_block/
        s3_url.replace("gs://", "https://storage.googleapis.com/")
    } else if s3_url.starts_with("gs://") {
        // 处理其他 gs:// 格式，转换为通用CDN格式
        s3_url.replace("gs://", "https://storage.googleapis.com/")
    } else if s3_url.starts_with("s3://") {
        // 处理其他 s3:// 格式，转换为通用CDN格式
        s3_url.replace("s3://", "https://cdn.roasmax.cn/")
    } else {
        // 如果不是预期的S3格式，返回原URL
        s3_url.to_string()
    }
}

/// 检查网络连接
async fn check_network_connectivity() -> Result<(), anyhow::Error> {
    let client = reqwest::Client::builder()
        .timeout(std::time::Duration::from_secs(10))
        .connect_timeout(std::time::Duration::from_secs(5))
        .build()?;

    // 尝试连接到Google DNS
    match client.get("https://dns.google").send().await {
        Ok(_) => Ok(()),
        Err(e) => Err(anyhow::anyhow!(
            "网络连接检查失败: {}。请检查您的网络连接。",
            e
        )),
    }
}

/// 执行 Vertex AI Search 搜索
pub async fn execute_vertex_ai_search(
    _gemini_service: &mut GeminiService,
    request: &SearchRequest,
) -> Result<SearchResponse, anyhow::Error> {
    // 0. 检查网络连接
    check_network_connectivity()
        .await
        .map_err(|e| anyhow::anyhow!("网络连接问题: {}", e))?;

    // 1. 获取访问令牌（通过直接调用API）
    let access_token = get_google_access_token()
        .await
        .map_err(|e| anyhow::anyhow!("获取访问令牌失败: {}。请检查网络连接或API配置。", e))?;

    // 2. 验证搜索配置
    if let Err(validation_error) = SearchFilterBuilder::validate_config(&request.config) {
        eprintln!("搜索配置验证失败: {}", validation_error);
        return Err(anyhow::anyhow!("搜索配置无效: {}", validation_error));
    }

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

    // 4. 记录搜索配置摘要
    if request.config.debug_mode {
        let config_summary = SearchFilterBuilder::generate_config_summary(&request.config);
        eprintln!("搜索配置摘要: {}", config_summary);
    }

    // 5. 构建简化的搜索过滤器 - 参考Python实现
    let search_filter = build_simple_filters(&request.config);

    // 6. 构建简化的查询字符串 - 参考 Python 实现
    let enhanced_query = build_simple_query(&request.query, &request.config);

    // 调试输出
    if request.config.debug_mode {
        eprintln!("原始查询: {}", request.query);
        eprintln!("增强查询: {}", enhanced_query);
        eprintln!("过滤器: {}", search_filter);
    }

    // 5. 构建请求负载
    let mut payload = serde_json::json!({
        "query": enhanced_query,
        "pageSize": request.page_size,
        "offset": request.page_offset
    });

    // 添加相关性阈值和评分规范（参考Python实现）
    // 暂时使用较低的阈值来获取更多结果
    let threshold_str = match request.config.relevance_threshold {
        crate::data::models::outfit_search::RelevanceThreshold::Lowest => "LOWEST",
        crate::data::models::outfit_search::RelevanceThreshold::Low => "LOWEST", // 降低阈值
        crate::data::models::outfit_search::RelevanceThreshold::Medium => "LOW", // 降低阈值
        crate::data::models::outfit_search::RelevanceThreshold::High => "MEDIUM", // 降低阈值
    };
    payload["relevanceThreshold"] = serde_json::Value::String(threshold_str.to_owned());
    payload["relevanceScoreSpec"] = serde_json::json!({
        "returnRelevanceScore": true
    });

    // 6. 添加过滤器（如果有）
    let mut all_filters = Vec::new();

    // 添加主要过滤器
    if !search_filter.is_empty() {
        all_filters.push(search_filter);
    }

    // 添加自定义过滤器
    if !request.config.custom_filters.is_empty() {
        all_filters.extend(request.config.custom_filters.clone());
    }

    // 组合所有过滤器
    if !all_filters.is_empty() {
        let combined_filter = all_filters.join(" AND ");

        if request.config.debug_mode {
            eprintln!("最终过滤器: {}", combined_filter);
        }

        payload["filter"] = serde_json::Value::String(combined_filter);
    }

    // 7. 构建请求URL - 使用正确的 dataStores 端点
    let search_url = format!(
        "https://discoveryengine.googleapis.com/v1beta/projects/{}/locations/global/collections/default_collection/dataStores/{}/servingConfigs/default_search:search",
        global_config.google_project_id,
        global_config.data_store_id
    );

    // 添加调试日志：打印完整的请求 payload
    if request.config.debug_mode {
        eprintln!("=== 发送到 Vertex AI Search 的完整请求 ===");
        eprintln!("URL: {}", search_url);
        eprintln!("Payload: {}", serde_json::to_string_pretty(&payload).unwrap_or_else(|_| "无法序列化请求".to_string()));
        eprintln!("=== 请求结束 ===");
    }

    // 8. 创建带有超时配置的客户端
    let client = reqwest::Client::builder()
        .timeout(std::time::Duration::from_secs(60))
        .connect_timeout(std::time::Duration::from_secs(15))
        .build()?;

    // 9. 发送HTTP请求（带重试机制）
    let mut last_error = None;
    for attempt in 0..3 {
        match client
            .post(&search_url)
            .header("Authorization", format!("Bearer {}", access_token))
            .header("Content-Type", "application/json")
            .json(&payload)
            .send()
            .await
        {
            Ok(response) => {
                let status = response.status();
                let response_text = response.text().await?;

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

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

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

                return Ok(search_results);
            }
            Err(e) => {
                let error_msg = format!("网络请求失败: {}", e);
                eprintln!("{}", error_msg);
                last_error = Some(anyhow::anyhow!(error_msg));

                if attempt < 2 {
                    eprintln!(
                        "Vertex AI Search 请求失败，重试中... (尝试 {}/3)",
                        attempt + 1
                    );
                    tokio::time::sleep(std::time::Duration::from_secs(3)).await;
                } else {
                    eprintln!("Vertex AI Search 请求最终失败，已重试3次");
                }
            }
        }
    }

    Err(anyhow::anyhow!(
        "Vertex AI Search 请求失败，已重试3次: {}",
        last_error.unwrap()
    ))
}

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

    // 创建带有超时和重试配置的客户端
    let client = reqwest::Client::builder()
        .timeout(std::time::Duration::from_secs(30))
        .connect_timeout(std::time::Duration::from_secs(10))
        .build()?;

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

    // 重试机制
    let mut last_error = None;
    for attempt in 0..3 {
        match client
            .get(&url)
            .header("Authorization", format!("Bearer {}", config.bearer_token))
            .send()
            .await
        {
            Ok(response) => {
                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 字段"))?;

                return Ok(access_token.to_string());
            }
            Err(e) => {
                let error_msg = format!("网络连接失败: {}", e);
                eprintln!("{}", error_msg);
                last_error = Some(anyhow::anyhow!(error_msg));

                if attempt < 2 {
                    eprintln!("获取访问令牌失败，重试中... (尝试 {}/3)", attempt + 1);
                    tokio::time::sleep(std::time::Duration::from_secs(2)).await;
                }
            }
        }
    }

    Err(anyhow::anyhow!(
        "获取访问令牌失败，已重试3次: {}",
        last_error.unwrap()
    ))
}

/// 将 Vertex AI Search 响应转换为我们的搜索结果格式
pub fn convert_vertex_response_to_search_results(
    vertex_response: &serde_json::Value,
    _request: &SearchRequest,
) -> Result<SearchResponse, anyhow::Error> {
    let mut results = Vec::new();

    // 添加调试日志：打印完整的 API 响应
    eprintln!("=== Vertex AI Search API 完整响应 ===");
    eprintln!("{}", serde_json::to_string_pretty(vertex_response).unwrap_or_else(|_| "无法序列化响应".to_string()));
    eprintln!("=== 响应结束 ===");

    // 解析 Vertex AI Search 响应
    if let Some(vertex_results) = vertex_response.get("results").and_then(|v| v.as_array()) {
        eprintln!("收到 {} 个原始搜索结果", vertex_results.len());

        for vertex_result in vertex_results {
            if let Ok(search_result) = parse_vertex_result_to_search_result(vertex_result) {
                eprintln!(
                    "解析结果: ID={}, 相关性评分={:.2}",
                    search_result.id, search_result.relevance_score
                );

                // 应用相关性阈值过滤（暂时跳过，直接添加结果）
                // let _threshold = request.config.relevance_threshold;
                results.push(search_result);
            } else {
                eprintln!("解析搜索结果失败");
            }
        }
    } else {
        eprintln!("响应中没有找到 results 数组");
        eprintln!("可能的原因：");
        eprintln!("1. 数据存储中没有匹配的数据");
        eprintln!("2. 过滤器条件过于严格");
        eprintln!("3. 相关性阈值过高");
        eprintln!("4. 查询词与数据不匹配");

        // 检查响应中的其他字段
        if let Some(summary) = vertex_response.get("summary") {
            eprintln!("API 返回的摘要信息：{}", serde_json::to_string_pretty(summary).unwrap_or_else(|_| "无法解析".to_string()));
        }

        if let Some(query_expansion) = vertex_response.get("queryExpansionInfo") {
            eprintln!("查询扩展信息：{}", serde_json::to_string_pretty(query_expansion).unwrap_or_else(|_| "无法解析".to_string()));
        }
    }

    eprintln!("最终返回 {} 个过滤后的结果", results.len());

    // 按相关性评分降序排序
    results.sort_by(|a, b| {
        b.relevance_score.partial_cmp(&a.relevance_score).unwrap_or(std::cmp::Ordering::Equal)
    });

    eprintln!("排序后的结果:");
    for (index, result) in results.iter().enumerate() {
        eprintln!("  {}. ID={}, 相关性评分={:.3}", index + 1, result.id, result.relevance_score);
    }

    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 raw_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("");

    // 转换S3/GS URL为CDN URL
    let image_url = convert_s3_to_cdn_url(raw_image_url);

    // 调试：显示URL转换
    if raw_image_url != image_url {
        eprintln!("URL转换: {} -> {}", raw_image_url, image_url);
    }

    // 获取相关性评分
    let relevance_score = vertex_result
        .get("modelScores")
        .and_then(|scores| scores.get("relevance_score"))
        .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.0);

    // 调试：打印相关性评分解析过程
    if let Some(model_scores) = vertex_result.get("modelScores") {
        eprintln!("ModelScores 结构: {}", serde_json::to_string_pretty(model_scores).unwrap_or_default());

        if let Some(relevance_data) = model_scores.get("relevance_score") {
            eprintln!("Relevance Score 数据: {}", serde_json::to_string_pretty(relevance_data).unwrap_or_default());
        } else {
            eprintln!("未找到 relevance_score 字段，可用字段: {:?}", model_scores.as_object().map(|obj| obj.keys().collect::<Vec<_>>()));
        }
    } else {
        eprintln!("未找到 modelScores 字段");
    }

    eprintln!("解析得到的相关性评分: {:.3}", relevance_score);

    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 = if let Some(desc) = value.get("description").and_then(|v| v.as_str()) {
        desc.to_string()
    } else if let Some(styles_array) = value.get("design_styles").and_then(|v| v.as_array()) {
        if !styles_array.is_empty() {
            let styles: Vec<String> = styles_array.iter()
                .filter_map(|v| v.as_str())
                .map(|s| s.to_string())
                .collect();
            if !styles.is_empty() {
                styles.join("、")
            } else {
                "时尚单品".to_string()
            }
        } else {
            "时尚单品".to_string()
        }
    } else {
        "时尚单品".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",
    ]
}

/// 将抽象类别映射到具体的服装类型
fn map_abstract_to_concrete_categories(abstract_category: &str) -> Vec<&str> {
    match abstract_category {
        "上装" => vec![
            "连衣裙", "吊带裙", "晚礼服", "迷你礼服", "连体衣",
            "开衫", "衬衫", "T恤", "背心", "外套", "夹克"
        ],
        "下装" => vec![
            "裤子", "牛仔裤", "短裤", "裙子", "半身裙", "网纱裙",
            "迷你裙", "长裙", "A字裙"
        ],
        "鞋子" => vec![
            "运动鞋", "高跟鞋", "平底鞋", "靴子", "凉鞋", "拖鞋"
        ],
        "配饰" => vec![
            "包包", "帽子", "项链", "耳环", "手表", "眼镜", "围巾"
        ],
        // 如果是具体类别，直接返回
        _ => vec![abstract_category]
    }
}

/// 构建简化的过滤器字符串 - 参考Python实现，支持类别映射
fn build_simple_filters(config: &crate::data::models::outfit_search::SearchConfig) -> String {
    let mut filters = Vec::new();

    // 优先使用类别过滤（最重要的过滤条件）
    if !config.categories.is_empty() {
        let mut all_concrete_categories = Vec::new();

        // 将抽象类别映射为具体类别
        for abstract_cat in &config.categories {
            let concrete_cats = map_abstract_to_concrete_categories(abstract_cat);
            all_concrete_categories.extend(concrete_cats);
        }

        // 去重并构建过滤器
        all_concrete_categories.sort();
        all_concrete_categories.dedup();

        let cat_filter = all_concrete_categories.iter()
            .map(|cat| format!("\"{}\"", cat))
            .collect::<Vec<_>>()
            .join(",");
        filters.push(format!("products.category: ANY({})", cat_filter));
    }

    // 如果没有类别过滤，尝试环境标签
    if filters.is_empty() && !config.environments.is_empty() {
        let env_filter = config.environments.iter()
            .map(|env| format!("\"{}\"", env))
            .collect::<Vec<_>>()
            .join(",");
        filters.push(format!("environment_tags: ANY({})", env_filter));
    }

    filters.join(" AND ")
}

/// 丰富的图像分析结果展示
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct EnrichedAnalysisResult {
    /// 原始分析结果
    pub original_result: crate::data::models::gemini_analysis::OutfitAnalysisResult,
    /// 分析时间信息
    pub analysis_time_ms: u64,
    /// 分析时间戳
    pub analyzed_at: chrono::DateTime<chrono::Utc>,
    /// 丰富的颜色信息
    pub color_analysis: ColorAnalysisDetails,
    /// 风格分析详情
    pub style_analysis: StyleAnalysisDetails,
    /// 产品分析详情
    pub product_analysis: ProductAnalysisDetails,
    /// 环境分析详情
    pub environment_analysis: EnvironmentAnalysisDetails,
    /// 搭配建议
    pub styling_suggestions: StylingSuggestions,
    /// 统计信息
    pub statistics: AnalysisStatistics,
}

/// 颜色分析详情
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ColorAnalysisDetails {
    /// 整体色调描述
    pub overall_color_description: String,
    /// 主色调十六进制值
    pub dress_color_hex: String,
    /// 环境色调十六进制值
    pub environment_color_hex: String,
    /// 色彩和谐度分析
    pub color_harmony: ColorHarmonyAnalysis,
    /// 色彩温度分析
    pub color_temperature: ColorTemperatureAnalysis,
    /// 色彩对比度
    pub color_contrast: f64,
}

/// 色彩和谐度分析
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ColorHarmonyAnalysis {
    /// 和谐度评分 (0-1)
    pub harmony_score: f64,
    /// 和谐类型
    pub harmony_type: String,
    /// 和谐度描述
    pub harmony_description: String,
}

/// 色彩温度分析
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ColorTemperatureAnalysis {
    /// 整体温度类型
    pub overall_temperature: String,
    /// 服装温度
    pub dress_temperature: String,
    /// 环境温度
    pub environment_temperature: String,
    /// 温度匹配度
    pub temperature_match: f64,
}

/// 风格分析详情
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct StyleAnalysisDetails {
    /// 主要风格标签
    pub primary_styles: Vec<String>,
    /// 次要风格标签
    pub secondary_styles: Vec<String>,
    /// 风格一致性评分
    pub style_consistency: f64,
    /// 风格复杂度
    pub style_complexity: String,
    /// 风格适合场合
    pub suitable_occasions: Vec<String>,
    /// 风格季节适配
    pub seasonal_suitability: Vec<String>,
}

/// 产品分析详情
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ProductAnalysisDetails {
    /// 产品数量统计
    pub product_count_by_category: std::collections::HashMap<String, u32>,
    /// 最佳匹配产品
    pub best_matched_product: Option<String>,
    /// 颜色匹配度统计
    pub color_match_statistics: ColorMatchStatistics,
    /// 风格多样性评分
    pub style_diversity: f64,
    /// 搭配完整度
    pub outfit_completeness: f64,
}

/// 颜色匹配度统计
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct ColorMatchStatistics {
    /// 平均服装匹配度
    pub avg_dress_match: f64,
    /// 平均环境匹配度
    pub avg_environment_match: f64,
    /// 最高匹配度
    pub max_match: f64,
    /// 最低匹配度
    pub min_match: f64,
}

/// 环境分析详情
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct EnvironmentAnalysisDetails {
    /// 环境类型
    pub environment_type: String,
    /// 光照条件
    pub lighting_condition: String,
    /// 背景复杂度
    pub background_complexity: String,
    /// 环境适配度
    pub environment_suitability: f64,
    /// 拍摄质量评估
    pub photo_quality_assessment: PhotoQualityAssessment,
}

/// 拍摄质量评估
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct PhotoQualityAssessment {
    /// 整体质量评分
    pub overall_quality: f64,
    /// 清晰度
    pub clarity: String,
    /// 构图质量
    pub composition: String,
    /// 光线质量
    pub lighting_quality: String,
}

/// 搭配建议
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct StylingSuggestions {
    /// 改进建议
    pub improvement_suggestions: Vec<String>,
    /// 替代搭配建议
    pub alternative_suggestions: Vec<String>,
    /// 配饰建议
    pub accessory_suggestions: Vec<String>,
    /// 场合适配建议
    pub occasion_suggestions: Vec<String>,
}

/// 分析统计信息
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct AnalysisStatistics {
    /// 总产品数量
    pub total_products: u32,
    /// 识别的风格数量
    pub total_styles: u32,
    /// 环境标签数量
    pub total_environment_tags: u32,
    /// 平均描述长度
    pub avg_description_length: f64,
    /// 分析复杂度评分
    pub analysis_complexity: f64,
}

/// 丰富图像分析结果
#[tauri::command]
pub async fn enrich_analysis_result(
    _state: State<'_, AppState>,
    analysis_result: crate::data::models::gemini_analysis::OutfitAnalysisResult,
    analysis_time_ms: u64,
) -> Result<EnrichedAnalysisResult, String> {
    // 生成丰富的分析结果
    let enriched = EnrichedAnalysisResult {
        color_analysis: generate_color_analysis(&analysis_result),
        style_analysis: generate_style_analysis(&analysis_result),
        product_analysis: generate_product_analysis(&analysis_result),
        environment_analysis: generate_environment_analysis(&analysis_result),
        styling_suggestions: generate_styling_suggestions(&analysis_result),
        statistics: generate_analysis_statistics(&analysis_result),
        analysis_time_ms,
        analyzed_at: chrono::Utc::now(),
        original_result: analysis_result,
    };

    Ok(enriched)
}

/// 生成颜色分析详情
fn generate_color_analysis(result: &crate::data::models::gemini_analysis::OutfitAnalysisResult) -> ColorAnalysisDetails {
    // 转换HSV到十六进制
    let dress_hex = hsv_to_hex(&result.dress_color_pattern);
    let env_hex = hsv_to_hex(&result.environment_color_pattern);

    // 计算色彩和谐度
    let harmony = calculate_color_harmony(&result.dress_color_pattern, &result.environment_color_pattern);

    // 分析色彩温度
    let temperature = analyze_color_temperature(&result.dress_color_pattern, &result.environment_color_pattern);

    // 计算对比度
    let contrast = calculate_color_contrast(&result.dress_color_pattern, &result.environment_color_pattern);

    ColorAnalysisDetails {
        overall_color_description: generate_color_description(&result.dress_color_pattern, &result.environment_color_pattern),
        dress_color_hex: dress_hex,
        environment_color_hex: env_hex,
        color_harmony: harmony,
        color_temperature: temperature,
        color_contrast: contrast,
    }
}

/// 生成风格分析详情
fn generate_style_analysis(result: &crate::data::models::gemini_analysis::OutfitAnalysisResult) -> StyleAnalysisDetails {
    // 收集所有风格标签
    let all_styles: Vec<String> = result.products.iter()
        .flat_map(|p| p.design_styles.iter())
        .cloned()
        .collect();

    // 统计风格频率
    let mut style_counts = std::collections::HashMap::new();
    for style in &all_styles {
        *style_counts.entry(style.clone()).or_insert(0) += 1;
    }

    // 分离主要和次要风格
    let mut sorted_styles: Vec<_> = style_counts.into_iter().collect();
    sorted_styles.sort_by(|a, b| b.1.cmp(&a.1));

    let primary_styles: Vec<String> = sorted_styles.iter()
        .take(3)
        .map(|(style, _)| style.clone())
        .collect();

    let secondary_styles: Vec<String> = sorted_styles.iter()
        .skip(3)
        .take(5)
        .map(|(style, _)| style.clone())
        .collect();

    StyleAnalysisDetails {
        primary_styles,
        secondary_styles,
        style_consistency: calculate_style_consistency(&all_styles),
        style_complexity: determine_style_complexity(&all_styles),
        suitable_occasions: generate_suitable_occasions(&all_styles),
        seasonal_suitability: generate_seasonal_suitability(&all_styles),
    }
}

/// 生成产品分析详情
fn generate_product_analysis(result: &crate::data::models::gemini_analysis::OutfitAnalysisResult) -> ProductAnalysisDetails {
    // 统计产品类别
    let mut category_counts = std::collections::HashMap::new();
    for product in &result.products {
        *category_counts.entry(product.category.clone()).or_insert(0) += 1;
    }

    // 计算颜色匹配度统计
    let dress_matches: Vec<f64> = result.products.iter()
        .map(|p| p.color_pattern_match_dress)
        .collect();

    let env_matches: Vec<f64> = result.products.iter()
        .map(|p| p.color_pattern_match_environment)
        .collect();

    let all_matches: Vec<f64> = dress_matches.iter()
        .chain(env_matches.iter())
        .cloned()
        .collect();

    let color_stats = ColorMatchStatistics {
        avg_dress_match: dress_matches.iter().sum::<f64>() / dress_matches.len() as f64,
        avg_environment_match: env_matches.iter().sum::<f64>() / env_matches.len() as f64,
        max_match: all_matches.iter().cloned().fold(0.0, f64::max),
        min_match: all_matches.iter().cloned().fold(1.0, f64::min),
    };

    // 找到最佳匹配产品
    let best_product = result.products.iter()
        .max_by(|a, b| {
            let a_score = (a.color_pattern_match_dress + a.color_pattern_match_environment) / 2.0;
            let b_score = (b.color_pattern_match_dress + b.color_pattern_match_environment) / 2.0;
            a_score.partial_cmp(&b_score).unwrap_or(std::cmp::Ordering::Equal)
        })
        .map(|p| p.description.clone());

    ProductAnalysisDetails {
        product_count_by_category: category_counts,
        best_matched_product: best_product,
        color_match_statistics: color_stats,
        style_diversity: calculate_style_diversity(&result.products),
        outfit_completeness: calculate_outfit_completeness(&result.products),
    }
}

/// 生成环境分析详情
fn generate_environment_analysis(result: &crate::data::models::gemini_analysis::OutfitAnalysisResult) -> EnvironmentAnalysisDetails {
    let env_type = determine_environment_type(&result.environment_tags);
    let lighting = determine_lighting_condition(&result.environment_tags, &result.environment_color_pattern);
    let complexity = determine_background_complexity(&result.environment_tags);

    EnvironmentAnalysisDetails {
        environment_type: env_type,
        lighting_condition: lighting,
        background_complexity: complexity,
        environment_suitability: calculate_environment_suitability(&result.environment_tags, &result.products),
        photo_quality_assessment: assess_photo_quality(&result.environment_tags, &result.environment_color_pattern),
    }
}

/// 生成搭配建议
fn generate_styling_suggestions(result: &crate::data::models::gemini_analysis::OutfitAnalysisResult) -> StylingSuggestions {
    StylingSuggestions {
        improvement_suggestions: generate_improvement_suggestions(&result.products),
        alternative_suggestions: generate_alternative_suggestions(&result.products),
        accessory_suggestions: generate_accessory_suggestions(&result.products),
        occasion_suggestions: generate_occasion_suggestions(&result.products, &result.environment_tags),
    }
}

/// 生成分析统计信息
fn generate_analysis_statistics(result: &crate::data::models::gemini_analysis::OutfitAnalysisResult) -> AnalysisStatistics {
    let total_styles = result.products.iter()
        .flat_map(|p| p.design_styles.iter())
        .collect::<std::collections::HashSet<_>>()
        .len() as u32;

    let avg_desc_length = result.products.iter()
        .map(|p| p.description.len() as f64)
        .sum::<f64>() / result.products.len() as f64;

    AnalysisStatistics {
        total_products: result.products.len() as u32,
        total_styles,
        total_environment_tags: result.environment_tags.len() as u32,
        avg_description_length: avg_desc_length,
        analysis_complexity: calculate_analysis_complexity(result),
    }
}

// 辅助函数实现

/// HSV转十六进制
fn hsv_to_hex(color: &crate::data::models::gemini_analysis::ColorHSV) -> String {
    let (r, g, b) = hsv_to_rgb(color.hue, color.saturation, color.value);
    format!("#{:02X}{:02X}{:02X}",
        (r * 255.0) as u8,
        (g * 255.0) as u8,
        (b * 255.0) as u8
    )
}

/// HSV转RGB
fn hsv_to_rgb(h: f64, s: f64, v: f64) -> (f64, f64, f64) {
    let c = v * s;
    let x = c * (1.0 - ((h * 6.0) % 2.0 - 1.0).abs());
    let m = v - c;

    let (r_prime, g_prime, b_prime) = match (h * 6.0) as i32 {
        0 => (c, x, 0.0),
        1 => (x, c, 0.0),
        2 => (0.0, c, x),
        3 => (0.0, x, c),
        4 => (x, 0.0, c),
        5 => (c, 0.0, x),
        _ => (0.0, 0.0, 0.0),
    };

    (r_prime + m, g_prime + m, b_prime + m)
}

/// 计算色彩和谐度
fn calculate_color_harmony(dress: &crate::data::models::gemini_analysis::ColorHSV, env: &crate::data::models::gemini_analysis::ColorHSV) -> ColorHarmonyAnalysis {
    let hue_diff = (dress.hue - env.hue).abs();
    let hue_distance = hue_diff.min(1.0 - hue_diff);

    let harmony_score = 1.0 - hue_distance;
    let harmony_type = match hue_distance {
        d if d < 0.1 => "单色调和".to_string(),
        d if d < 0.25 => "邻近色调和".to_string(),
        d if d < 0.4 => "对比色调和".to_string(),
        _ => "互补色调和".to_string(),
    };

    let description = match harmony_score {
        s if s > 0.8 => "色彩搭配非常和谐，视觉效果优雅统一".to_string(),
        s if s > 0.6 => "色彩搭配较为和谐，整体协调".to_string(),
        s if s > 0.4 => "色彩搭配一般，有一定对比感".to_string(),
        _ => "色彩对比强烈，视觉冲击力强".to_string(),
    };

    ColorHarmonyAnalysis {
        harmony_score,
        harmony_type,
        harmony_description: description,
    }
}

/// 分析色彩温度
fn analyze_color_temperature(dress: &crate::data::models::gemini_analysis::ColorHSV, env: &crate::data::models::gemini_analysis::ColorHSV) -> ColorTemperatureAnalysis {
    let dress_temp = get_color_temperature(dress);
    let env_temp = get_color_temperature(env);

    let overall_temp = if dress_temp == env_temp {
        dress_temp.clone()
    } else {
        "混合温度".to_string()
    };

    let temp_match = if dress_temp == env_temp { 1.0 } else { 0.5 };

    ColorTemperatureAnalysis {
        overall_temperature: overall_temp,
        dress_temperature: dress_temp,
        environment_temperature: env_temp,
        temperature_match: temp_match,
    }
}

/// 获取颜色温度
fn get_color_temperature(color: &crate::data::models::gemini_analysis::ColorHSV) -> String {
    match color.hue {
        h if h >= 0.0 && h < 0.08 => "暖色调".to_string(),  // 红色
        h if h >= 0.08 && h < 0.17 => "暖色调".to_string(), // 橙色
        h if h >= 0.17 && h < 0.25 => "暖色调".to_string(), // 黄色
        h if h >= 0.25 && h < 0.42 => "冷色调".to_string(), // 绿色
        h if h >= 0.42 && h < 0.75 => "冷色调".to_string(), // 蓝色
        h if h >= 0.75 && h < 0.83 => "冷色调".to_string(), // 紫色
        _ => "中性色调".to_string(),
    }
}

/// 计算颜色对比度
fn calculate_color_contrast(dress: &crate::data::models::gemini_analysis::ColorHSV, env: &crate::data::models::gemini_analysis::ColorHSV) -> f64 {
    let value_diff = (dress.value - env.value).abs();
    let sat_diff = (dress.saturation - env.saturation).abs();
    let hue_diff = (dress.hue - env.hue).abs().min(1.0 - (dress.hue - env.hue).abs());

    (value_diff * 0.5 + sat_diff * 0.3 + hue_diff * 0.2).clamp(0.0, 1.0)
}

/// 生成颜色描述
fn generate_color_description(dress: &crate::data::models::gemini_analysis::ColorHSV, env: &crate::data::models::gemini_analysis::ColorHSV) -> String {
    let dress_desc = describe_color(dress);
    let env_desc = describe_color(env);

    format!("整体以{}为主色调，在{}环境中呈现出协调的视觉效果", dress_desc, env_desc)
}

/// 描述单个颜色
fn describe_color(color: &crate::data::models::gemini_analysis::ColorHSV) -> String {
    let hue_name = match color.hue {
        h if h >= 0.0 && h < 0.08 => "红色",
        h if h >= 0.08 && h < 0.17 => "橙色",
        h if h >= 0.17 && h < 0.25 => "黄色",
        h if h >= 0.25 && h < 0.42 => "绿色",
        h if h >= 0.42 && h < 0.58 => "青色",
        h if h >= 0.58 && h < 0.75 => "蓝色",
        h if h >= 0.75 && h < 0.83 => "紫色",
        h if h >= 0.83 && h < 0.92 => "品红",
        _ => "红色",
    };

    let saturation_desc = match color.saturation {
        s if s < 0.2 => "淡",
        s if s < 0.6 => "中等",
        _ => "鲜艳",
    };

    let value_desc = match color.value {
        v if v < 0.3 => "深",
        v if v < 0.7 => "中等",
        _ => "浅",
    };

    format!("{}{}{}", value_desc, saturation_desc, hue_name)
}

/// 计算风格一致性
fn calculate_style_consistency(styles: &[String]) -> f64 {
    if styles.is_empty() { return 0.0; }

    let mut style_counts = std::collections::HashMap::new();
    for style in styles {
        *style_counts.entry(style).or_insert(0) += 1;
    }

    let max_count = style_counts.values().max().unwrap_or(&0);
    *max_count as f64 / styles.len() as f64
}

/// 确定风格复杂度
fn determine_style_complexity(styles: &[String]) -> String {
    let unique_styles = styles.iter().collect::<std::collections::HashSet<_>>().len();

    match unique_styles {
        0..=2 => "简约".to_string(),
        3..=5 => "中等".to_string(),
        _ => "复杂".to_string(),
    }
}

/// 生成适合场合
fn generate_suitable_occasions(styles: &[String]) -> Vec<String> {
    let mut occasions = Vec::new();

    for style in styles {
        match style.as_str() {
            "休闲" | "街头" => occasions.push("日常出行".to_string()),
            "正式" | "商务" => occasions.push("商务会议".to_string()),
            "优雅" | "时尚" => occasions.push("社交聚会".to_string()),
            "运动" => occasions.push("健身运动".to_string()),
            "简约" | "极简" => occasions.push("工作日常".to_string()),
            _ => {}
        }
    }

    occasions.sort();
    occasions.dedup();
    occasions
}

/// 生成季节适配
fn generate_seasonal_suitability(styles: &[String]) -> Vec<String> {
    let mut seasons = Vec::new();

    for style in styles {
        match style.as_str() {
            "清爽" | "轻薄" => seasons.push("夏季".to_string()),
            "保暖" | "厚重" => seasons.push("冬季".to_string()),
            "层次" | "叠穿" => seasons.push("秋季".to_string()),
            "清新" | "明亮" => seasons.push("春季".to_string()),
            _ => {
                seasons.push("四季".to_string());
            }
        }
    }

    seasons.sort();
    seasons.dedup();
    seasons
}

/// 计算风格多样性
fn calculate_style_diversity(products: &[crate::data::models::gemini_analysis::ProductAnalysis]) -> f64 {
    let all_styles: Vec<&String> = products.iter()
        .flat_map(|p| p.design_styles.iter())
        .collect();

    let unique_styles = all_styles.iter().collect::<std::collections::HashSet<_>>().len();
    let total_styles = all_styles.len();

    if total_styles == 0 { 0.0 } else { unique_styles as f64 / total_styles as f64 }
}

/// 计算搭配完整度
fn calculate_outfit_completeness(products: &[crate::data::models::gemini_analysis::ProductAnalysis]) -> f64 {
    let categories: std::collections::HashSet<&String> = products.iter()
        .map(|p| &p.category)
        .collect();

    let essential_categories = ["上装", "下装"];
    let has_essentials = essential_categories.iter()
        .all(|cat| categories.iter().any(|c| c.contains(cat)));

    let base_score = if has_essentials { 0.7 } else { 0.3 };
    let bonus = (categories.len() as f64 - 2.0).max(0.0) * 0.1;

    (base_score + bonus).min(1.0)
}

// 简化的实现函数（可以根据需要扩展）

fn determine_environment_type(tags: &[String]) -> String {
    if tags.iter().any(|t| t.contains("Indoor") || t.contains("室内")) {
        "室内环境".to_string()
    } else if tags.iter().any(|t| t.contains("Outdoor") || t.contains("户外")) {
        "户外环境".to_string()
    } else {
        "未知环境".to_string()
    }
}

fn determine_lighting_condition(tags: &[String], _color: &crate::data::models::gemini_analysis::ColorHSV) -> String {
    if tags.iter().any(|t| t.contains("Studio") || t.contains("摄影棚")) {
        "专业照明".to_string()
    } else if tags.iter().any(|t| t.contains("Natural") || t.contains("自然")) {
        "自然光".to_string()
    } else {
        "人工照明".to_string()
    }
}

fn determine_background_complexity(tags: &[String]) -> String {
    if tags.iter().any(|t| t.contains("Minimalist") || t.contains("简约")) {
        "简洁背景".to_string()
    } else if tags.iter().any(|t| t.contains("Complex") || t.contains("复杂")) {
        "复杂背景".to_string()
    } else {
        "中等复杂度".to_string()
    }
}

fn calculate_environment_suitability(_tags: &[String], _products: &[crate::data::models::gemini_analysis::ProductAnalysis]) -> f64 {
    0.8 // 简化实现
}

fn assess_photo_quality(_tags: &[String], _color: &crate::data::models::gemini_analysis::ColorHSV) -> PhotoQualityAssessment {
    PhotoQualityAssessment {
        overall_quality: 0.85,
        clarity: "清晰".to_string(),
        composition: "良好".to_string(),
        lighting_quality: "优秀".to_string(),
    }
}

fn generate_improvement_suggestions(_products: &[crate::data::models::gemini_analysis::ProductAnalysis]) -> Vec<String> {
    vec![
        "可以考虑添加一些配饰来增加层次感".to_string(),
        "颜色搭配可以更加大胆一些".to_string(),
        "尝试不同的材质组合会更有趣".to_string(),
    ]
}

fn generate_alternative_suggestions(_products: &[crate::data::models::gemini_analysis::ProductAnalysis]) -> Vec<String> {
    vec![
        "可以尝试用亮色单品作为点缀".to_string(),
        "换一个不同风格的包包会有新的感觉".to_string(),
        "考虑季节性的搭配调整".to_string(),
    ]
}

fn generate_accessory_suggestions(_products: &[crate::data::models::gemini_analysis::ProductAnalysis]) -> Vec<String> {
    vec![
        "添加一条精致的项链".to_string(),
        "选择一款时尚的手表".to_string(),
        "考虑搭配一个小巧的包包".to_string(),
    ]
}

fn generate_occasion_suggestions(_products: &[crate::data::models::gemini_analysis::ProductAnalysis], _tags: &[String]) -> Vec<String> {
    vec![
        "适合日常通勤".to_string(),
        "可以用于休闲聚会".to_string(),
        "适合购物逛街".to_string(),
    ]
}

fn calculate_analysis_complexity(_result: &crate::data::models::gemini_analysis::OutfitAnalysisResult) -> f64 {
    0.75 // 简化实现
}

/// 构建简化的查询字符串 - 参考Python实现
fn build_simple_query(base_query: &str, config: &crate::data::models::outfit_search::SearchConfig) -> String {
    if !config.query_enhancement_enabled {
        return base_query.to_string();
    }

    let mut keywords = Vec::new();

    // 添加环境关键词
    keywords.extend(config.environments.clone());

    // 添加设计风格关键词
    for styles in config.design_styles.values() {
        keywords.extend(styles.clone());
    }

    // 限制关键词数量
    if keywords.len() > config.max_keywords {
        keywords.truncate(config.max_keywords);
    }

    if keywords.is_empty() {
        base_query.to_string()
    } else {
        let keywords_str = keywords.join(" ");
        if base_query.trim().is_empty() {
            format!("model {}", keywords_str)
        } else {
            format!("{} {}", base_query.trim(), keywords_str)
        }
    }
}
