using System;
using System.Drawing;
using System.Windows.Forms;
using NyxCS2.Core;

namespace NyxCS2.UI;

// ============================================================================
//  NYX CS2 - external menu  (clean neon-dark sidebar + panels)
//
//  Left sidebar tabs switch the content panel. Every control writes straight
//  into AppSettings, which the engine/overlay re-read every tick, so each
//  toggle applies live as you click it - no re-open, no "menu trash".
//
//  Palette:  #0d1117 base / #161b22 sidebar / #00d4ff accent / Segoe UI.
// ============================================================================
public class MenuForm : Form
{
    private readonly Engine _engine;
    private readonly AppSettings _s;
    private readonly OverlayForm _overlay;

    private readonly Panel _sidebar;
    private readonly Panel _pVisuals, _pAim, _pTrig, _pExtra;

    private readonly System.Windows.Forms.Timer _statusTimer;
    private readonly Label _status;
    private readonly Button _btnVisuals, _btnAim, _btnTrig, _btnExtra;

    private Label _valFov = null!, _valSmooth = null!, _valDist = null!, _valTrig = null!;

    // ---------- theme ----------
    private static readonly Color Bg     = Color.FromArgb(13, 17, 23);   // #0d1117
    private static readonly Color Side   = Color.FromArgb(22, 27, 34);   // #161b22
    private static readonly Color Accent = Color.FromArgb(0, 212, 255);  // #00d4ff
    private static readonly Color TextDim = Color.FromArgb(139, 148, 158);

    public MenuForm(Engine engine, AppSettings s, OverlayForm overlay)
    {
        _engine = engine;
        _s = s;
        _overlay = overlay;

        Text = "NYX CS2 v" + Program.Version;
        FormBorderStyle = FormBorderStyle.FixedSingle;
        MaximizeBox = false;
        MinimizeBox = false;
        ClientSize = new Size(640, 560);
        StartPosition = FormStartPosition.CenterScreen;
        BackColor = Bg;
        ForeColor = Color.WhiteSmoke;
        Font = new Font("Segoe UI", 9f);

        // ---------------- sidebar ----------------
        _sidebar = new Panel
        {
            Bounds = new Rectangle(0, 0, 160, ClientSize.Height),
            BackColor = Side
        };
        Controls.Add(_sidebar);

        _sidebar.Controls.Add(new Label
        {
            Text = "NYX CS2",
            Location = new Point(16, 14),
            AutoSize = true,
            Font = new Font("Segoe UI", 13f, FontStyle.Bold),
            ForeColor = Accent
        });
        _sidebar.Controls.Add(new Label
        {
            Text = "external · v" + Program.Version,
            Location = new Point(16, 38),
            AutoSize = true,
            ForeColor = TextDim
        });

        int by = 64;
        _btnVisuals = AddTabButton("VISUALS", by);       by += 42;
        _btnAim     = AddTabButton("AIM", by);           by += 42;
        _btnTrig    = AddTabButton("TRIGGER", by);       by += 42;
        _btnExtra   = AddTabButton("EXTRA", by);         by += 42;

        // ---------------- content panels ----------------
        _pVisuals = NewPanel();
        _pAim     = NewPanel();
        _pTrig    = NewPanel();
        _pExtra   = NewPanel();

        Controls.Add(_pVisuals);
        Controls.Add(_pAim);
        Controls.Add(_pTrig);
        Controls.Add(_pExtra);

        BuildVisuals(_pVisuals);
        BuildAim(_pAim);
        BuildTrig(_pTrig);
        BuildExtra(_pExtra);

        // ---------------- bottom bar (to the right of the sidebar) ----------------
        var bottom = new Panel
        {
            Bounds = new Rectangle(160, ClientSize.Height - 44, ClientSize.Width - 160, 44),
            BackColor = Side
        };
        Controls.Add(bottom);
        bottom.BringToFront();

        var btnQuit = MakeButton("Quit", 10, () => Application.Exit());
        var btnHide = MakeButton("Hide [INS]", 96, () => _overlay.Toggle());
        var btnMenu = MakeButton("Menu [END]", 182, () => Toggle());
        var btnRef  = MakeButton("Re-fetch", 270, () => NyxCS2.Core.OffsetUpdater.RefetchNow());
        bottom.Controls.Add(btnQuit);
        bottom.Controls.Add(btnHide);
        bottom.Controls.Add(btnMenu);
        bottom.Controls.Add(btnRef);

        // ---------------- status line (inside the bottom bar) ----------------
        _status = new Label
        {
            Text = "waiting for CS2...",
            Location = new Point(368, 10),
            AutoSize = true,
            ForeColor = TextDim
        };
        bottom.Controls.Add(_status);

        _statusTimer = new System.Windows.Forms.Timer { Interval = 1000 };
        _statusTimer.Tick += (_, _) => UpdateStatus();
        _statusTimer.Start();
        UpdateStatus();

        SelectTab(_pVisuals);
    }

