using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace OCES.Audio
{

    public static class AudioImportTool
    {
        const string k_audioResourcePath = "Audios";
        const string k_audioConfigPath = "AudioData";

        static string AudioAbsolutePath
        {
            get { return Path.Combine(Application.dataPath, "Resources", k_audioResourcePath); }
        }
        static string ConfigAbsolutePath
        {
            get { return Path.Combine(Application.dataPath, "Resources", k_audioConfigPath); }
        }

        [MenuItem("Tools/Audio/Apply Audio Import Settings")]
        public static void RunFromMenu()
        {
            if (EditorUtility.DisplayDialog(
                    "Apply Audio Import Settings",
                    $"将对 {AudioAbsolutePath} 下所有文件重新应用导入设置，确认继续？",
                    "确认", "取消"))
            {
                Run();
            }
        }

        /// <summary>
        /// Executes the audio import tool from the command line in batch mode.
        /// This method is designed to be called via Unity's -executeMethod command line argument
        /// and serves as the entry point for automated audio import workflows.
        /// It initializes the process and delegates to the main Run method to apply
        /// audio import settings to all supported audio files in the configured directory.
        /// </summary>
        public static void RunCli()
        {
            Debug.Log("[AudioImportTool] CLI 模式启动");
            Run();
        }

        public static void Run()
        {
            // 1. 加载配置表
            var audioObjectConfig = AudioConfigLoader.Load<AudioObjectConfig>(ConfigAbsolutePath, "AudioObject.bytes");
            var musicSegmentConfig = AudioConfigLoader.Load<MusicSegmentConfig>(ConfigAbsolutePath, "MusicSegment.bytes");
            if (audioObjectConfig == null || musicSegmentConfig == null)
            {
                Debug.LogError("[AudioImportTool] 配置表加载失败，终止");
                return;
            }

            // 2. 扫描文件
            List<string> supportedExtensions = new() { ".wav", ".ogg" };
            DirectoryInfo dir = new(AudioAbsolutePath);
            FileInfo[] files = dir.GetFiles().Where(f => supportedExtensions.Contains(f.Extension.ToLower())).ToArray();
            int total = files.Length, processed = 0, failed = 0;

            AssetDatabase.StartAssetEditing(); // 批量操作，暂停自动刷新
            try
            {
                foreach (FileInfo file in files)
                {
                    // 转成 Assets/... 相对路径供 AssetDatabase 使用
                    string assetPath = "Assets" + file.FullName
                        .Replace(Application.dataPath, "")
                        .Replace("\\", "/");

                    EditorUtility.DisplayProgressBar(
                        "Audio Import Tool",
                        $"处理: {file.Name}  ({processed}/{total})",
                        (float)processed / total);

                    bool ok = ProcessFile(assetPath, file.Name, audioObjectConfig, musicSegmentConfig);
                    if (ok) processed++;
                    else failed++;
                }
            }
            finally
            {
                EditorUtility.ClearProgressBar();
                AssetDatabase.StopAssetEditing();
                AssetDatabase.SaveAssets();
            }

            Debug.Log($"[AudioImportTool] 完成：{processed} 成功，{failed} 失败，共 {total} 个文件");
        }
        
        static bool ProcessFile(
            string assetPath, string fileName,
            AudioObjectConfig audioObjectConfig, MusicSegmentConfig musicSegmentConfig)
        {
            AudioImporter importer = AssetImporter.GetAtPath(assetPath) as AudioImporter;
            if (!importer)
            {
                Debug.LogWarning($"[AudioImportTool] 无法获取 AudioImporter: {assetPath}");
                return false;
            }
            
            AudioClip clip = AssetDatabase.LoadAssetAtPath<AudioClip>(assetPath);
            if (!clip)
            {
                Debug.LogWarning($"[AudioImportTool] 无法加载 AudioClip: {assetPath}");
                return false;
            }
            
            float duration = clip.length;
            string fileNameNoExt = Path.GetFileNameWithoutExtension(fileName);
            AudioCategory category = ClassifyAudio(fileNameNoExt, audioObjectConfig, musicSegmentConfig, out AudioObject audioObject);

            importer.ClearSampleSettingOverride("Android");
            importer.ClearSampleSettingOverride("iOS");
            
            AudioImporterSampleSettings settings = importer.defaultSampleSettings;
            settings.compressionFormat = AudioCompressionFormat.Vorbis;

            settings.sampleRateSetting = AudioSampleRateSetting.OverrideSampleRate;
            settings.preloadAudioData = audioObject?.Haptic != 0;
            switch (category)
            {
                case AudioCategory.Music:
                    settings.sampleRateOverride = 44100;
                    settings.quality = 0.13f;
                    settings.loadType = duration switch
                    {
                        <= 5  => AudioClipLoadType.DecompressOnLoad,
                        >= 15 => AudioClipLoadType.Streaming,
                        _     => AudioClipLoadType.CompressedInMemory,
                    };
                    break;
                case AudioCategory.Voice:
                case AudioCategory.SFX:
                default:
                    settings.sampleRateOverride = 22050; // 音效2022.3.62f3没有32kHz这一档，要是有的话这一档其实最合适
                    settings.quality = 0.5f;
                    settings.loadType = duration switch
                    {
                        >= 15 => AudioClipLoadType.Streaming,
                        _     => AudioClipLoadType.DecompressOnLoad,
                    };
                    break;
            }

            importer.defaultSampleSettings = settings;
            importer.forceToMono = false;
            importer.SaveAndReimport();
            return true;
        }
        
        enum AudioCategory { Music, SFX, Voice }

        static AudioCategory ClassifyAudio(
            string fileName,                  // 不含扩展名
            AudioObjectConfig audioObjectConfig,
            MusicSegmentConfig musicSegmentConfig,
            out AudioObject matchedObject)
        {
            matchedObject = null;

            // 1. MusicSegment 表命中 → Music
            MusicSegment segment = musicSegmentConfig.MusicSegmentList()
                .FirstOrDefault(musicSegment => musicSegment.Name == fileName);
            if (segment != null)
                return AudioCategory.Music;

            // 2. AudioObject 表命中 → 按 MixingType
            AudioObject audioObject = audioObjectConfig.AudioObjectList()
                .FirstOrDefault(audioObject => audioObject.Name != null && audioObject.Name.Contains(fileName));
            if (audioObject != null)
            {
                matchedObject = audioObject;
                return audioObject.MixingType == MixingType.Voice
                    ? AudioCategory.Voice
                    : AudioCategory.SFX;   // SFX + Accent 都走 SFX 分支
            }

            // 3. 文件名 fallback
            string lower = fileName.ToLowerInvariant();
            if (lower.Contains("music") || lower.Contains("bgm"))
                return AudioCategory.Music;
            if (lower.Contains("sfx"))
                return AudioCategory.SFX;
            if (lower.Contains("voice"))
                return AudioCategory.Voice;

            // 4. 完全兜底
            Debug.LogWarning($"[AudioImportTool] 无法分类: {fileName}，默认当作 SFX 处理");
            return AudioCategory.SFX;
        }
    }
}