import { synthesizeSpeech } from './cosyvoice';
import { Log } from '../log/main';
import * as path from 'path';
import * as fs from 'fs';
import { app } from 'electron';

/**
 * 系统默认音色列表（与前端保持一致）
 */
const SYSTEM_VOICES = [
    { id: 'sys_Cherry', title: '芊悦（普通话女声）', aliyunVoiceId: 'Cherry' },
    { id: 'sys_Serena', title: '苏瑶（普通话女声）', aliyunVoiceId: 'Serena' },
    { id: 'sys_Ethan', title: '晨煦（普通话男声）', aliyunVoiceId: 'Ethan' },
    { id: 'sys_Chelsie', title: '千雪（二次元女声）', aliyunVoiceId: 'Chelsie' },
    { id: 'sys_Momo', title: '茉兔（活泼女声）', aliyunVoiceId: 'Momo' },
    { id: 'sys_Vivian', title: '十三（个性女声）', aliyunVoiceId: 'Vivian' },
    { id: 'sys_Moon', title: '月白（率性男声）', aliyunVoiceId: 'Moon' },
    { id: 'sys_Maia', title: '四月（知性女声）', aliyunVoiceId: 'Maia' },
    { id: 'sys_Kai', title: '凯（沉浸男声）', aliyunVoiceId: 'Kai' },
    { id: 'sys_Nofish', title: '不吃鱼（特色男声）', aliyunVoiceId: 'Nofish' },
    { id: 'sys_Bella', title: '萌宝（萝莉女声）', aliyunVoiceId: 'Bella' },
    { id: 'sys_Jennifer', title: '詹妮弗（美语女声）', aliyunVoiceId: 'Jennifer' },
    { id: 'sys_Ryan', title: '甜茶（张力男声）', aliyunVoiceId: 'Ryan' },
    { id: 'sys_Katerina', title: '卡捷琳娜（御姐女声）', aliyunVoiceId: 'Katerina' },
    { id: 'sys_Aiden', title: '艾登（美语男声）', aliyunVoiceId: 'Aiden' },
    { id: 'sys_Arthur', title: '徐大爷（故事男声）', aliyunVoiceId: 'Arthur' },
    { id: 'sys_Bellona', title: '燕铮莺（洪亮女声）', aliyunVoiceId: 'Bellona' },
    { id: 'sys_Bunny', title: '萌小姬（萌系女声）', aliyunVoiceId: 'Bunny' },
    { id: 'sys_Mia', title: '乖小妹（温顺女声）', aliyunVoiceId: 'Mia' },
    { id: 'sys_Mochi', title: '沙小弥（早慧童声）', aliyunVoiceId: 'Mochi' },
    { id: 'sys_Neil', title: '阿闻（新闻男声）', aliyunVoiceId: 'Neil' },
    { id: 'sys_Nini', title: '邻家妹妹（甜美女声）', aliyunVoiceId: 'Nini' },
    { id: 'sys_Ebona', title: '诡婆婆（惊悚女声）', aliyunVoiceId: 'Ebona' },
    { id: 'sys_Seren', title: '小婉（助眠女声）', aliyunVoiceId: 'Seren' },
    { id: 'sys_Pip', title: '顽屁小孩（淘气童声）', aliyunVoiceId: 'Pip' },
    { id: 'sys_Stella', title: '少女阿月（元气女声）', aliyunVoiceId: 'Stella' },
    { id: 'sys_Vincent', title: '田叔（烟嗓男声）', aliyunVoiceId: 'Vincent' },
    { id: 'sys_Radio_Gol', title: '拉迪奥·戈尔（足球解说）', aliyunVoiceId: 'Radio Gol' },
    { id: 'sys_Jada', title: '上海-阿珍（上海话女声）', aliyunVoiceId: 'Jada' },
    { id: 'sys_Dylan', title: '北京-晓东（北京话男声）', aliyunVoiceId: 'Dylan' },
    { id: 'sys_Li', title: '南京-老李（南京话男声）', aliyunVoiceId: 'Li' },
    { id: 'sys_Marcus', title: '陕西-秦川（陕西话男声）', aliyunVoiceId: 'Marcus' },
    { id: 'sys_Roy', title: '闽南-阿杰（闽南语男声）', aliyunVoiceId: 'Roy' },
    { id: 'sys_Peter', title: '天津-李彼得（天津话男声）', aliyunVoiceId: 'Peter' },
    { id: 'sys_Sunny', title: '四川-晴儿（四川话女声）', aliyunVoiceId: 'Sunny' },
    { id: 'sys_Eric', title: '四川-程川（四川话男声）', aliyunVoiceId: 'Eric' },
    { id: 'sys_Rocky', title: '粤语-阿强（粤语男声）', aliyunVoiceId: 'Rocky' },
    { id: 'sys_Kiki', title: '粤语-阿清（粤语女声）', aliyunVoiceId: 'Kiki' },
    { id: 'sys_Bodega', title: '博德加（西语男声）', aliyunVoiceId: 'Bodega' },
    { id: 'sys_Sonrisa', title: '索尼莎（西语女声）', aliyunVoiceId: 'Sonrisa' },
    { id: 'sys_Alek', title: '阿列克（俄语男声）', aliyunVoiceId: 'Alek' },
    { id: 'sys_Dolce', title: '多尔切（意语男声）', aliyunVoiceId: 'Dolce' },
    { id: 'sys_Sohee', title: '素熙（韩语女声）', aliyunVoiceId: 'Sohee' },
    { id: 'sys_Ono_Anna', title: '小野杏（日语女声）', aliyunVoiceId: 'Ono Anna' },
    { id: 'sys_Lenn', title: '莱恩（德语男声）', aliyunVoiceId: 'Lenn' },
    { id: 'sys_Emilien', title: '埃米尔安（法语男声）', aliyunVoiceId: 'Emilien' },
    { id: 'sys_Andre', title: '安德雷（磁性男声）', aliyunVoiceId: 'Andre' },
];

