using System.Numerics;
using Dalamud.Bindings.ImGui;
using Dalamud.Interface;
using Dalamud.Interface.Colors;
using Dalamud.Interface.Utility;
using Dalamud.Interface.Utility.Raii;
using HellionChat.Resources;
using HellionChat.Util;

namespace HellionChat.Ui.SettingsTabs;

// Six sections: Messages, Input & preview, Auto-tell tabs, Emotes, Links & tooltips, Novice network.
internal sealed class Chat : ISettingsTab
{
    private Plugin Plugin { get; }
    private Configuration Mutable { get; }

    public string Name => HellionStrings.Settings_Tab_Chat + "###tabs-chat";

    private SearchSelector.SelectorPopupOptions WordPopupOptions;

    // Tracks which EmoteCache state WordPopupOptions was built for so we
    // don't refill every frame when FilteredSheet is empty.
    private EmoteCache.LoadingState? WordPopupOptionsBuiltFor;

    internal Chat(Plugin plugin, Configuration mutable)
    {
        Plugin = plugin;
        Mutable = mutable;

        WordPopupOptions = RefillSheet();
        WordPopupOptionsBuiltFor = EmoteCache.State;
    }

    private SearchSelector.SelectorPopupOptions RefillSheet() =>
        new SearchSelector.SelectorPopupOptions
        {
            FilteredSheet = EmoteCache
                .SortedCodeArray.Where(w => !Mutable.BlockedEmotes.Contains(w))
                .ToArray(),
        };

    public void Draw(bool sectionJustEntered)
    {
        DrawMessagesSection(sectionJustEntered);
        ImGui.Spacing();
        DrawInputPreviewSection(sectionJustEntered);
        ImGui.Spacing();
        DrawAutoTellTabsSection(sectionJustEntered);
        ImGui.Spacing();
        DrawEmotesSection(sectionJustEntered);
        ImGui.Spacing();
        DrawLinksTooltipsSection(sectionJustEntered);
        ImGui.Spacing();
        DrawNoviceNetworkSection(sectionJustEntered);
    }

    private void DrawMessagesSection(bool sectionJustEntered)
    {
        if (sectionJustEntered)
            ImGui.SetNextItemOpen(false);
        using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_Messages);
        if (!tree.Success)
            return;

