use tauri::{command, State};
use crate::data::models::outfit_favorite::{
    SaveOutfitToFavoritesRequest, SaveOutfitToFavoritesResponse,
    GetFavoriteOutfitsResponse, SearchMaterialsByFavoriteRequest,
    CompareOutfitFavoritesRequest, CompareOutfitFavoritesResponse,
};
use crate::data::models::material_search::{MaterialSearchRequest, MaterialSearchPagination};
use crate::data::repositories::outfit_favorite_repository::OutfitFavoriteRepository;
use crate::app_state::AppState;
use crate::services::material_search_service::MaterialSearchService;

/// 保存方案到收藏
#[command]
pub async fn save_outfit_to_favorites(
    state: State<'_, AppState>,
    request: SaveOutfitToFavoritesRequest,
) -> Result<SaveOutfitToFavoritesResponse, String> {
    println!("💖 保存方案到收藏: {}", request.recommendation.title);

    let database = {
        let database_guard = state.database.lock().unwrap();
        database_guard.as_ref().ok_or("Database not initialized")?.clone()
    };

    let repository = OutfitFavoriteRepository::new(database);

    let favorite = repository
        .save_to_favorites(request.recommendation, request.custom_name)
        .await
        .map_err(|e| {
            eprintln!("保存收藏失败: {}", e);
            format!("保存收藏失败: {}", e)
        })?;

    println!("✅ 方案收藏成功，ID: {}", favorite.id);

    Ok(SaveOutfitToFavoritesResponse {
        favorite_id: favorite.id.clone(),
        favorite,
    })
}

/// 获取所有收藏的方案
#[command]
pub async fn get_favorite_outfits(
    state: State<'_, AppState>,
) -> Result<GetFavoriteOutfitsResponse, String> {
    println!("📋 获取收藏方案列表");

    let database = {
        let database_guard = state.database.lock().unwrap();
        database_guard.as_ref().ok_or("Database not initialized")?.clone()
    };

    let repository = OutfitFavoriteRepository::new(database);

    let favorites = repository
        .get_all_favorites()
        .await
        .map_err(|e| {
            eprintln!("获取收藏列表失败: {}", e);
            format!("获取收藏列表失败: {}", e)
        })?;

    println!("✅ 获取到 {} 个收藏方案", favorites.len());

    Ok(GetFavoriteOutfitsResponse {
        total_count: favorites.len(),
        favorites,
    })
}

/// 从收藏中移除方案
#[command]
pub async fn remove_from_favorites(
    state: State<'_, AppState>,
    favorite_id: String,
) -> Result<bool, String> {
    println!("🗑️ 从收藏中移除方案: {}", favorite_id);

    let database = {
        let database_guard = state.database.lock().unwrap();
        database_guard.as_ref().ok_or("Database not initialized")?.clone()
    };

    let repository = OutfitFavoriteRepository::new(database);

    let removed = repository
        .remove_from_favorites(&favorite_id)
        .await
        .map_err(|e| {
            eprintln!("移除收藏失败: {}", e);
            format!("移除收藏失败: {}", e)
        })?;

    if removed {
        println!("✅ 收藏移除成功");
    } else {
        println!("⚠️ 未找到要移除的收藏");
    }

    Ok(removed)
}

/// 基于收藏方案检索素材
#[command]
pub async fn search_materials_by_favorite(
    state: State<'_, AppState>,
    request: SearchMaterialsByFavoriteRequest,
) -> Result<crate::data::models::material_search::MaterialSearchResponse, String> {
    println!("🔍 基于收藏方案检索素材: {}", request.favorite_id);

    let database = {
        let database_guard = state.database.lock().unwrap();
        database_guard.as_ref().ok_or("Database not initialized")?.clone()
    };

    let repository = OutfitFavoriteRepository::new(database);

    // 获取收藏方案
    let favorite = repository
        .get_favorite_by_id(&request.favorite_id)
        .await
        .map_err(|e| {
            eprintln!("获取收藏方案失败: {}", e);
            format!("获取收藏方案失败: {}", e)
        })?
        .ok_or_else(|| format!("收藏方案不存在: {}", request.favorite_id))?;

    // 使用现有的素材检索服务
    let search_service = MaterialSearchService::new();
    
    // 生成检索条件
    let query_response = search_service
        .generate_search_query(&favorite.recommendation_data, None)
        .await
        .map_err(|e| {
            eprintln!("生成检索条件失败: {}", e);
            format!("生成检索条件失败: {}", e)
        })?;

    // 执行检索
    let search_request = MaterialSearchRequest {
        query: query_response.query,
        recommendation_id: favorite.recommendation_data.id,
        search_config: query_response.search_config,
        pagination: MaterialSearchPagination {
            page: request.page.unwrap_or(1),
            page_size: request.page_size.unwrap_or(9),
        },
    };

    let search_response = search_service
        .search_materials(&search_request)
        .await
        .map_err(|e| {
            eprintln!("素材检索失败: {}", e);
            format!("素材检索失败: {}", e)
        })?;

    println!("✅ 检索完成，找到 {} 个结果", search_response.results.len());

    Ok(search_response)
}

