// VRC Messages — ajoute un sous-menu « Messages » avec 2 boutons :
//   - Écrire un message  (MSG_Open) -> l'app ouvre une zone de texte au centre de l'écran
//   - Conversation       (MSG_Chat) -> l'app ouvre la fenêtre de conversation
//   - Vocal              (MSG_Voice) -> maintenu = enregistre, relâché = envoie
// Les boutons ne font rien sur l'avatar : ils préviennent seulement l'app (OSC). Paramètres locaux, 0 bit synchronisé.
//
// Menu : Tools > VRC Messages > Installer les boutons sur l'avatar sélectionné
// (ou glisser « Clavier Messages » sur l'avatar, ou clic droit sur le VRC Avatar Descriptor)
#if UNITY_EDITOR
using System.Collections.Generic;
using System.IO;
using UnityEditor;
using UnityEngine;
using VRC.SDK3.Avatars.Components;
using VRC.SDK3.Avatars.ScriptableObjects;

public static class VRCMessagesSimpleToggle
{
    const string ParamOpen = "MSG_Open";
    const string ParamChat = "MSG_Chat";
    const string ParamVoice = "MSG_Voice";
    const string ParamQuick = "MSG_Quick";
    const string LabelQuick = "Réponses rapides";
    const string QuickMenuPath = GenDir + "/VRCM_QuickMenu.asset";
    static readonly string[] QuickLabels =
        { "J'arrive !", "Viens en vocal", "2 minutes", "❤️", "Oui", "Non", "Tu es où ?", "Bonne nuit 🌙" };
    const string LabelVoice = "Vocal (maintenir)";
    const string LabelOpen = "Écrire un message";
    const string LabelChat = "Conversation";
    const string SubMenuLabel = "Messages";
    const string GenDir = "Assets/VRCMessages/Generated";
    const string IconDir = GenDir + "/Icons";
    const string SubMenuPath = GenDir + "/VRCM_MessagesMenu.asset";

    [MenuItem("Tools/VRC Messages/Installer les boutons sur l'avatar sélectionné")]
    static void FromMenu()
    {
        var sel = Selection.activeGameObject;
        var desc = sel != null ? sel.GetComponentInParent<VRCAvatarDescriptor>() : null;
        if (desc == null)
        {
            EditorUtility.DisplayDialog("VRC Messages", "Sélectionne ton avatar dans la Hierarchy, puis relance.", "OK");
            return;
        }
        Install(desc);
    }

    [MenuItem("CONTEXT/VRCAvatarDescriptor/VRC Messages : installer les boutons")]
    static void FromContext(MenuCommand cmd)
    {
        var desc = cmd.context as VRCAvatarDescriptor;
        if (desc != null) Install(desc);
    }

