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

public class AudioImportSettingsWindow : EditorWindow
{
    private Vector2 scrollPosition;
    private List<AudioClipInfo> audioClips = new List<AudioClipInfo>();
    private bool scanned;
    private bool applyWebGLOverride;

    // Unity 6+ renamed "WebGL" to "Web" as the platform identifier
    private static readonly string[] WebPlatformNames = { "WebGL", "Web" };

    private class AudioClipInfo
    {
        public string path;
        public AudioImporter importer;
        public AudioImporterSampleSettings defaultSettings;
        public bool hasWebGLOverride;
        public AudioImporterSampleSettings webGLSettings;
        public bool needsFix;
    }

    [MenuItem("FRVR/Audio Import Settings")]
    public static void ShowWindow()
    {
        GetWindow<AudioImportSettingsWindow>("Audio Import Settings");
    }

    private void OnGUI()
    {
        EditorGUILayout.Space(5);

        EditorGUILayout.BeginHorizontal();
        if (GUILayout.Button("Scan All Audio", GUILayout.Height(30)))
        {
            ScanAudioClips();
        }

        int fixCount = 0;
        foreach (var clip in audioClips)
        {
            if (clip.needsFix) fixCount++;
        }

        EditorGUI.BeginDisabledGroup(fixCount == 0);
        if (GUILayout.Button($"Fix All ({fixCount})", GUILayout.Height(30)))
        {
            FixAll();
        }
        EditorGUI.EndDisabledGroup();
        EditorGUILayout.EndHorizontal();

        EditorGUILayout.Space(5);
        bool prev = applyWebGLOverride;
        applyWebGLOverride = EditorGUILayout.ToggleLeft(
            "Apply WebGL Override (use when global setting doesn't propagate properly)",
            applyWebGLOverride);
        if (prev != applyWebGLOverride && scanned)
        {
            ScanAudioClips();
        }

        if (!scanned)
        {
            EditorGUILayout.HelpBox("Click 'Scan All Audio' to find all audio clips in the project.", MessageType.Info);
            return;
        }

        EditorGUILayout.Space(5);
        EditorGUILayout.LabelField($"Found {audioClips.Count} audio clips, {fixCount} need fixing", EditorStyles.boldLabel);

        string targetDesc = "Target settings:\n  - Load Type: Compressed In Memory";
        if (applyWebGLOverride)
            targetDesc += "\n  - WebGL Override: Compression Format = AAC";
        targetDesc += "\n\nThis fixes the iOS WebGL mute button issue.";
        EditorGUILayout.HelpBox(targetDesc, MessageType.Info);
        EditorGUILayout.Space(5);

        scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);

        foreach (var clip in audioClips)
        {
            DrawClipEntry(clip);
        }

