/**
 * 一键匹配服务
 * 遵循前端开发规范的服务层设计原则
 */

import { invoke } from '@tauri-apps/api/core';
import { listen, UnlistenFn } from '@tauri-apps/api/event';
import {
  BatchMatchingRequest,
  BatchMatchingResult,
  BatchMatchingProgress,
  BatchMatchingProgressStatus,
} from '../types/batchMatching';

export class BatchMatchingService {
  // 进度回调函数类型
  static progressCallback: ((progress: BatchMatchingProgress) => void) | null = null;
  // 事件监听器
  static progressEventUnlisten: UnlistenFn | null = null;

  /**
   * 设置进度回调函数
   */
  static async setProgressCallback(callback: (progress: BatchMatchingProgress) => void) {
    this.progressCallback = callback;

    // 设置事件监听器
    try {
      this.progressEventUnlisten = await listen('batch_matching_progress', (event: any) => {
        const progressData = event.payload;
        if (this.progressCallback) {
          this.progressCallback({
            status: BatchMatchingProgressStatus.InProgress,
            current_binding_index: progressData.current_binding_index,
            total_bindings: progressData.total_bindings,
            current_template_name: progressData.current_template_name,
            completed_bindings: progressData.completed_bindings,
            failed_bindings: progressData.failed_bindings,
            elapsed_time_ms: progressData.elapsed_time_ms,
          });
        }
      });
    } catch (error) {
      console.error('设置批量匹配进度事件监听器失败:', error);
    }
  }

  /**
   * 清除进度回调函数
   */
  static clearProgressCallback() {
    this.progressCallback = null;

    // 清除事件监听器
    if (this.progressEventUnlisten) {
      this.progressEventUnlisten();
      this.progressEventUnlisten = null;
    }
  }

  /**
   * 执行一键匹配
   * 遍历项目的所有活跃模板绑定并逐一执行匹配
   */
  static async executeBatchMatching(request: BatchMatchingRequest): Promise<BatchMatchingResult> {
    const startTime = Date.now();

    try {
      console.log('BatchMatchingService: 开始执行一键匹配', request);

      // 初始化进度
      if (this.progressCallback) {
        this.progressCallback({
          status: BatchMatchingProgressStatus.InProgress,
          current_binding_index: 0,
          total_bindings: 0, // 将在后端返回实际数量
          completed_bindings: 0,
          failed_bindings: 0,
          elapsed_time_ms: 0,
        });
      }

      const result = await invoke<BatchMatchingResult>('batch_match_all_templates', {
        request,
      });

      // 完成进度
      if (this.progressCallback) {
        this.progressCallback({
          status: BatchMatchingProgressStatus.Completed,
          current_binding_index: result.total_bindings,
          total_bindings: result.total_bindings,
          completed_bindings: result.successful_matches,
          failed_bindings: result.failed_matches,
          elapsed_time_ms: Date.now() - startTime,
        });
      }

      console.log('BatchMatchingService: 一键匹配完成', result);
      return result;
    } catch (error) {
      // 失败进度
      if (this.progressCallback) {
        this.progressCallback({
          status: BatchMatchingProgressStatus.Failed,
          current_binding_index: 0,
          total_bindings: 0,
          completed_bindings: 0,
          failed_bindings: 0,
          elapsed_time_ms: Date.now() - startTime,
        });
      }

      console.error('BatchMatchingService: 一键匹配失败', error);
      throw new Error(`一键匹配失败: ${error}`);
    }
  }

  /**
   * 验证项目是否可以执行一键匹配
   */
  static async validateProjectForBatchMatching(_projectId: string): Promise<{
    canMatch: boolean;
    activeBindingsCount: number;
    issues: string[];
  }> {
    try {
      // 这里可以添加预检查逻辑，比如检查活跃绑定数量、素材数量等
      // 目前简化实现，直接返回可以匹配
      return {
        canMatch: true,
        activeBindingsCount: 0, // 实际应该从后端获取
        issues: [],
      };
    } catch (error) {
      console.error('BatchMatchingService: 验证项目匹配条件失败', error);
      return {
        canMatch: false,
        activeBindingsCount: 0,
        issues: [`验证失败: ${error}`],
      };
    }
  }

  /**
   * 格式化匹配结果摘要
   */
  static formatResultSummary(result: BatchMatchingResult): string {
    const {
      total_bindings,
      successful_matches,
      failed_matches,
      skipped_bindings,
      summary,
      total_rounds,
      successful_rounds,
      termination_reason,
      materials_exhausted,
    } = result;

    const successRate = total_bindings > 0
      ? Math.round((successful_matches / total_bindings) * 100)
      : 0;

    return `循环匹配完成！总计 ${total_rounds} 轮匹配，成功轮数 ${successful_rounds} 轮` +
           `\n模板绑定: 总计 ${total_bindings} 个，成功 ${successful_matches} 个，失败 ${failed_matches} 个，跳过 ${skipped_bindings} 个` +
           `\n成功率: ${successRate}%` +
           `\n匹配片段: ${summary.total_segments_matched} 个` +
           `\n使用素材: ${summary.total_materials_used} 个` +
           `\n使用模特: ${summary.total_models_used} 个` +
           `\n终止原因: ${termination_reason}` +
           (materials_exhausted ? '\n状态: 素材已耗尽' : '') +
           (summary.best_matching_template ? `\n最佳匹配模板: ${summary.best_matching_template}` : '') +
           (summary.worst_matching_template ? `\n最差匹配模板: ${summary.worst_matching_template}` : '');
  }

  /**
   * 检查匹配结果是否成功
   */
  static isMatchingSuccessful(result: BatchMatchingResult): boolean {
    return result.successful_matches > 0 && result.failed_matches === 0;
  }

  /**
   * 检查匹配结果是否部分成功
   */
  static isMatchingPartiallySuccessful(result: BatchMatchingResult): boolean {
    return result.successful_matches > 0 && result.failed_matches > 0;
  }

  /**
   * 获取匹配结果的整体状态
   */
  static getOverallStatus(result: BatchMatchingResult): 'success' | 'partial' | 'failed' {
    if (this.isMatchingSuccessful(result)) {
      return 'success';
    } else if (this.isMatchingPartiallySuccessful(result)) {
      return 'partial';
    } else {
      return 'failed';
    }
  }

  /**
   * 生成匹配结果报告
   */
  static generateReport(result: BatchMatchingResult): {
    title: string;
    summary: string;
    details: Array<{
      templateName: string;
      status: string;
      duration: string;
      error?: string;
    }>;
  } {
    const overallStatus = this.getOverallStatus(result);
    const title = overallStatus === 'success' 
      ? '一键匹配成功完成' 
      : overallStatus === 'partial' 
        ? '一键匹配部分成功' 
        : '一键匹配失败';

    const summary = this.formatResultSummary(result);

    const details = result.matching_results.map(item => ({
      templateName: item.template_name,
      status: item.status,
      duration: this.formatDuration(item.duration_ms),
      error: item.error_message,
      roundNumber: item.round_number,
      attemptsCount: item.attempts_count,
      failureReason: item.failure_reason,
    }));

    return {
      title,
      summary,
      details,
    };
  }

  /**
   * 格式化时长显示
   */
  private static formatDuration(durationMs: number): string {
    if (durationMs < 1000) {
      return `${durationMs}ms`;
    } else if (durationMs < 60000) {
      return `${(durationMs / 1000).toFixed(1)}s`;
    } else {
      const minutes = Math.floor(durationMs / 60000);
      const seconds = Math.floor((durationMs % 60000) / 1000);
      return `${minutes}m ${seconds}s`;
    }
  }
}