    public static void Install(VRCAvatarDescriptor desc)
    {
        // 1. Retire le clavier 3D (ancienne version) s'il est présent
        VRCMessagesKeyboardSetup.RemoveFromAvatar(desc, VRCMessagesKeyboardSetup.GetFxController(desc));

        EnsureFolder(GenDir);
        EnsureFolder(IconDir);

        // 2. Paramètres locaux
        var ep = desc.expressionParameters;
        if (ep == null)
        {
            ep = ScriptableObject.CreateInstance<VRCExpressionParameters>();
            ep.parameters = new VRCExpressionParameters.Parameter[0];
            AssetDatabase.CreateAsset(ep, AssetDatabase.GenerateUniqueAssetPath(GenDir + "/VRCM_Parameters.asset"));
            desc.expressionParameters = ep;
        }
        var list = new List<VRCExpressionParameters.Parameter>(ep.parameters ?? new VRCExpressionParameters.Parameter[0]);
        list.RemoveAll(p => p != null && (p.name == ParamOpen || p.name == ParamChat || p.name == ParamVoice ||
                                          p.name == ParamQuick));
        list.Add(LocalBool(ParamOpen));
        list.Add(LocalBool(ParamChat));
        list.Add(LocalBool(ParamVoice));
        list.Add(new VRCExpressionParameters.Parameter
        {
            name = ParamQuick,
            valueType = VRCExpressionParameters.ValueType.Int,
            defaultValue = 0f,
            saved = false,
            networkSynced = false
        });
        ep.parameters = list.ToArray();
        EditorUtility.SetDirty(ep);

        // 3. Icônes
        var iconMsg = EnsureIcon("vrcm_icon_message.png", VRCMessagesIcons.Message);
        var iconConv = EnsureIcon("vrcm_icon_conversation.png", VRCMessagesIcons.Conversation);
        var iconVoice = EnsureIcon("vrcm_icon_voice.png", VRCMessagesIcons.Voice);
        var iconQuick = EnsureIcon("vrcm_icon_quick.png", VRCMessagesIcons.Quick);

        // Sous-menu « Réponses rapides » : 8 boutons qui mettent MSG_Quick à 1..8
        AssetDatabase.DeleteAsset(QuickMenuPath);
        var quick = ScriptableObject.CreateInstance<VRCExpressionsMenu>();
        quick.controls = new List<VRCExpressionsMenu.Control>();
        for (int i = 0; i < QuickLabels.Length; i++)
        {
            quick.controls.Add(new VRCExpressionsMenu.Control
            {
                name = QuickLabels[i],
                type = VRCExpressionsMenu.Control.ControlType.Button,
                parameter = new VRCExpressionsMenu.Control.Parameter { name = ParamQuick },
                value = i + 1
            });
        }
        AssetDatabase.CreateAsset(quick, QuickMenuPath);

        // 4. Sous-menu « Messages »
        AssetDatabase.DeleteAsset(SubMenuPath);
        var sub = ScriptableObject.CreateInstance<VRCExpressionsMenu>();
        sub.controls = new List<VRCExpressionsMenu.Control>
        {
            new VRCExpressionsMenu.Control
            {
                name = LabelOpen,
                icon = iconMsg,
                type = VRCExpressionsMenu.Control.ControlType.Button,
                parameter = new VRCExpressionsMenu.Control.Parameter { name = ParamOpen },
                value = 1f
            },
            new VRCExpressionsMenu.Control
            {
                name = LabelChat,
                icon = iconConv,
                type = VRCExpressionsMenu.Control.ControlType.Button,
                parameter = new VRCExpressionsMenu.Control.Parameter { name = ParamChat },
                value = 1f
            },
            new VRCExpressionsMenu.Control
            {
                name = LabelVoice,
                icon = iconVoice,
                type = VRCExpressionsMenu.Control.ControlType.Button,
                parameter = new VRCExpressionsMenu.Control.Parameter { name = ParamVoice },
                value = 1f
            },
            new VRCExpressionsMenu.Control
            {
                name = LabelQuick,
                icon = iconQuick,
                type = VRCExpressionsMenu.Control.ControlType.SubMenu,
                subMenu = quick
            }
        };
        AssetDatabase.CreateAsset(sub, SubMenuPath);

        // 5. Menu principal
        var menu = desc.expressionsMenu;
        if (menu == null)
        {
            menu = ScriptableObject.CreateInstance<VRCExpressionsMenu>();
            menu.controls = new List<VRCExpressionsMenu.Control>();
            AssetDatabase.CreateAsset(menu, AssetDatabase.GenerateUniqueAssetPath(GenDir + "/VRCM_Menu.asset"));
            desc.expressionsMenu = menu;
        }
        menu.controls.RemoveAll(c => c != null &&
            (c.name == LabelOpen || c.name == SubMenuLabel || c.name == "Clavier messages"));
        bool added = false;
        if (menu.controls.Count < 8)
        {
            menu.controls.Add(new VRCExpressionsMenu.Control
            {
                name = SubMenuLabel,
                icon = iconMsg,
                type = VRCExpressionsMenu.Control.ControlType.SubMenu,
                subMenu = sub
            });
            added = true;
        }
        EditorUtility.SetDirty(menu);

        desc.customExpressions = true;
        EditorUtility.SetDirty(desc);
        AssetDatabase.SaveAssets();

        EditorUtility.DisplayDialog("VRC Messages",
            "Installé sur « " + desc.gameObject.name + " ».\n\n" +
            (added
                ? "Sous-menu « " + SubMenuLabel + " » ajouté à ton menu, avec « " + LabelOpen + " », « " + LabelChat + " », « " + LabelVoice + " » et « " + LabelQuick + " ».\n"
                : "⚠ Ton menu principal est plein (8 contrôles). Ajoute à la main un SubMenu qui pointe vers :\n" + SubMenuPath + "\n") +
            "\nRé-uploade l'avatar, puis dans VRChat : Options > OSC > Reset Config.", "OK");
    }

    static VRCExpressionParameters.Parameter LocalBool(string name)
    {
        return new VRCExpressionParameters.Parameter
        {
            name = name,
            valueType = VRCExpressionParameters.ValueType.Bool,
            defaultValue = 0f,
            saved = false,
            networkSynced = false
        };
    }

    static Texture2D EnsureIcon(string file, string base64)
    {
        string path = IconDir + "/" + file;
        if (AssetDatabase.LoadAssetAtPath<Texture2D>(path) == null)
        {
            File.WriteAllBytes(path, System.Convert.FromBase64String(base64));
            AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceSynchronousImport | ImportAssetOptions.ForceUpdate);
        }
        var imp = AssetImporter.GetAtPath(path) as TextureImporter;
        if (imp != null)
        {
            bool changed = false;
            if (imp.textureType != TextureImporterType.Default) { imp.textureType = TextureImporterType.Default; changed = true; }
            if (!imp.alphaIsTransparency) { imp.alphaIsTransparency = true; changed = true; }
            if (imp.mipmapEnabled) { imp.mipmapEnabled = false; changed = true; }
            if (imp.maxTextureSize != 256) { imp.maxTextureSize = 256; changed = true; }
            if (changed) imp.SaveAndReimport();
        }
        return AssetDatabase.LoadAssetAtPath<Texture2D>(path);
    }

    static void EnsureFolder(string path)
    {
        if (AssetDatabase.IsValidFolder(path)) return;
        string parent = Path.GetDirectoryName(path).Replace('\\', '/');
        EnsureFolder(parent);
        AssetDatabase.CreateFolder(parent, Path.GetFileName(path));
    }
}
#endif
