using System;
using LittleSim.App;
using LittleSim.Content;
using LittleSim.UI;
using Microsoft.Xna.Framework;
using MrGameEng.Audio;
using MrGameEng.Core;
using MrGameEng.Host;
using Myra.Graphics2D.Brushes;
using Myra.Graphics2D.UI;

namespace LittleSim.Scenes;

/// <summary>
/// Внутриигровое меню-пауза: затемняющий оверлей поверх мира (мир остаётся загруженным).
/// Открытие ставит игру на паузу через <see cref="GameSpeed"/>, закрытие — снимает.
/// Кнопки: Продолжить / Настройки (общая <see cref="SettingsPanel"/>) / Сохранить /
/// Главное меню / Выход. <see cref="Root"/> добавляется в корневую панель сцены.
/// </summary>
internal sealed class PauseMenu
{
    private readonly EngineContext _context;
    private readonly GameContent _content;
    private readonly GameSpeed _speed;
    private readonly GameHost _host;
    private readonly AudioManager _audio;
    private readonly Func<string> _onSave;
    private readonly Action _onMainMenu;
    private readonly Action _onQuit;
    private readonly Panel _overlay;
    private GameSettings _settings = GameSettingsStore.Load();
    private bool _inSettings;
    private string? _savedToast;

    public PauseMenu(
        EngineContext context,
        GameContent content,
        GameSpeed speed,
        Func<string> onSave,
        Action onMainMenu,
        Action onQuit
    )
    {
        _context = context;
        _content = content;
        _speed = speed;
        _host = (GameHost)context.Services.Get<Game>();
        _audio = context.Services.Get<AudioManager>();
        _onSave = onSave;
        _onMainMenu = onMainMenu;
        _onQuit = onQuit;

        _overlay = new Panel
        {
            Visible = false,
            Background = new SolidBrush(new Color(0, 0, 0, 200)),
            HorizontalAlignment = HorizontalAlignment.Stretch,
            VerticalAlignment = VerticalAlignment.Stretch,
        };
    }

    /// <summary>Виджет оверлея для добавления в корень сцены.</summary>
    public Widget Root => _overlay;

    /// <summary>Открыт ли оверлей паузы.</summary>
    public bool IsOpen { get; private set; }

    /// <summary>
    /// Реакция на Esc: закрыть подменю настроек → вернуться к кнопкам; иначе открыть/закрыть
    /// меню паузы.
    /// </summary>
    public void Toggle()
    {
        if (!IsOpen)
        {
            Open();
        }
        else if (_inSettings)
        {
            _inSettings = false;
            ShowButtons();
        }
        else
        {
            Close();
        }
    }

    private void Open()
    {
        IsOpen = true;
        _inSettings = false;
        _savedToast = null;
        _speed.Pause();
        ShowButtons();
        _overlay.Visible = true;
    }

    private void Close()
    {
        IsOpen = false;
        _inSettings = false;
        _overlay.Visible = false;
        _speed.Resume();
    }

    private void ShowButtons()
    {
        var lang = _content.Languages;
        var column = Ui.Column(10);
        column.Widgets.Add(Ui.Title(lang.Get("pause.title")));
        column.Widgets.Add(new Label { Height = 8 });
        column.Widgets.Add(Ui.Button(lang.Get("pause.resume"), Close));
        column.Widgets.Add(
            Ui.Button(
                lang.Get("pause.settings"),
                () =>
                {
                    _inSettings = true;
                    ShowSettings();
                }
            )
        );
        column.Widgets.Add(Ui.Button(lang.Get("pause.save"), Save));
        column.Widgets.Add(Ui.Button(lang.Get("pause.mainmenu"), _onMainMenu));
        column.Widgets.Add(Ui.Button(lang.Get("pause.quit"), _onQuit));

        if (_savedToast is not null)
        {
            column.Widgets.Add(
                new Label { Text = lang.Format("pause.saved", _savedToast), TextColor = Ui.Muted }
            );
        }

        SetContent(column);
    }

    private void ShowSettings() =>
        SetContent(
            SettingsPanel.Build(
                _settings,
                _content.Languages,
                onApply: () =>
                {
                    GameSettingsStore.Save(_settings);
                    GameSettingsStore.Apply(_settings, _host.Graphics, _content.Languages, _audio);
                    ShowSettings(); // язык мог смениться
                },
                onBack: () =>
                {
                    _inSettings = false;
                    ShowButtons();
                }
            )
        );

    private void Save()
    {
        _savedToast = _onSave();
        ShowButtons();
    }

    private void SetContent(Widget content)
    {
        _overlay.Widgets.Clear();
        _overlay.Widgets.Add(content);
    }
}