        using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
        {
            // Checkboxes first.
            ImGui.Checkbox(
                Language.Options_CollapseDuplicateMessages_Name,
                ref Mutable.CollapseDuplicateMessages
            );
            ImGuiUtil.HelpMarker(Language.Options_CollapseDuplicateMessages_Description);

            // Conditional child: only visible when parent is on (R4).
            if (Mutable.CollapseDuplicateMessages)
            {
                ImGui.Checkbox(
                    Language.Options_CollapseDuplicateMsgUniqueLink_Name,
                    ref Mutable.CollapseKeepUniqueLinks
                );
                ImGuiUtil.HelpMarker(Language.Options_CollapseDuplicateMsgUniqueLink_Description);
            }

            ImGui.Checkbox(
                HellionStrings.Settings_Chat_NotifyFailedTell_Name,
                ref Mutable.NotifyFailedTell
            );
            ImGuiUtil.HelpMarker(HellionStrings.Settings_Chat_NotifyFailedTell_Description);

            ImGui.Checkbox(
                HellionStrings.Settings_Chat_NotifyPluginDisclosure_Name,
                ref Mutable.NotifyPluginDisclosure
            );
            ImGuiUtil.HelpMarker(HellionStrings.Settings_Chat_NotifyPluginDisclosure_Description);

            // Dropdowns after checkboxes (R3).
            // UI-7: name display options.
            using (
                var combo = ImGuiUtil.BeginComboVertical(
                    HellionStrings.Settings_Chat_WorldSuffix_Name,
                    Mutable.WorldSuffixMode.Name()
                )
            )
            {
                if (combo.Success)
                {
                    foreach (var mode in Enum.GetValues<WorldSuffixMode>())
                    {
                        if (ImGui.Selectable(mode.Name(), Mutable.WorldSuffixMode == mode))
                            Mutable.WorldSuffixMode = mode;
                    }
                }
            }
            ImGuiUtil.HelpMarker(HellionStrings.Settings_Chat_WorldSuffix_Description);

            using (
                var combo = ImGuiUtil.BeginComboVertical(
                    HellionStrings.Settings_Chat_NameForm_Name,
                    Mutable.NameFormMode.Name()
                )
            )
            {
                if (combo.Success)
                {
                    foreach (var mode in Enum.GetValues<NameFormMode>())
                    {
                        if (ImGui.Selectable(mode.Name(), Mutable.NameFormMode == mode))
                            Mutable.NameFormMode = mode;
                    }
                }
            }
            ImGuiUtil.HelpMarker(HellionStrings.Settings_Chat_NameForm_Description);
        }
    }

    private void DrawInputPreviewSection(bool sectionJustEntered)
    {
        if (sectionJustEntered)
            ImGui.SetNextItemOpen(false);
        using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_InputPreview);
        if (!tree.Success)
            return;

        using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
        {
            // Checkboxes first.
            ImGui.Checkbox(
                HellionStrings.Settings_Chat_SymbolPicker_Enable_Name,
                ref Mutable.SymbolPickerEnabled
            );
            ImGuiUtil.HelpMarker(HellionStrings.Settings_Chat_SymbolPicker_Enable_Description);

            ImGui.Checkbox(Language.Options_PreviewOnlyIf_Name, ref Mutable.OnlyPreviewIf);
            ImGuiUtil.HelpMarker(Language.Options_PreviewOnlyIf_Description);

            // Dropdown after checkboxes (R3).
            using (
                var combo = ImGuiUtil.BeginComboVertical(
                    Language.Options_Preview_Name,
                    Mutable.PreviewPosition.Name()
                )
            )
            {
                if (combo)
                {
                    foreach (var position in Enum.GetValues<PreviewPosition>())
                    {
                        if (ImGui.Selectable(position.Name(), Mutable.PreviewPosition == position))
                            Mutable.PreviewPosition = position;
                    }
                }
            }
            ImGuiUtil.HelpMarker(Language.Options_Preview_Description);

            // Number input last (R3).
            if (
                ImGuiUtil.InputIntVertical(
                    Language.Options_PreviewMinimum_Name,
                    Language.Options_PreviewMinimum_Description,
                    ref Mutable.PreviewMinimum
                )
            )
                Mutable.PreviewMinimum = Math.Clamp(Mutable.PreviewMinimum, 1, 250);
        }
    }

    private void DrawAutoTellTabsSection(bool sectionJustEntered)
    {
        if (sectionJustEntered)
            ImGui.SetNextItemOpen(false);
        using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_AutoTellTabs);
        if (!tree.Success)
            return;

        using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
        {
            // Checkboxes first (R3).
            ImGui.Checkbox(
                HellionStrings.ChatLog_AutoTellTabs_Enable_Name,
                ref Mutable.EnableAutoTellTabs
            );
            ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_Enable_Description);

            ImGui.Checkbox(
                HellionStrings.ChatLog_AutoTellTabs_Compact_Name,
                ref Mutable.AutoTellTabsCompactDisplay
            );
            ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_Compact_Description);

            ImGui.Checkbox(
                HellionStrings.ChatLog_AutoTellTabs_OpenAsPopout_Name,
                ref Mutable.AutoTellTabsOpenAsPopout
            );
            ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_OpenAsPopout_Description);

            ImGui.Checkbox(
                HellionStrings.ChatLog_AutoTellTabs_GreetedToggle_Name,
                ref Mutable.AutoTellTabsShowGreetedToggle
            );
            ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_GreetedToggle_Description);

            // Sliders after checkboxes (R3).
            ImGui.SetNextItemWidth(200f * ImGuiHelpers.GlobalScale);
            var limit = Mutable.AutoTellTabsLimit;
            if (ImGui.SliderInt(HellionStrings.ChatLog_AutoTellTabs_Limit_Name, ref limit, 1, 50))
                Mutable.AutoTellTabsLimit = limit;
            ImGuiUtil.HelpMarker(HellionStrings.ChatLog_AutoTellTabs_Limit_Description);

            ImGui.Spacing();
            ImGuiUtil.HelpText(HellionStrings.ChatLog_AutoTellTabs_PreloadHint);

            ImGui.Spacing();
            ImGuiUtil.WarningText(HellionStrings.ChatLog_AutoTellTabs_ConflictHint);

            ImGui.Spacing();
            ImGui.Separator();
            ImGui.Spacing();

            var preload = Mutable.AutoTellTabsHistoryPreload;
            ImGui.SetNextItemWidth(200f * ImGuiHelpers.GlobalScale);
            if (
                ImGui.SliderInt(
                    HellionStrings.Privacy_AutoTellTabs_Preload_Name,
                    ref preload,
                    0,
                    100
                )
            )
                Mutable.AutoTellTabsHistoryPreload = preload;
            ImGuiUtil.HelpMarker(HellionStrings.Privacy_AutoTellTabs_Preload_Description);

            ImGui.Spacing();
            ImGuiUtil.HelpText(HellionStrings.Privacy_AutoTellTabs_Preload_Hint);
        }
    }

    private void DrawEmotesSection(bool sectionJustEntered)
    {
        if (sectionJustEntered)
            ImGui.SetNextItemOpen(false);
        using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_Emotes);
        if (!tree.Success)
            return;

        using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
        {
            // Checkbox first (R3).
            ImGui.Checkbox(Language.Options_ShowEmotes_Name, ref Mutable.ShowEmotes);
            ImGuiUtil.HelpMarker(Language.Options_ShowEmotes_Desc);

            ImGui.Spacing();
            ImGui.TextUnformatted(Language.Options_Emote_BlockedEmotes);
            ImGui.Spacing();

            if (
                EmoteCache.State is EmoteCache.LoadingState.Done
                && WordPopupOptions.FilteredSheet.Length == 0
                && WordPopupOptionsBuiltFor != EmoteCache.LoadingState.Done
            )
            {
                WordPopupOptions = RefillSheet();
                WordPopupOptionsBuiltFor = EmoteCache.LoadingState.Done;
            }

            // Button to add blocked emotes (R3 — button before table).
            var buttonWidth = ImGui.GetContentRegionAvail().X / 3;
            using (Plugin.FontManager.FontAwesome.Push())
                ImGui.Button(FontAwesomeIcon.Plus.ToIconString(), new Vector2(buttonWidth, 0));

            // OpenPopup on click because SelectorPopup uses ContextPopupItem
            // which only triggers on right-click by default.
            if (ImGui.IsItemClicked())
                ImGui.OpenPopup("WordAddPopup");

            if (SearchSelector.SelectorPopup("WordAddPopup", out var newWord, WordPopupOptions))
                Mutable.BlockedEmotes.Add(newWord);

            using (
                var table = ImRaii.Table(
                    "##BlockedWords",
                    2,
                    ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersInner
                )
            )
            {
                if (table)
                {
                    ImGui.TableSetupColumn(Language.Options_Emote_EmoteTable);
                    ImGui.TableSetupColumn("##Del", ImGuiTableColumnFlags.WidthStretch, 0.07f);
                    ImGui.TableHeadersRow();

                    foreach (var word in Mutable.BlockedEmotes.ToArray())
                    {
                        ImGui.TableNextColumn();
                        ImGui.TextUnformatted(word);

                        ImGui.TableNextColumn();
                        if (
                            ImGuiUtil.Button(
                                $"##{word}Del",
                                FontAwesomeIcon.Trash,
                                !ImGui.GetIO().KeyCtrl
                            )
                        )
                            Mutable.BlockedEmotes.Remove(word);
                    }
                }
            }

            ImGui.Spacing();
            ImGui.Separator();
            ImGui.Spacing();

            ImGui.TextUnformatted(Language.Options_Emote_EmoteStats);
            ImGui.Spacing();

            if (EmoteCache.State is EmoteCache.LoadingState.Done)
                ImGui.TextColored(ImGuiColors.HealerGreen, Language.Options_Emote_Ready);
            else
                ImGui.TextColored(ImGuiColors.DPSRed, Language.Options_Emote_NotReady);

            ImGui.TextUnformatted(
                $"{Language.Options_Emote_Loaded} {EmoteCache.SortedCodeArray.Length}"
            );

            // 5-column loaded-emotes display table.
            using (
                var emoteTable = ImRaii.Table(
                    "##LoadedEmotes",
                    5,
                    ImGuiTableFlags.RowBg | ImGuiTableFlags.BordersInner
                )
            )
            {
                if (emoteTable)
                {
                    ImGui.TableSetupColumn("##word1");
                    ImGui.TableSetupColumn("##word2");
                    ImGui.TableSetupColumn("##word3");
                    ImGui.TableSetupColumn("##word4");
                    ImGui.TableSetupColumn("##word5");

                    foreach (var word in EmoteCache.SortedCodeArray)
                    {
                        ImGui.TableNextColumn();
                        ImGui.TextUnformatted(word);
                    }
                }
            }
        }
    }

    private void DrawLinksTooltipsSection(bool sectionJustEntered)
    {
        if (sectionJustEntered)
            ImGui.SetNextItemOpen(false);
        using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_LinksTooltips);
        if (!tree.Success)
            return;

        using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
        {
            ImGui.Checkbox(
                Language.Options_NativeItemTooltips_Name,
                ref Mutable.NativeItemTooltips
            );
            ImGuiUtil.HelpMarker(
                string.Format(Language.Options_NativeItemTooltips_Description, Plugin.PluginName)
            );

            // Conditional slider: only shown when native tooltips are enabled (R4).
            if (Mutable.NativeItemTooltips)
            {
                ImGuiUtil.DragFloatVertical(
                    Language.Options_TooltipOffset_Name,
                    Language.Options_TooltipOffset_Desc,
                    ref Mutable.TooltipOffset,
                    1,
                    0f,
                    400f,
                    $"{Mutable.TooltipOffset:N0}px",
                    ImGuiSliderFlags.AlwaysClamp
                );
            }
        }
    }

    private void DrawNoviceNetworkSection(bool sectionJustEntered)
    {
        if (sectionJustEntered)
            ImGui.SetNextItemOpen(false);
        using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_NoviceNetwork);
        if (!tree.Success)
            return;

        using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
        {
            ImGui.Checkbox(Language.Options_ShowNoviceNetwork_Name, ref Mutable.ShowNoviceNetwork);
            ImGuiUtil.HelpMarker(Language.Options_ShowNoviceNetwork_Description);
        }
    }
}