        EditorGUILayout.EndScrollView();
    }

    private void DrawClipEntry(AudioClipInfo clip)
    {
        var style = new GUIStyle(EditorStyles.helpBox);
        {
            var tex = new Texture2D(1, 1);
            tex.SetPixel(0, 0, clip.needsFix
                ? new Color(0.8f, 0.2f, 0.2f, 0.15f)
                : new Color(0.2f, 0.8f, 0.2f, 0.15f));
            tex.Apply();
            style.normal.background = tex;
        }

        EditorGUILayout.BeginVertical(style);

        // Header row
        EditorGUILayout.BeginHorizontal();
        string statusIcon = clip.needsFix ? "X" : "OK";
        EditorGUILayout.LabelField($"[{statusIcon}] {clip.path}", EditorStyles.boldLabel);

        if (GUILayout.Button("Select", GUILayout.Width(60)))
        {
            var obj = AssetDatabase.LoadAssetAtPath<AudioClip>(clip.path);
            if (obj != null)
            {
                Selection.activeObject = obj;
                EditorGUIUtility.PingObject(obj);
            }
        }

        if (clip.needsFix)
        {
            if (GUILayout.Button("Fix", GUILayout.Width(50)))
            {
                ApplyFix(clip);
                ScanAudioClips();
                GUIUtility.ExitGUI();
            }
        }
        EditorGUILayout.EndHorizontal();

        // Default settings
        EditorGUI.indentLevel++;
        string loadType = clip.defaultSettings.loadType.ToString();
        bool loadTypeOk = clip.defaultSettings.loadType == AudioClipLoadType.CompressedInMemory;
        EditorGUILayout.LabelField("Default Load Type", FormatValue(loadType, loadTypeOk));

        // WebGL settings (always show current state for info)
        if (clip.hasWebGLOverride)
        {
            string webGLFormat = clip.webGLSettings.compressionFormat.ToString();
            string webGLLoadType = clip.webGLSettings.loadType.ToString();

            if (applyWebGLOverride)
            {
                bool formatOk = clip.webGLSettings.compressionFormat == AudioCompressionFormat.AAC;
                bool webGLLoadOk = clip.webGLSettings.loadType == AudioClipLoadType.CompressedInMemory;
                EditorGUILayout.LabelField("WebGL Compression", FormatValue(webGLFormat, formatOk));
                EditorGUILayout.LabelField("WebGL Load Type", FormatValue(webGLLoadType, webGLLoadOk));
            }
            else
            {
                EditorGUILayout.LabelField("WebGL Override", $"{webGLFormat} / {webGLLoadType}  (has override)");
            }
        }
        else
        {
            if (applyWebGLOverride)
                EditorGUILayout.LabelField("WebGL Override", FormatValue("Not Set", false));
            else
                EditorGUILayout.LabelField("WebGL Override", "Not Set");
        }
        EditorGUI.indentLevel--;

        EditorGUILayout.EndVertical();
        EditorGUILayout.Space(2);
    }

    private string FormatValue(string value, bool isCorrect)
    {
        return isCorrect ? $"{value}  [OK]" : $"{value}  [NEEDS FIX]";
    }

    private static string FindWebPlatformKey(string assetPath)
    {
        string metaPath = assetPath + ".meta";
        if (!File.Exists(metaPath)) return null;

        string metaContent = File.ReadAllText(metaPath);
        foreach (var name in WebPlatformNames)
        {
            if (metaContent.Contains($"    {name}:") || metaContent.Contains($"\t{name}:"))
                return name;
        }
        return null;
    }

    private static bool ContainsWebOverride(AudioImporter importer, string assetPath)
    {
        // Try API first
        foreach (var name in WebPlatformNames)
            if (importer.ContainsSampleSettingsOverride(name)) return true;

        // Fallback: check .meta file directly (Unity 6 API may not report overrides correctly)
        return FindWebPlatformKey(assetPath) != null;
    }

    private static AudioImporterSampleSettings GetWebOverride(AudioImporter importer, string assetPath)
    {
        // Try API first
        foreach (var name in WebPlatformNames)
            if (importer.ContainsSampleSettingsOverride(name))
                return importer.GetOverrideSampleSettings(name);

        // Fallback: try to read using the key found in the .meta file
        string key = FindWebPlatformKey(assetPath);
        if (key != null)
            return importer.GetOverrideSampleSettings(key);

        return importer.defaultSampleSettings;
    }

    private static void SetWebOverride(AudioImporter importer, AudioImporterSampleSettings settings)
    {
        foreach (var name in WebPlatformNames)
        {
            if (importer.SetOverrideSampleSettings(name, settings))
                return;
        }
    }

    private void ScanAudioClips()
    {
        audioClips.Clear();
        string[] guids = AssetDatabase.FindAssets("t:AudioClip");

        foreach (string guid in guids)
        {
            string path = AssetDatabase.GUIDToAssetPath(guid);
            var importer = AssetImporter.GetAtPath(path) as AudioImporter;
            if (importer == null) continue;

            var info = new AudioClipInfo
            {
                path = path,
                importer = importer,
                defaultSettings = importer.defaultSampleSettings,
            };

            info.hasWebGLOverride = ContainsWebOverride(importer, path);
            if (info.hasWebGLOverride)
            {
                info.webGLSettings = GetWebOverride(importer, path);
            }

            // Check if it needs fixing
            bool defaultOk = info.defaultSettings.loadType == AudioClipLoadType.CompressedInMemory;

            if (applyWebGLOverride)
            {
                bool webGLOk = info.hasWebGLOverride
                    && info.webGLSettings.compressionFormat == AudioCompressionFormat.AAC
                    && info.webGLSettings.loadType == AudioClipLoadType.CompressedInMemory;
                info.needsFix = !defaultOk || !webGLOk;
            }
            else
            {
                info.needsFix = !defaultOk;
            }

            audioClips.Add(info);
        }

        // Sort: items needing fix first
        audioClips.Sort((a, b) =>
        {
            if (a.needsFix != b.needsFix)
                return a.needsFix ? -1 : 1;
            return string.Compare(a.path, b.path);
        });

        scanned = true;
    }

    private void ApplyFix(AudioClipInfo clip)
    {
        var importer = clip.importer;

        // Set default load type to Compressed In Memory
        var defaultSettings = importer.defaultSampleSettings;
        defaultSettings.loadType = AudioClipLoadType.CompressedInMemory;
        importer.defaultSampleSettings = defaultSettings;

        if (applyWebGLOverride)
        {
            // Set WebGL/Web override with AAC compression and Compressed In Memory
            var webGLSettings = ContainsWebOverride(importer, clip.path)
                ? GetWebOverride(importer, clip.path)
                : importer.defaultSampleSettings;

            webGLSettings.compressionFormat = AudioCompressionFormat.AAC;
            webGLSettings.loadType = AudioClipLoadType.CompressedInMemory;
            SetWebOverride(importer, webGLSettings);
        }

        importer.SaveAndReimport();
    }

    private void FixAll()
    {
        int count = 0;
        foreach (var clip in audioClips)
        {
            if (!clip.needsFix) continue;
            ApplyFix(clip);
            count++;
        }

        string msg = $"Fixed {count} audio clip(s).\n\nAll clips now use:\n- Compressed In Memory";
        if (applyWebGLOverride)
            msg += "\n- WebGL: AAC compression";

        EditorUtility.DisplayDialog("Audio Import Settings", msg, "OK");

        ScanAudioClips();
    }
}
