/**
 * 歌曲音源配置管理器
 *
 * 职责：
 * 1. 统一管理每首歌曲的自定义音源配置
 * 2. 提供清晰的读取/写入/清除 API
 * 3. 区分"手动"和"自动"设置的音源
 * 4. 管理已尝试的音源列表（按歌曲隔离）
 */

import type { Platform } from '@/types/music';

// 歌曲音源配置类型
export type SongSourceConfig = {
  sources: Platform[];
  type: 'manual' | 'auto';
  updatedAt: number;
};

// 内存中缓存已尝试的音源（按歌曲隔离）
const triedSourcesMap = new Map<string, Set<string>>();
const triedSourceDiffsMap = new Map<string, Map<string, number>>();

// localStorage key 前缀
const STORAGE_KEY_PREFIX = 'song_source_';
const STORAGE_TYPE_KEY_PREFIX = 'song_source_type_';

/**
 * 歌曲音源配置管理器
 */
export class SongSourceConfigManager {
  /**
   * 获取歌曲的自定义音源配置
   */
  static getConfig(songId: number | string): SongSourceConfig | null {
    const id = String(songId);
    const sourcesStr = localStorage.getItem(`${STORAGE_KEY_PREFIX}${id}`);
    const typeStr = localStorage.getItem(`${STORAGE_TYPE_KEY_PREFIX}${id}`);

    if (!sourcesStr) {
      return null;
    }

    try {
      const sources = JSON.parse(sourcesStr) as Platform[];
      if (!Array.isArray(sources) || sources.length === 0) {
        return null;
      }

      return {
        sources,
        type: typeStr === 'auto' ? 'auto' : 'manual',
        updatedAt: Date.now()
      };
    } catch (error) {
      console.error(`[SongSourceConfigManager] 解析歌曲 ${id} 配置失败:`, error);
      return null;
    }
  }

  /**
   * 设置歌曲的自定义音源配置
   */
  static setConfig(
    songId: number | string,
    sources: Platform[],
    type: 'manual' | 'auto' = 'manual'
  ): void {
    const id = String(songId);

    if (!sources || sources.length === 0) {
      this.clearConfig(songId);
      return;
    }

    try {
      localStorage.setItem(`${STORAGE_KEY_PREFIX}${id}`, JSON.stringify(sources));
      localStorage.setItem(`${STORAGE_TYPE_KEY_PREFIX}${id}`, type);
      console.log(`[SongSourceConfigManager] 设置歌曲 ${id} 音源: ${sources.join(', ')} (${type})`);
    } catch (error) {
      console.error(`[SongSourceConfigManager] 保存歌曲 ${id} 配置失败:`, error);
    }
  }

  /**
   * 清除歌曲的自定义配置
   */
  static clearConfig(songId: number | string): void {
    const id = String(songId);
    localStorage.removeItem(`${STORAGE_KEY_PREFIX}${id}`);
    localStorage.removeItem(`${STORAGE_TYPE_KEY_PREFIX}${id}`);
    // 同时清除内存中的已尝试音源
    this.clearTriedSources(songId);
    console.log(`[SongSourceConfigManager] 清除歌曲 ${id} 配置`);
  }

  /**
   * 检查歌曲是否有自定义配置
   */
  static hasConfig(songId: number | string): boolean {
    return this.getConfig(songId) !== null;
  }

  /**
   * 检查配置类型是否为手动设置
   */
  static isManualConfig(songId: number | string): boolean {
    const config = this.getConfig(songId);
    return config?.type === 'manual';
  }

  // ==================== 已尝试音源管理 ====================

  /**
   * 获取歌曲已尝试的音源列表
   */
  static getTriedSources(songId: number | string): Set<string> {
    const id = String(songId);
    if (!triedSourcesMap.has(id)) {
      triedSourcesMap.set(id, new Set());
    }
    return triedSourcesMap.get(id)!;
  }

  /**
   * 添加已尝试的音源
   */
  static addTriedSource(songId: number | string, source: string): void {
    const id = String(songId);
    const tried = this.getTriedSources(id);
    tried.add(source);
    console.log(`[SongSourceConfigManager] 歌曲 ${id} 添加已尝试音源: ${source}`);
  }

  /**
   * 清除歌曲的已尝试音源
   */
  static clearTriedSources(songId: number | string): void {
    const id = String(songId);
    triedSourcesMap.delete(id);
    triedSourceDiffsMap.delete(id);
    console.log(`[SongSourceConfigManager] 清除歌曲 ${id} 已尝试音源`);
  }

  /**
   * 获取歌曲已尝试音源的时长差异
   */
  static getTriedSourceDiffs(songId: number | string): Map<string, number> {
    const id = String(songId);
    if (!triedSourceDiffsMap.has(id)) {
      triedSourceDiffsMap.set(id, new Map());
    }
    return triedSourceDiffsMap.get(id)!;
  }

  /**
   * 设置音源的时长差异
   */
  static setTriedSourceDiff(songId: number | string, source: string, diff: number): void {
    const id = String(songId);
    const diffs = this.getTriedSourceDiffs(id);
    diffs.set(source, diff);
  }

  /**
   * 查找最佳匹配的音源（时长差异最小）
   */
  static findBestMatchingSource(songId: number | string): { source: string; diff: number } | null {
    const diffs = this.getTriedSourceDiffs(songId);
    if (diffs.size === 0) {
      return null;
    }

    let bestSource = '';
    let minDiff = Infinity;

    for (const [source, diff] of diffs.entries()) {
      if (diff < minDiff) {
        minDiff = diff;
        bestSource = source;
      }
    }

    return bestSource ? { source: bestSource, diff: minDiff } : null;
  }

  /**
   * 清理所有内存缓存（用于测试或重置）
   */
  static clearAllMemoryCache(): void {
    triedSourcesMap.clear();
    triedSourceDiffsMap.clear();
    console.log('[SongSourceConfigManager] 清除所有内存缓存');
  }
}

// 导出单例实例方便使用
export const songSourceConfig = SongSourceConfigManager;