const LEGACY_SYSTEM_VOICE_FILES = [
    'sys_longanyang.mp3',
    'sys_longanhuan.mp3',
    'sys_longanrou_v3.mp3',
    'sys_longhan_v3.mp3',
    'sys_longhuhu_v3.mp3',
];

/**
 * 获取预缓存目录路径
 */
export function getPreCacheDir(): string {
    const userDataPath = app.getPath('userData');
    const cacheDir = path.join(userDataPath, 'voice-preview-cache');

    // 确保目录存在
    if (!fs.existsSync(cacheDir)) {
        fs.mkdirSync(cacheDir, { recursive: true });
    }

    return cacheDir;
}

/**
 * 获取指定音色的预缓存文件路径
 */
export function getPreCachedVoicePath(voiceId: string): string | null {
    const cacheDir = getPreCacheDir();
    const filePath = path.join(cacheDir, `${voiceId}.wav`);

    if (fs.existsSync(filePath)) {
        return filePath;
    }

    return null;
}

export function clearLegacyPreCacheFiles(): void {
    const cacheDir = getPreCacheDir();

    for (const file of LEGACY_SYSTEM_VOICE_FILES) {
        const filePath = path.join(cacheDir, file);
        if (!fs.existsSync(filePath)) {
            continue;
        }

        try {
            fs.unlinkSync(filePath);
            Log.info('voicePreCache.legacyCleared', { filePath });
        } catch (error: any) {
            Log.error('voicePreCache.legacyClearError', { filePath, error: error.message });
        }
    }
}

/**
 * 检查所有默认音色是否已缓存
 */
export function isAllVoicesCached(): boolean {
    return SYSTEM_VOICES.every(voice => {
        const cachedPath = getPreCachedVoicePath(voice.id);
        return cachedPath !== null;
    });
}

/**
 * 预生成所有默认音色的试听音频
 * @param apiKey 阿里云API Key
 * @param force 是否强制重新生成（即使已存在）
 */
export async function preCacheSystemVoices(apiKey: string, force: boolean = false): Promise<void> {
    if (!apiKey) {
        Log.warn('voicePreCache.preCacheSystemVoices', '缺少阿里云API Key，跳过预缓存');
        return;
    }

    Log.info('voicePreCache.preCacheSystemVoices.start', {
        totalVoices: SYSTEM_VOICES.length,
        force
    });

    const cacheDir = getPreCacheDir();
    let cachedCount = 0;
    let generatedCount = 0;
    let errorCount = 0;

    for (const voice of SYSTEM_VOICES) {
        try {
            const filePath = path.join(cacheDir, `${voice.id}.wav`);

            // 如果文件已存在且不强制重新生成，则跳过
            if (!force && fs.existsSync(filePath)) {
                cachedCount++;
                Log.info('voicePreCache.alreadyCached', {
                    voiceId: voice.id,
                    title: voice.title,
                    filePath
                });
                continue;
            }

            // 生成试听文本
            const previewText = `你好，我是${voice.title.split('（')[0]}，很高兴为您服务。`;

            Log.info('voicePreCache.generating', {
                voiceId: voice.id,
                title: voice.title,
                text: previewText
            });

            // 调用阿里云API生成音频
            const result = await synthesizeSpeech(previewText, {
                apiKey: apiKey,
                model: 'qwen3-tts-flash',
                voice: voice.aliyunVoiceId,
                format: 'wav',
                sampleRate: 24000,
                instruction: '请用自然、清晰、适合短视频配音的风格朗读。',
                outputPath: filePath
            });

            if (result.success && result.audioPath) {
                generatedCount++;
                Log.info('voicePreCache.generated', {
                    voiceId: voice.id,
                    title: voice.title,
                    audioPath: result.audioPath,
                    fileSize: fs.existsSync(result.audioPath) ? fs.statSync(result.audioPath).size : 0
                });
            } else {
                errorCount++;
                Log.error('voicePreCache.generateFailed', {
                    voiceId: voice.id,
                    title: voice.title,
                    error: result.error
                });
            }

            // 添加短暂延迟，避免API请求过快
            await new Promise(resolve => setTimeout(resolve, 500));

        } catch (error: any) {
            errorCount++;
            Log.error('voicePreCache.error', {
                voiceId: voice.id,
                title: voice.title,
                error: error.message
            });
        }
    }

    Log.info('voicePreCache.preCacheSystemVoices.complete', {
        total: SYSTEM_VOICES.length,
        alreadyCached: cachedCount,
        generated: generatedCount,
        errors: errorCount
    });
}

