/**
 * Voice Store - Zustand
 * ======================
 *
 * 管理 TTS 合成、本地音色库的全局状态。
 */

import { create } from 'zustand';
import type { VoiceInfo, VoiceMaterial } from '../api/modules/voice';
import * as voiceApi from '../api/modules/voice';

interface VoiceState {
  // 预设音色列表
  presetVoices: VoiceInfo[];

  // 加载状态
  isLoadingVoices: boolean;

  // 素材库（用户上传的克隆音色）
  voiceMaterials: VoiceMaterial[];
  isLoadingMaterials: boolean;
}

interface VoiceActions {
  // 音色操作
  loadPresetVoices: () => Promise<void>;

  // 素材库操作
  loadVoiceMaterials: () => Promise<void>;
  addVoiceMaterial: (_file: File, _name: string) => Promise<VoiceMaterial>;
  updateVoiceMaterialStatus: (_id: string, _status: VoiceMaterial['status'], _voiceId?: string, _trialUrl?: string) => void;
  renameVoiceMaterial: (_id: string, _name: string) => Promise<void>;
  deleteVoiceMaterial: (_materialId: string) => Promise<void>;

  // 重置
  reset: () => void;
}

const initialState: VoiceState = {
  presetVoices: [],
  isLoadingVoices: false,
  voiceMaterials: [],
  isLoadingMaterials: false,
};

export const useVoiceStore = create<VoiceState & VoiceActions>()(
  (set) => ({
    ...initialState,

    // ====================== 音色操作 ======================

    loadPresetVoices: async () => {
      set({ isLoadingVoices: true });
      try {
        const voices = await voiceApi.getVoiceList();
        set({ presetVoices: voices });
      } catch (err) {
        console.error('[VoiceStore] 加载音色列表失败:', err);
        // 静默失败，使用预设音色
        set({
          presetVoices: [
            {
              voiceId: 'tianxin_xiaoling',
              name: '甜心小玲',
              description: '甜美可爱，活泼俏皮',
              recommended: true,
              language: 'zh',
              previewUrl: 'https://media.liche.cn/meijiaka-zy/voice/tianxin_xiaoling.mp3',
            },
            {
              voiceId: 'danya_xuejie',
              name: '淡雅学姐',
              description: '淡雅知性，温婉柔和',
              recommended: false,
              language: 'zh',
              previewUrl: 'https://media.liche.cn/meijiaka-zy/voice/danya_xuejie.mp3',
            },
            {
              voiceId: 'Chinese (Mandarin)_Warm_Girl',
              name: '温暖少女',
              description: '温暖亲切，清新自然',
              recommended: false,
              language: 'zh',
              previewUrl: 'https://media.liche.cn/meijiaka-zy/voice/Warm_Girl.mp3',
            },
            {
              voiceId: 'Chinese (Mandarin)_Radio_Host',
              name: '电台男主播',
              description: '专业播报，沉稳有力',
              recommended: false,
              language: 'zh',
              previewUrl: 'https://media.liche.cn/meijiaka-zy/voice/Radio_Host.mp3',
            },
            {
              voiceId: 'Chinese (Mandarin)_Straightforward_Boy',
              name: '率真弟弟',
              description: '率真爽朗，青春阳光',
              recommended: false,
              language: 'zh',
              previewUrl: 'https://media.liche.cn/meijiaka-zy/voice/Straightforward_Boy.mp3',
            },
            {
              voiceId: 'Chinese (Mandarin)_Gentleman',
              name: '温润男声',
              description: '温润如玉，低沉磁性',
              recommended: false,
              language: 'zh',
              previewUrl: 'https://media.liche.cn/meijiaka-zy/voice/Gentleman.mp3',
            },
          ],
        });
      } finally {
        set({ isLoadingVoices: false });
      }
    },

    // ====================== 素材库操作 ======================
    loadVoiceMaterials: async () => {
      set({ isLoadingMaterials: true });
      try {
        const materials = await voiceApi.loadVoiceMaterials();
        set({ voiceMaterials: materials });
      } catch (err) {
        console.error('[VoiceStore] 加载素材库失败:', err);
      } finally {
        set({ isLoadingMaterials: false });
      }
    },

    addVoiceMaterial: async (file: File, name: string) => {
      // 1. 上传七牛云
      const sourceUrl = await voiceApi.uploadAudio(file);

      // 2. 提交 Vidu 同步克隆
      const cloneResult = await voiceApi.submitCloneTask({
        sourceAudioUrl: sourceUrl,
        voiceName: name,
      });

      // 3. Vidu 同步返回，直接 ready
      const material: VoiceMaterial = {
        id: cloneResult.voiceId || cloneResult.taskId,
        name,
        voiceId: cloneResult.voiceId || '',
        sourceUrl,
        trialUrl: cloneResult.trialUrl,
        status: 'ready',
        createdAt: new Date().toISOString(),
      };

      // 4. 保存到本地 JSON
      await voiceApi.saveVoiceMaterial(material);
      set(state => ({ voiceMaterials: [material, ...state.voiceMaterials] }));

      return material;
    },

    updateVoiceMaterialStatus: (id: string, status: VoiceMaterial['status'], voiceId?: string, trialUrl?: string) => {
      set(state => {
        const updated: VoiceMaterial[] = state.voiceMaterials.map((m): VoiceMaterial => {
          if (m.id !== id) {return m;}
          return {
            ...m,
            status,
            voiceId: voiceId || m.voiceId,
            trialUrl: trialUrl || m.trialUrl,
          };
        });
        // 同步保存到本地
        const target = updated.find(m => m.id === id);
        if (target) {
          voiceApi.saveVoiceMaterial(target).catch(err => {
            console.error('[VoiceStore] 保存素材状态失败:', err);
          });
        }
        return { voiceMaterials: updated };
      });
    },

    renameVoiceMaterial: async (id: string, name: string) => {
      set(state => {
        const updated = state.voiceMaterials.map(m => m.id === id ? { ...m, name } : m);
        const target = updated.find(m => m.id === id);
        if (target) {
          voiceApi.saveVoiceMaterial(target).catch(err => {
            console.error('[VoiceStore] 重命名素材失败:', err);
          });
        }
        return { voiceMaterials: updated };
      });
    },

    deleteVoiceMaterial: async (materialId: string) => {
      await voiceApi.deleteVoiceMaterial(materialId);
      set(state => ({
        voiceMaterials: state.voiceMaterials.filter(m => m.id !== materialId),
      }));
    },

    // ====================== 重置 ======================

    reset: () => set(initialState),
  })
);
