import { invoke } from '@tauri-apps/api/core';
import {
  MaterialSearchRequest,
  MaterialSearchResponse,
  MaterialSearchResult,
  GenerateSearchQueryRequest,
  GenerateSearchQueryResponse,
  MaterialSearchConfig,
  OutfitRecommendation,
} from '../types/outfitRecommendation';

/**
 * 素材库检索API服务
 * 遵循 Tauri 开发规范的API服务设计原则
 */
export class MaterialSearchService {
  /**
   * 为穿搭方案生成智能检索条件
   */
  static async generateSearchQuery(
    recommendation: OutfitRecommendation,
    options?: {
      include_colors?: boolean;
      include_styles?: boolean;
      include_occasions?: boolean;
      include_seasons?: boolean;
    }
  ): Promise<GenerateSearchQueryResponse> {
    try {
      const request: GenerateSearchQueryRequest = {
        recommendation,
        options,
      };

      console.log('🔍 生成素材检索条件:', request);

      const response = await invoke<GenerateSearchQueryResponse>(
        'generate_material_search_query',
        { request }
      );

      console.log('✅ 检索条件生成成功:', response);
      return response;
    } catch (error) {
      console.error('❌ 检索条件生成失败:', error);
      throw new Error(`检索条件生成失败: ${error}`);
    }
  }

  /**
   * 执行素材库检索
   */
  static async searchMaterials(
    request: MaterialSearchRequest
  ): Promise<MaterialSearchResponse> {
    try {
      console.log('🔍 执行素材库检索:', request);

      const response = await invoke<MaterialSearchResponse>(
        'search_materials_for_outfit',
        { request }
      );

      console.log('✅ 素材检索成功:', response);
      return response;
    } catch (error) {
      console.error('❌ 素材检索失败:', error);
      throw new Error(`素材检索失败: ${error}`);
    }
  }

  /**
   * 快速素材检索（使用默认配置）
   */
  static async quickSearch(
    recommendationId: string,
    query: string,
    page: number = 1,
    pageSize: number = 9
  ): Promise<MaterialSearchResponse> {
    try {
      console.log('🔍 快速素材检索:', { recommendationId, query, page, pageSize });

      const response = await invoke<MaterialSearchResponse>(
        'quick_material_search',
        {
          recommendationId,
          query,
          page,
          pageSize,
        }
      );

      console.log('✅ 快速检索成功:', response);
      return response;
    } catch (error) {
      console.error('❌ 快速检索失败:', error);
      throw new Error(`快速检索失败: ${error}`);
    }
  }

  /**
   * 执行分页检索
   */
  static async searchWithPagination(
    request: MaterialSearchRequest,
    page: number,
    pageSize: number = 9
  ): Promise<MaterialSearchResponse> {
    try {
      const paginatedRequest: MaterialSearchRequest = {
        ...request,
        pagination: {
          page,
          page_size: pageSize,
        },
      };

      return await this.searchMaterials(paginatedRequest);
    } catch (error) {
      console.error('Failed to perform paginated material search:', error);
      throw new Error(`分页检索失败: ${error}`);
    }
  }

  /**
   * 为穿搭方案生成并执行检索
   */
  static async generateAndSearch(
    recommendation: OutfitRecommendation,
    page: number = 1,
    pageSize: number = 9,
    options?: {
      include_colors?: boolean;
      include_styles?: boolean;
      include_occasions?: boolean;
      include_seasons?: boolean;
    }
  ): Promise<{
    queryResponse: GenerateSearchQueryResponse;
    searchResponse: MaterialSearchResponse;
  }> {
    try {
      // 1. 生成检索条件
      const queryResponse = await this.generateSearchQuery(recommendation, options);

      // 2. 执行检索
      const searchRequest: MaterialSearchRequest = {
        query: queryResponse.query,
        recommendation_id: recommendation.id,
        search_config: queryResponse.search_config,
        pagination: {
          page,
          page_size: pageSize,
        },
      };

      const searchResponse = await this.searchMaterials(searchRequest);

      return {
        queryResponse,
        searchResponse,
      };
    } catch (error) {
      console.error('Failed to generate and search materials:', error);
      throw new Error(`生成并检索失败: ${error}`);
    }
  }

