using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Myra;
using Theriapolis.Game.CodexUI.Core;
using Theriapolis.Game.Screens;

namespace Theriapolis.Game;

/// <summary>
/// Root MonoGame game class.
/// Owns the screen stack, SpriteBatch, and the path to content data files.
/// </summary>
public sealed class Game1 : Microsoft.Xna.Framework.Game
{
    private readonly GraphicsDeviceManager _graphics;
    private SpriteBatch _spriteBatch = null!;

    public ScreenManager Screens { get; private set; } = null!;

    /// <summary>
    /// Path to the Content/Data directory containing JSON data files.
    /// Defaults to "Data" relative to the executable; Desktop shell overrides this.
    /// </summary>
    public string ContentDataDirectory { get; set; } = "Data";

    /// <summary>
    /// Path to the Content/Gfx directory containing sprite assets. Defaults to
    /// "Gfx" relative to the executable; Desktop shell overrides this. The
    /// TacticalAtlas reads <c>Gfx/tactical/surface/*.png</c> and
    /// <c>Gfx/tactical/deco/*.png</c> from here, falling back to procedural
    /// placeholders for any tile that has no PNG yet.
    /// </summary>
    public string ContentGfxDirectory { get; set; } = "Gfx";

    /// <summary>
    /// Strongly-typed asset bundle for CodexUI screens. Loaded once during
    /// <see cref="LoadContent"/> so every CodexScreen can reference the
    /// atlas without re-reading PNGs from disk.
    /// </summary>
    public CodexAtlas CodexAtlas { get; private set; } = new();

    // Dev background colour — distinctive so it's obvious when nothing is drawn
    private static readonly Color DevClear = new(18, 24, 48);

    public Game1()
    {
        _graphics = new GraphicsDeviceManager(this)
        {
            PreferredBackBufferWidth  = 1280,
            PreferredBackBufferHeight = 800,
            IsFullScreen              = false,
        };
        Content.RootDirectory = "Content";
        IsMouseVisible = true;
        Window.Title   = "Theriapolis";
        Window.AllowUserResizing = true;
    }

    protected override void Initialize()
    {
        // Initialise Myra before any screen tries to use it
        MyraEnvironment.Game = this;

        Screens = new ScreenManager(this);
        Screens.Push(new TitleScreen());

        base.Initialize();
    }

    protected override void LoadContent()
    {
        _spriteBatch = new SpriteBatch(GraphicsDevice);

        // CodexUI assets + fonts — must load before any CodexScreen is pushed.
        // Fonts live under a sibling directory of Gfx; resolve via the parent.
        CodexAtlas.LoadAll(GraphicsDevice, ContentGfxDirectory);
        string contentRoot = System.IO.Path.GetDirectoryName(ContentGfxDirectory.TrimEnd('/', '\\')) ?? ".";
        CodexFonts.LoadAll(GraphicsDevice, contentRoot);
    }

    protected override void Update(GameTime gameTime)
    {
        // Global ESC from title → exit (ScreenManager handles in-game ESC)
        if (Screens.Current is TitleScreen && Keyboard.GetState().IsKeyDown(Keys.Escape))
            Exit();

        Screens.Update(gameTime);
        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(DevClear);
        Screens.Draw(gameTime, _spriteBatch);
        base.Draw(gameTime);
    }
}