    // ---------- lifetime ----------
    public void Toggle()
    {
        if (InvokeRequired) { BeginInvoke(new Action(Toggle)); return; }
        Visible = !Visible;
    }

    private void UpdateStatus()
    {
        try
        {
            Snapshot snap = _engine.Snap;
            _status.Text = snap == null || !snap.Attached
                ? snap?.Status ?? "not started"
                : $"{snap.Status} | p={snap.Players.Count}";
        }
        catch { }
    }

    // ---------- helpers ----------
    private Button AddTabButton(string text, int y)
    {
        var b = new Button
        {
            Text = text,
            Location = new Point(10, y),
            Size = new Size(140, 36),
            FlatStyle = FlatStyle.Flat,
            FlatAppearance = { BorderSize = 0, MouseOverBackColor = Color.FromArgb(30, 36, 48) },
            BackColor = Side,
            ForeColor = Color.Gainsboro,
            TextAlign = ContentAlignment.MiddleLeft
        };
        b.Click += (_, _) => SelectTab(PanelFor(text));
        _sidebar.Controls.Add(b);
        return b;
    }

    private Panel PanelFor(string text) =>
        text switch
        {
            "AIM"     => _pAim,
            "TRIGGER" => _pTrig,
            "EXTRA"   => _pExtra,
            _         => _pVisuals
        };

    private void SelectTab(Panel target)
    {
        Activate(_btnVisuals, ReferenceEquals(target, _pVisuals));
        Activate(_btnAim,     ReferenceEquals(target, _pAim));
        Activate(_btnTrig,    ReferenceEquals(target, _pTrig));
        Activate(_btnExtra,   ReferenceEquals(target, _pExtra));
        _pVisuals.Visible = ReferenceEquals(target, _pVisuals);
        _pAim.Visible     = ReferenceEquals(target, _pAim);
        _pTrig.Visible    = ReferenceEquals(target, _pTrig);
        _pExtra.Visible   = ReferenceEquals(target, _pExtra);
    }

    private static void Activate(Button b, bool active)
    {
        b.BackColor = active ? Color.FromArgb(0, 120, 160) : Side;
        b.ForeColor = active ? Color.White : Color.Gainsboro;
    }

    private Panel NewPanel() =>
        new Panel
        {
            Bounds = new Rectangle(160, 0, ClientSize.Width - 160, ClientSize.Height - 44),
            BackColor = Bg
        };

    private static Button MakeButton(string text, int x, Action onClick)
    {
        var b = new Button
        {
            Text = text,
            Location = new Point(x, 7),
            Size = new Size(80, 30),
            FlatStyle = FlatStyle.Flat,
            FlatAppearance = { BorderSize = 0, MouseOverBackColor = Color.FromArgb(30, 36, 48) },
            BackColor = Color.FromArgb(30, 36, 48),
            ForeColor = Color.Gainsboro
        };
        b.Click += (_, _) => onClick();
        return b;
    }

    // ---------- control factories ----------
    private int AddHeader(string text, int y, Panel p)
    {
        p.Controls.Add(new Label
        {
            Text = text,
            Location = new Point(18, y),
            AutoSize = true,
            Font = new Font("Segoe UI", 10f, FontStyle.Bold),
            ForeColor = Accent
        });
        return y + 26;
    }

    private int AddCheck(string text, bool init, Action<bool> set, int y, Panel p)
    {
        var c = new CheckBox
        {
            Text = text,
            Checked = init,
            Location = new Point(20, y),
            AutoSize = true,
            ForeColor = Color.WhiteSmoke
        };
        c.CheckedChanged += (_, _) => set(c.Checked);
        p.Controls.Add(c);
        return y + 30;
    }

    private int AddCombo(string text, string[] items, int sel, Action<int> set, int y, Panel p)
    {
        p.Controls.Add(new Label
        {
            Text = text,
            Location = new Point(20, y + 3),
            AutoSize = true,
            ForeColor = TextDim
        });
        var cb = new ComboBox
        {
            Location = new Point(180, y),
            Width = 110,
            DropDownStyle = ComboBoxStyle.DropDownList
        };
        cb.Items.AddRange(items);
        if (sel >= 0 && sel < cb.Items.Count) cb.SelectedIndex = sel;
        cb.SelectedIndexChanged += (_, _) => set(cb.SelectedIndex);
        p.Controls.Add(cb);
        return y + 32;
    }

