using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Myra.Graphics2D;
using Myra.Graphics2D.Brushes;
using Myra.Graphics2D.UI;
using Theriapolis.Core.Data;
using Theriapolis.Core.Rules.Reputation;

namespace Theriapolis.Game.Screens;

/// <summary>
/// Phase 6 M2 — reputation screen (R key). Two columns:
///   1. **Factions:** strip of bars per known faction with NEMESIS..CHAMPION
///      colour banding + numeric standing.
///   2. **Recent contacts:** last N NPCs the player has personally
///      interacted with — name, role, current personal disposition,
///      trust ladder.
/// Plus a tail block showing the most recent ledger entries with their
/// reasons ("why does so-and-so hate me?" breadcrumbs).
///
/// Hidden factions (e.g. The Maw before Act I climax) are skipped from
/// the faction column; they still accumulate state internally.
///
/// In debug builds, F12 fires a synthetic "+5 Inheritor" event so we can
/// eyeball the cascade live without scripting a quest.
/// </summary>
public sealed class ReputationScreen : IScreen
{
    private readonly PlayerReputation _rep;
    private readonly ContentResolver  _content;
    private Game1 _game = null!;
    private Desktop _desktop = null!;
    private bool _rWasDown   = true;
    private bool _escWasDown = true;
    private bool _f12WasDown = true;

    public ReputationScreen(PlayerReputation rep, ContentResolver content)
    {
        _rep     = rep     ?? throw new System.ArgumentNullException(nameof(rep));
        _content = content ?? throw new System.ArgumentNullException(nameof(content));
    }

    public void Initialize(Game1 game)
    {
        _game = game;
        BuildUI();
    }

    private void BuildUI()
    {
        var root = new VerticalStackPanel
        {
            Spacing             = 8,
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment   = VerticalAlignment.Top,
            Margin              = new Thickness(20),
            Padding             = new Thickness(20, 12, 20, 12),
            Background          = new SolidBrush(new Color(15, 12, 8, 235)),
            Width               = 880,
        };

        root.Widgets.Add(new Label
        {
            Text                = "REPUTATION",
            HorizontalAlignment = HorizontalAlignment.Center,
            TextColor           = new Color(255, 230, 170),
        });
        root.Widgets.Add(new Label { Text = " " });

        var twoCol = new HorizontalStackPanel { Spacing = 24 };

        // ── Factions column ─────────────────────────────────────────────
        var leftCol = new VerticalStackPanel { Spacing = 4, Width = 420 };
        leftCol.Widgets.Add(new Label { Text = "FACTIONS", TextColor = new Color(200, 180, 130) });
        foreach (var f in _content.Factions.Values.Where(f => !f.Hidden).OrderBy(f => f.Name))
        {
            int score = _rep.Factions.Get(f.Id);
            var label = DispositionLabels.For(score);
            leftCol.Widgets.Add(new Label
            {
                Text      = $"{f.Name,-24}  {score,+4:+#;-#;0}   {DispositionLabels.DisplayName(label)}",
                TextColor = ColorForLabel(label),
            });
        }
        twoCol.Widgets.Add(leftCol);

        // ── Personal column ────────────────────────────────────────────
        var rightCol = new VerticalStackPanel { Spacing = 4, Width = 420 };
        rightCol.Widgets.Add(new Label { Text = "RECENT CONTACTS", TextColor = new Color(200, 180, 130) });
        var personals = _rep.Personal.Values.OrderByDescending(p => p.LastInteractionSeconds).Take(12).ToList();
        if (personals.Count == 0)
            rightCol.Widgets.Add(new Label
            {
                Text      = "(no one has met you yet)",
                TextColor = new Color(120, 110, 100),
            });
        foreach (var p in personals)
        {
            var label = DispositionLabels.For(p.Score);
            rightCol.Widgets.Add(new Label
            {
                Text      = $"{p.RoleTag,-30}  {p.Score,+4:+#;-#;0}  {p.Trust}",
                TextColor = ColorForLabel(label),
            });
        }
        twoCol.Widgets.Add(rightCol);
        root.Widgets.Add(twoCol);

        // ── Recent ledger ──────────────────────────────────────────────
        root.Widgets.Add(new Label { Text = " " });
        root.Widgets.Add(new Label { Text = "RECENT EVENTS", TextColor = new Color(200, 180, 130) });
        var recent = _rep.Ledger.Entries.Reverse().Take(10).ToList();
        if (recent.Count == 0)
            root.Widgets.Add(new Label
            {
                Text      = "(no events yet)",
                TextColor = new Color(120, 110, 100),
            });
        foreach (var ev in recent)
        {
            string what = string.IsNullOrEmpty(ev.FactionId)
                ? (string.IsNullOrEmpty(ev.RoleTag) ? "world" : ev.RoleTag)
                : ev.FactionId;
            string note = string.IsNullOrEmpty(ev.Note) ? "" : $" — {ev.Note}";
            root.Widgets.Add(new Label
            {
                Text      = $"  [{ev.Kind,-9}] {what,-26} {ev.Magnitude,+4:+#;-#;0}{note}",
                TextColor = ev.Magnitude >= 0 ? new Color(160, 200, 140) : new Color(220, 140, 140),
            });
        }

        // ── Footer ─────────────────────────────────────────────────────
        root.Widgets.Add(new Label { Text = " " });
        root.Widgets.Add(new Label
        {
            Text                = "(R / Esc to close · F12 in debug build = +5 Inheritor synthetic event)",
            HorizontalAlignment = HorizontalAlignment.Center,
            TextColor           = new Color(120, 110, 100),
        });

        _desktop = new Desktop { Root = root };
    }

    public void Update(GameTime gt)
    {
        var ks = Keyboard.GetState();
        bool r   = ks.IsKeyDown(Keys.R);
        bool esc = ks.IsKeyDown(Keys.Escape);
        bool f12 = ks.IsKeyDown(Keys.F12);

        bool rPressed   = r   && !_rWasDown;
        bool escPressed = esc && !_escWasDown;
        bool f12Pressed = f12 && !_f12WasDown;

        _rWasDown = r; _escWasDown = esc; _f12WasDown = f12;

        if (rPressed || escPressed) { _game.Screens.Pop(); return; }

#if DEBUG
        if (f12Pressed)
        {
            // Dev affordance — fire a +5 Inheritor event so the cascade is
            // visible to the eye without authoring a quest.
            _rep.Submit(new RepEvent
            {
                Kind      = RepEventKind.Misc,
                FactionId = "inheritors",
                Magnitude = 5,
                Note      = "dev affordance (F12)",
            }, _content.Factions);
            BuildUI();  // refresh
        }
#endif
    }

    public void Draw(GameTime gt, SpriteBatch sb) => _desktop.Render();
    public void Deactivate() { }
    public void Reactivate() { }

    private static Color ColorForLabel(DispositionLabel label) => label switch
    {
        DispositionLabel.Nemesis      => new Color(220,  60,  60),
        DispositionLabel.Hostile      => new Color(220, 110,  90),
        DispositionLabel.Antagonistic => new Color(220, 160, 110),
        DispositionLabel.Unfriendly   => new Color(200, 180, 130),
        DispositionLabel.Neutral      => new Color(180, 180, 180),
        DispositionLabel.Favorable    => new Color(170, 200, 150),
        DispositionLabel.Friendly     => new Color(140, 210, 130),
        DispositionLabel.Allied       => new Color(110, 220, 130),
        DispositionLabel.Champion     => new Color(150, 230, 200),
        _                              => Color.White,
    };
}