/**
 * 清除所有预缓存的音色文件
 */
export function clearPreCache(): void {
    const cacheDir = getPreCacheDir();

    if (fs.existsSync(cacheDir)) {
        const files = fs.readdirSync(cacheDir);
        files.forEach(file => {
            const filePath = path.join(cacheDir, file);
            try {
                fs.unlinkSync(filePath);
                Log.info('voicePreCache.cleared', { filePath });
            } catch (error: any) {
                Log.error('voicePreCache.clearError', { filePath, error: error.message });
            }
        });
    }
}

/**
 * 尝试从应用资源目录复制预缓存文件
 * 用于首次启动或升级时，支持开发环境和打包后的环境
 */
export async function copyPreCacheFromResources(): Promise<boolean> {
    try {
        // 尝试找到应用内的预缓存资源目录
        const possibleResourcePaths = [
            // 打包后的应用（electron-builder extraResources）
            path.join(app.getAppPath(), '../voice-preview-cache'),
            path.join(app.getAppPath(), 'voice-preview-cache'),
            // 打包后的应用（asar 格式）
            path.join(app.getAppPath(), 'voice-preview-cache'),
            path.join(app.getAppPath().replace(/\.asar$/, '.asar.unpacked'), 'voice-preview-cache'),
            // 开发环境
            path.join(process.cwd(), 'electron/resources/voice-preview-cache'),
            // 备选路径
            path.join(process.resourcesPath, 'voice-preview-cache'),
            path.join(process.resourcesPath, '../voice-preview-cache'),
        ];

        Log.info('voicePreCache.searchingResources', {
            appPath: app.getAppPath(),
            resourcesPath: process.resourcesPath,
            cwd: process.cwd(),
            possiblePaths: possibleResourcePaths
        });

        for (const resourcePath of possibleResourcePaths) {
            try {
                if (fs.existsSync(resourcePath)) {
                    const files = SYSTEM_VOICES
                        .map(voice => `${voice.id}.wav`)
                        .filter(file => fs.existsSync(path.join(resourcePath, file)));

                    if (files.length === 0) {
                        Log.info('voicePreCache.resourcePathEmpty', {
                            resourcePath,
                            allFiles: fs.readdirSync(resourcePath)
                        });
                        continue;
                    }

                    const targetDir = getPreCacheDir();
                    let copiedCount = 0;

                    for (const file of files) {
                        const sourceFile = path.join(resourcePath, file);
                        const targetFile = path.join(targetDir, file);

                        try {
                            const existed = fs.existsSync(targetFile);
                            fs.copyFileSync(sourceFile, targetFile);
                            copiedCount++;
                            Log.info(existed ? 'voicePreCache.fileUpdated' : 'voicePreCache.fileCopied', {
                                file,
                                sourceFile,
                                targetFile,
                                size: fs.statSync(sourceFile).size
                            });
                        } catch (copyError: any) {
                            Log.error('voicePreCache.copyError', {
                                file,
                                error: copyError.message
                            });
                        }
                    }

                    if (copiedCount > 0 || files.length > 0) {
                        Log.info('voicePreCache.copyFromResourcesComplete', {
                            resourcePath,
                            totalFiles: files.length,
                            copiedCount,
                            targetDir
                        });
                        return true;
                    }
                }
            } catch (pathError: any) {
                Log.debug('voicePreCache.pathCheckError', {
                    resourcePath,
                    error: pathError.message
                });
                continue;
            }
        }

        // 没有找到资源目录，返回 false
        Log.info('voicePreCache.noResourcesFound', {
            message: '未找到预缓存资源文件，将自动生成',
            possiblePaths: possibleResourcePaths
        });
        return false;
    } catch (error: any) {
        Log.error('voicePreCache.copyFromResourcesError', {
            error: error.message,
            stack: error.stack
        });
        return false;
    }
}
