using CloudBuilder.AI.Policy;
using CloudBuilder.Core.DatabaseAccessor.Entity;
using DocumentFormat.OpenXml.Spreadsheet;
using EdgeTtsSharp;
using Google.Protobuf.WellKnownTypes;
using SherpaOnnx;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace CloudBuilder.AI.Service.Utility
{
    public class SaveAudioToFileHelper
    {
        private IApplicationService service;
        private OfflineTts offlineTts1;
        private OfflineTts offlineTts2;
        private OfflineTts offlineTts3;
        private OfflineTts offlineTts4;

        public SaveAudioToFileHelper(IApplicationService service)
        {
            this.service = service;

            InitOfflineTtsConfig(DeclaimerPolicy.VITS_ZH_HF_THERESA);

            InitOfflineTtsConfig(DeclaimerPolicy.VITS_ZH_HF_FANCHEN_C);

            InitOfflineTtsConfig(DeclaimerPolicy.SHERPA_ONNX_VITS_ZH_LL);

            InitOfflineTtsConfig(DeclaimerPolicy.VITS_MELO_TTS_ZH_EN);
        }

        private void InitOfflineTtsConfig(string ttsId)
        {
            var config = new OfflineTtsConfig();
            config.Model.Provider = "cpu";
            config.Model.NumThreads = 2;
            config.MaxNumSentences = 1;

            switch (ttsId)
            {
                case DeclaimerPolicy.VITS_ZH_HF_THERESA:
                    config.Model.Vits.Model = "tts-models/vits-zh-hf-theresa/theresa.onnx";
                    config.Model.Vits.Tokens = "tts-models/vits-zh-hf-theresa/tokens.txt";
                    config.Model.Vits.Lexicon = "tts-models/vits-zh-hf-theresa/lexicon.txt";
                    offlineTts1 = new OfflineTts(config);
                    break;
                case DeclaimerPolicy.VITS_ZH_HF_FANCHEN_C:
                    config.Model.Vits.Model = "tts-models/vits-zh-hf-fanchen-C/vits-zh-hf-fanchen-C.onnx";
                    config.Model.Vits.Tokens = "tts-models/vits-zh-hf-fanchen-C/tokens.txt";
                    config.Model.Vits.Lexicon = "tts-models/vits-zh-hf-fanchen-C/lexicon.txt";
                    config.RuleFars = "tts-models/vits-zh-hf-fanchen-C/phone.fst,tts-models/vits-zh-hf-fanchen-C/number.fst";
                    offlineTts2 = new OfflineTts(config);
                    break;
                case DeclaimerPolicy.SHERPA_ONNX_VITS_ZH_LL:
                    config.Model.Vits.Model = "tts-models/sherpa-onnx-vits-zh-ll/model.onnx";
                    config.Model.Vits.Tokens = "tts-models/sherpa-onnx-vits-zh-ll/tokens.txt";
                    config.Model.Vits.Lexicon = "tts-models/sherpa-onnx-vits-zh-ll/lexicon.txt";
                    config.RuleFars = "tts-models/sherpa-onnx-vits-zh-ll/phone.fst,tts-models/sherpa-onnx-vits-zh-ll/number.fst";
                    offlineTts3 = new OfflineTts(config);
                    break;
                default://DeclaimerPolicy.VITS_MELO_TTS_ZH_EN
                    config.Model.Vits.Model = "tts-models/vits-melo-tts-zh_en/model.onnx";
                    config.Model.Vits.Tokens = "tts-models/vits-melo-tts-zh_en/tokens.txt";
                    config.Model.Vits.Lexicon = "tts-models/vits-melo-tts-zh_en/lexicon.txt";
                    offlineTts4 = new OfflineTts(config);
                    break;
            }

            // --- 2. 初始化引擎 ---
            offlineTts1 = new OfflineTts(config);
        }

        public void AudioToFile(string text, string saveFilePath)
        {
            AudioToFile(DeclaimerPolicy.VITS_MELO_TTS_ZH_EN, 0, text, saveFilePath);
        }

        public void AudioToFile(string ttsId, int sid, string text, string saveFilePath)
        {
            float speed = 1.0f;
            OfflineTtsGeneratedAudio audio;
            switch (ttsId)
            {
                case DeclaimerPolicy.VITS_ZH_HF_THERESA:
                    audio = offlineTts1.Generate(text, speed, sid);
                    break;
                case DeclaimerPolicy.VITS_ZH_HF_FANCHEN_C:
                    audio = offlineTts2.Generate(text, speed, sid);
                    break;
                case DeclaimerPolicy.SHERPA_ONNX_VITS_ZH_LL:
                    audio = offlineTts3.Generate(text, speed, sid);
                    break;
                default://DeclaimerPolicy.VITS_MELO_TTS_ZH_EN
                    audio = offlineTts4.Generate(text, speed, sid);
                    break;
            }
            audio.SaveToWaveFile(saveFilePath);
        }

        public static void AudioToFile(ChineseTtsVoice actorName, string text, string saveFilePath)
        {
            // 步骤1：同步获取异步语音对象
            var voiceTask = EdgeTts.GetVoice(actorName.GetVoiceId());
            var voice = voiceTask.GetAwaiter().GetResult(); // 替代await，同步阻塞

            // 步骤2：同步保存音频文件
            var saveTask = voice.SaveAudioToFile(text, saveFilePath);
            saveTask.GetAwaiter().GetResult(); // 同步等待保存完成
        }
    }
    /// <summary>
    /// 微软Edge TTS中文语音音色枚举
    /// 对应官方Neural语音标识，覆盖港澳台及大陆各地区音色
    /// </summary>
    public enum ChineseTtsVoice
    {
        /// <summary>
        /// 粤语（香港）- 喜佳（女性）
        /// </summary>
        [System.ComponentModel.Description("zh-HK-HiuGaaiNeural")]
        ZhHkHiuGaaiNeural,

        /// <summary>
        /// 粤语（香港）- 喜文（女性）
        /// </summary>
        [System.ComponentModel.Description("zh-HK-HiuMaanNeural")]
        ZhHkHiuMaanNeural,

        /// <summary>
        /// 粤语（香港）- 云龙（男性）
        /// </summary>
        [System.ComponentModel.Description("zh-HK-WanLungNeural")]
        ZhHkWanLungNeural,

        /// <summary>
        /// 普通话（中国大陆）- 晓晓（女性）
        /// </summary>
        [System.ComponentModel.Description("zh-CN-XiaoxiaoNeural")]
        ZhCnXiaoxiaoNeural,

        /// <summary>
        /// 普通话（中国大陆）- 小艺（女性）
        /// </summary>
        [System.ComponentModel.Description("zh-CN-XiaoyiNeural")]
        ZhCnXiaoyiNeural,

        /// <summary>
        /// 普通话（中国大陆）- 云健（男性）
        /// </summary>
        [System.ComponentModel.Description("zh-CN-YunjianNeural")]
        ZhCnYunjianNeural,

        /// <summary>
        /// 普通话（中国大陆）- 云希（男性）
        /// </summary>
        [System.ComponentModel.Description("zh-CN-YunxiNeural")]
        ZhCnYunxiNeural,

        /// <summary>
        /// 普通话（中国大陆）- 云夏（女性）
        /// </summary>
        [System.ComponentModel.Description("zh-CN-YunxiaNeural")]
        ZhCnYunxiaNeural,

        /// <summary>
        /// 普通话（中国大陆）- 云阳（男性）
        /// </summary>
        [System.ComponentModel.Description("zh-CN-YunyangNeural")]
        ZhCnYunyangNeural,

        /// <summary>
        /// 普通话（中国大陆-辽宁）- 小北（女性）
        /// </summary>
        [System.ComponentModel.Description("zh-CN-liaoning-XiaobeiNeural")]
        ZhCnLiaoningXiaobeiNeural,

        /// <summary>
        /// 普通话（台湾）- 小珍（女性）
        /// </summary>
        [System.ComponentModel.Description("zh-TW-HsiaoChenNeural")]
        ZhTwHsiaoChenNeural,

        /// <summary>
        /// 普通话（台湾）- 云哲（男性）
        /// </summary>
        [System.ComponentModel.Description("zh-TW-YunJheNeural")]
        ZhTwYunJheNeural,

        /// <summary>
        /// 普通话（台湾）- 小瑜（女性）
        /// </summary>
        [System.ComponentModel.Description("zh-TW-HsiaoYuNeural")]
        ZhTwHsiaoYuNeural,

        /// <summary>
        /// 普通话（中国大陆-陕西）- 小妮（女性）
        /// </summary>
        [System.ComponentModel.Description("zh-CN-shaanxi-XiaoniNeural")]
        ZhCnShaanxiXiaoniNeural
    }

    public static class ChineseTtsVoiceExtensions
    {
        /// <summary>
        /// 获取枚举值对应的Description特性值
        /// </summary>
        /// <param name="voice">语音枚举值</param>
        /// <returns>描述字符串（无特性时返回枚举名称）</returns>
        public static string GetVoiceId(this ChineseTtsVoice voice)
        {
            // 获取枚举成员的特性
            var field = voice.GetType().GetField(voice.ToString());
            var attribute = field?.GetCustomAttribute<DescriptionAttribute>();

            // 有特性返回描述，无则返回枚举名
            return attribute?.Description ?? voice.ToString();
        }
    }
}