    private int AddSlider(string text, int init, int min, int max, Action<int> set,
        out Label valLabel, int y, Panel p)
    {
        p.Controls.Add(new Label
        {
            Text = text,
            Location = new Point(20, y + 3),
            AutoSize = true,
            ForeColor = TextDim
        });
        valLabel = new Label
        {
            Text = init.ToString(),
            Location = new Point(286, y + 3),
            AutoSize = true,
            ForeColor = Accent
        };
        p.Controls.Add(valLabel);
        Label show = valLabel;
        var t = new TrackBar
        {
            Location = new Point(180, y),
            Width = 100,
            Minimum = min,
            Maximum = max,
            Value = Math.Clamp(init, min, max),
            TickStyle = TickStyle.None
        };
        t.ValueChanged += (_, _) => { set(t.Value); show.Text = t.Value.ToString(); };
        p.Controls.Add(t);
        return y + 36;
    }

    // ---------- tab contents ----------
    private void BuildVisuals(Panel p)
    {
        int y = 18;
        y = AddHeader("VISUALS", y, p);
        y = AddCheck("ESP enabled",     _s.EspEnabled,    v => _s.EspEnabled = v,    y, p);
        y = AddCheck("Boxes",           _s.Boxes,         v => _s.Boxes = v,         y, p);
        y = AddCheck("Health bar",      _s.HealthBar,     v => _s.HealthBar = v,     y, p);
        y = AddCheck("Name + distance", _s.ShowName,      v => _s.ShowName = v,      y, p);
        y = AddCheck("Snapline",        _s.Snapline,      v => _s.Snapline = v,      y, p);
        y = AddCheck("Weapon name",     _s.WeaponEsp,     v => _s.WeaponEsp = v,     y, p);
        y = AddCheck("Armor bar",       _s.ArmorBar,      v => _s.ArmorBar = v,      y, p);
        y = AddCheck("Health text",     _s.HealthText,    v => _s.HealthText = v,    y, p);
        y = AddCheck("Player list",     _s.ShowPlayerList,v => _s.ShowPlayerList = v,y, p);
        y = AddCheck("Enemies only",    _s.EnemiesOnly,   v => _s.EnemiesOnly = v,   y, p);
        y = AddCheck("Skeleton",        _s.Skeleton,      v => _s.Skeleton = v,      y, p);
    }

    private void BuildAim(Panel p)
    {
        int y = 18;
        y = AddHeader("AIM", y, p);
        y = AddCheck("Aim enabled", _s.AimEnabled, v => _s.AimEnabled = v, y, p);
        y = AddCheck("FOV circle",  _s.ShowFovCircle, v => _s.ShowFovCircle = v, y, p);
        y = AddCombo("Aim key", new[] { "Always", "Right mouse", "Alt" }, _s.AimKey - 1,
            i => _s.AimKey = i + 1, y, p);
        y = AddCombo("Aim position", new[] { "Head", "Chest", "Legs" }, _s.AimPos,
            i => _s.AimPos = i, y, p);
        y = AddSlider("FOV (deg)", _s.AimFov, 1, 60, v => _s.AimFov = v, out _valFov, y, p);
        y = AddSlider("Smooth", _s.AimSmooth, 1, 30, v => _s.AimSmooth = v, out _valSmooth, y, p);
        y = AddSlider("Max dist (m)", _s.MaxDistance, 0, 400, v => _s.MaxDistance = v, out _valDist, y, p);
    }

    private void BuildTrig(Panel p)
    {
        int y = 18;
        y = AddHeader("TRIGGER", y, p);
        y = AddCheck("Triggerbot", _s.Triggerbot, v => _s.Triggerbot = v, y, p);
        y = AddCombo("Trigger key", new[] { "Always", "Right mouse", "Alt" }, _s.TriggerKey - 1,
            i => _s.TriggerKey = i + 1, y, p);
        y = AddSlider("Delay (ms)", _s.TriggerDelay, 25, 400, v => _s.TriggerDelay = v,
            out _valTrig, y, p);
    }

    private void BuildExtra(Panel p)
    {
        int y = 18;
        y = AddHeader("EXTRA", y, p);
        y = AddCheck("Anti-flash", _s.AntiFlash, v => _s.AntiFlash = v, y, p);
        y = AddCheck("Crosshair",  _s.Crosshair, v => _s.Crosshair = v, y, p);
    }
}