  /**
   * 获取检索统计信息
   */
  static getSearchStats(response: MaterialSearchResponse): {
    totalResults: number;
    searchTime: number;
    averageScore: number;
    topCategories: string[];
  } {
    const totalResults = response.total_size;
    const searchTime = response.search_time_ms;

    // 计算平均评分
    const averageScore = response.results.length > 0
      ? response.results.reduce((sum, result) => sum + result.relevance_score, 0) / response.results.length
      : 0;

    // 统计热门类别
    const categoryCount: Record<string, number> = {};
    response.results.forEach(result => {
      result.products.forEach(product => {
        categoryCount[product.category] = (categoryCount[product.category] || 0) + 1;
      });
    });

    const topCategories = Object.entries(categoryCount)
      .sort(([, a], [, b]) => b - a)
      .slice(0, 5)
      .map(([category]) => category);

    return {
      totalResults,
      searchTime,
      averageScore,
      topCategories,
    };
  }

  /**
   * 格式化搜索时间
   */
  static formatSearchTime(timeMs: number): string {
    if (timeMs < 1000) {
      return `${timeMs}ms`;
    } else if (timeMs < 60000) {
      return `${(timeMs / 1000).toFixed(1)}s`;
    } else {
      return `${Math.floor(timeMs / 60000)}m ${Math.floor((timeMs % 60000) / 1000)}s`;
    }
  }

  /**
   * 格式化相关性评分
   */
  static formatRelevanceScore(score: number): string {
    return `${(score * 100).toFixed(1)}%`;
  }

  /**
   * 检查是否有更多结果
   */
  static hasMoreResults(response: MaterialSearchResponse): boolean {
    return response.current_page < response.total_pages;
  }

  /**
   * 检查是否有上一页
   */
  static hasPreviousResults(response: MaterialSearchResponse): boolean {
    return response.current_page > 1;
  }

  /**
   * 计算总页数
   */
  static getTotalPages(totalSize: number, pageSize: number): number {
    return Math.ceil(totalSize / pageSize);
  }

  /**
   * 生成搜索摘要
   */
  static generateSearchSummary(response: MaterialSearchResponse, query: string): string {
    const { total_size, search_time_ms, results } = response;
    const timeStr = this.formatSearchTime(search_time_ms);

    if (total_size === 0) {
      return `未找到与"${query}"相关的素材`;
    }

    const avgScore = results.length > 0
      ? results.reduce((sum, r) => sum + r.relevance_score, 0) / results.length
      : 0;

    return `找到 ${total_size} 个相关素材，用时 ${timeStr}，平均相关度 ${this.formatRelevanceScore(avgScore)}`;
  }

  /**
   * 获取页面范围信息
   */
  static getPageRangeInfo(currentPage: number, pageSize: number, totalSize: number): {
    start: number;
    end: number;
    total: number;
  } {
    const start = (currentPage - 1) * pageSize + 1;
    const end = Math.min(currentPage * pageSize, totalSize);
    
    return {
      start,
      end,
      total: totalSize,
    };
  }

  /**
   * 创建默认搜索配置
   */
  static createDefaultSearchConfig(): MaterialSearchConfig {
    return {
      relevance_threshold: 'HIGH',
      categories: [],
      environments: [],
      color_filters: {},
      design_styles: {},
      max_results: 50,
    };
  }

  /**
   * 验证搜索请求
   */
  static validateSearchRequest(request: MaterialSearchRequest): string[] {
    const errors: string[] = [];

    if (!request.query || request.query.trim().length === 0) {
      errors.push('搜索查询不能为空');
    }

    if (!request.recommendation_id || request.recommendation_id.trim().length === 0) {
      errors.push('穿搭方案ID不能为空');
    }

    if (request.pagination.page < 1) {
      errors.push('页码必须大于0');
    }

    if (request.pagination.page_size < 1 || request.pagination.page_size > 100) {
      errors.push('每页大小必须在1-100之间');
    }

    return errors;
  }

  /**
   * 批量处理搜索结果
   */
  static async batchProcessResults(
    results: MaterialSearchResult[],
    processor: (result: MaterialSearchResult) => Promise<MaterialSearchResult>
  ): Promise<MaterialSearchResult[]> {
    try {
      const processedResults = await Promise.all(
        results.map(result => processor(result))
      );
      return processedResults;
    } catch (error) {
      console.error('Failed to batch process results:', error);
      throw new Error(`批量处理失败: ${error}`);
    }
  }
}

/**
 * 导出默认实例
 */
export default MaterialSearchService;
