using System;
using System.Collections.Generic;
using LittleSim.App;
using MrGameEng.Mods;
using Myra.Graphics2D.UI;

namespace LittleSim.UI;

/// <summary>
/// Конструктор панели настроек (язык, полный экран, VSync, разрешение, громкость).
/// Возвращает виджет Myra, работающий с переданной копией <see cref="GameSettings"/>; общий
/// для сцены настроек и оверлея паузы. Вместо неоднозначных комбо/чекбоксов — кнопки-сегменты
/// и тумблеры (состояние показывает цвет текста), что переносимо между версиями Myra.
/// </summary>
internal static class SettingsPanel
{
    private static readonly (int W, int H)[] Resolutions =
    {
        (1280, 720),
        (1600, 900),
        (1920, 1080),
    };

    /// <summary>Строит панель. <paramref name="onApply"/>/<paramref name="onBack"/> — кнопки внизу.</summary>
    public static Widget Build(
        GameSettings settings,
        LanguageManager lang,
        Action onApply,
        Action onBack
    )
    {
        var refreshers = new List<Action>();
        var column = Ui.Column(10);

        column.Widgets.Add(Ui.Title(lang.Get("settings.title")));
        column.Widgets.Add(new Label { Height = 8 });

        // Язык — по одному сегменту на доступный язык.
        column.Widgets.Add(
            Segment(
                lang.Get("settings.language"),
                lang.AvailableLanguages,
                code => code.ToUpperInvariant(),
                () => settings.Language,
                code => settings.Language = code,
                refreshers
            )
        );

        // Полный экран и VSync — тумблеры (цвет = состояние).
        column.Widgets.Add(
            Toggle(
                lang.Get("settings.fullscreen"),
                () => settings.Fullscreen,
                v => settings.Fullscreen = v,
                refreshers
            )
        );
        column.Widgets.Add(
            Toggle(
                lang.Get("settings.vsync"),
                () => settings.VSync,
                v => settings.VSync = v,
                refreshers
            )
        );

        // Разрешение — сегменты пресетов.
        var resolutions = new List<(int, int)>(Resolutions);
        column.Widgets.Add(
            Segment(
                lang.Get("settings.resolution"),
                resolutions,
                r => $"{r.Item1}×{r.Item2}",
                () => (settings.Width, settings.Height),
                r =>
                {
                    settings.Width = r.Item1;
                    settings.Height = r.Item2;
                },
                refreshers
            )
        );

        // Громкость — кнопки −/+ с подписью процента.
        column.Widgets.Add(Volume(lang.Get("settings.volume"), settings, refreshers));

        column.Widgets.Add(new Label { Height = 8 });
        var buttons = Ui.Row(10);
        buttons.Widgets.Add(Ui.Button(lang.Get("settings.apply"), onApply, width: 150));
        buttons.Widgets.Add(Ui.Button(lang.Get("settings.back"), onBack, width: 150));
        column.Widgets.Add(buttons);

        foreach (var refresh in refreshers)
        {
            refresh();
        }

        return column;
    }

    private static Widget Segment<T>(
        string label,
        IReadOnlyList<T> options,
        Func<T, string> text,
        Func<T> get,
        Action<T> set,
        List<Action> refreshers
    )
    {
        var row = Ui.Row(6);
        row.Widgets.Add(new Label { Text = label, TextColor = Ui.Muted });
        foreach (var option in options)
        {
            var value = option;
            var button = new TextButton { Text = text(value) };
            button.Click += (_, _) => set(value);
            row.Widgets.Add(button);
            refreshers.Add(() =>
                button.TextColor = EqualityComparer<T>.Default.Equals(get(), value)
                    ? Ui.Accent
                    : Ui.Muted
            );
        }

        return row;
    }

    private static Widget Toggle(
        string label,
        Func<bool> get,
        Action<bool> set,
        List<Action> refreshers
    )
    {
        var button = new TextButton();
        button.Click += (_, _) => set(!get());
        refreshers.Add(() =>
        {
            button.Text = (get() ? "● " : "○ ") + label;
            button.TextColor = get() ? Ui.Accent : Ui.Muted;
        });
        return button;
    }

    private static Widget Volume(string label, GameSettings settings, List<Action> refreshers)
    {
        var row = Ui.Row(6);
        var caption = new Label { TextColor = Ui.Muted };
        refreshers.Add(() => caption.Text = $"{label}: {(int)MathF.Round(settings.Volume * 100)}%");

        void Adjust(float delta)
        {
            settings.Volume = Math.Clamp(settings.Volume + delta, 0f, 1f);
            foreach (var refresh in refreshers)
            {
                refresh();
            }
        }

        var minus = new TextButton { Text = "−" };
        minus.Click += (_, _) => Adjust(-0.1f);
        var plus = new TextButton { Text = "+" };
        plus.Click += (_, _) => Adjust(+0.1f);

        row.Widgets.Add(caption);
        row.Widgets.Add(minus);
        row.Widgets.Add(plus);
        return row;
    }
}