/// 对比两个收藏方案的素材检索结果
#[command]
pub async fn compare_outfit_favorites(
    state: State<'_, AppState>,
    request: CompareOutfitFavoritesRequest,
) -> Result<CompareOutfitFavoritesResponse, String> {
    println!("🔄 对比收藏方案: {} vs {}", request.favorite_id_1, request.favorite_id_2);

    let database = {
        let database_guard = state.database.lock().unwrap();
        database_guard.as_ref().ok_or("Database not initialized")?.clone()
    };

    let repository = OutfitFavoriteRepository::new(database);

    // 获取两个收藏方案
    let favorite_1 = repository
        .get_favorite_by_id(&request.favorite_id_1)
        .await
        .map_err(|e| format!("获取第一个收藏方案失败: {}", e))?
        .ok_or_else(|| format!("第一个收藏方案不存在: {}", request.favorite_id_1))?;

    let favorite_2 = repository
        .get_favorite_by_id(&request.favorite_id_2)
        .await
        .map_err(|e| format!("获取第二个收藏方案失败: {}", e))?
        .ok_or_else(|| format!("第二个收藏方案不存在: {}", request.favorite_id_2))?;

    // 并行执行两个方案的素材检索
    let search_service = MaterialSearchService::new();
    
    // 为两个方案生成检索条件和执行检索
    let (materials_1, materials_2) = tokio::try_join!(
        async {
            let query_response = search_service
                .generate_search_query(&favorite_1.recommendation_data, None)
                .await?;
            
            let search_request = MaterialSearchRequest {
                query: query_response.query,
                recommendation_id: favorite_1.recommendation_data.id.clone(),
                search_config: query_response.search_config,
                pagination: MaterialSearchPagination {
                    page: request.page.unwrap_or(1),
                    page_size: request.page_size.unwrap_or(9),
                },
            };
            
            search_service.search_materials(&search_request).await
        },
        async {
            let query_response = search_service
                .generate_search_query(&favorite_2.recommendation_data, None)
                .await?;
            
            let search_request = MaterialSearchRequest {
                query: query_response.query,
                recommendation_id: favorite_2.recommendation_data.id.clone(),
                search_config: query_response.search_config,
                pagination: MaterialSearchPagination {
                    page: request.page.unwrap_or(1),
                    page_size: request.page_size.unwrap_or(9),
                },
            };
            
            search_service.search_materials(&search_request).await
        }
    ).map_err(|e: anyhow::Error| format!("对比检索失败: {}", e))?;

    println!("✅ 对比完成，方案1找到{}个结果，方案2找到{}个结果", 
             materials_1.results.len(), materials_2.results.len());

    Ok(CompareOutfitFavoritesResponse {
        favorite_1,
        materials_1,
        favorite_2,
        materials_2,
        compared_at: chrono::Utc::now(),
    })
}

/// 检查方案是否已收藏
#[command]
pub async fn is_outfit_favorited(
    state: State<'_, AppState>,
    recommendation_id: String,
) -> Result<bool, String> {
    let database = {
        let database_guard = state.database.lock().unwrap();
        database_guard.as_ref().ok_or("Database not initialized")?.clone()
    };

    let repository = OutfitFavoriteRepository::new(database);

    repository
        .is_recommendation_favorited(&recommendation_id)
        .await
        .map_err(|e| {
            eprintln!("检查收藏状态失败: {}", e);
            format!("检查收藏状态失败: {}", e)
        })
}
