using Godot;
using Theriapolis.Core;
using Theriapolis.Core.Tactical;

namespace Theriapolis.GodotHost.Rendering;

/// <summary>
/// One Node2D per tactical chunk. Positioned at (chunk.OriginX, chunk.OriginY)
/// in world-pixel space; renders all CHUNK_SIZE x CHUNK_SIZE tiles via _Draw.
///
/// Godot caches CanvasItem _Draw output, so _Draw runs once on first paint
/// and the rasterised result is reused every frame thereafter. We only call
/// QueueRedraw() if the chunk's delta changes (M4 doesn't yet — chunks are
/// static once generated).
///
/// Each tactical tile is 1 world pixel wide; the source sprite is
/// TACTICAL_TILE_SPRITE_PX² and gets squashed into that 1×1 cell via
/// DrawTextureRect's destination rect. The camera's zoom (32x for tactical
/// view) magnifies the rasterisation back to native sprite resolution.
/// </summary>
public partial class TacticalChunkNode : Node2D
{
    private TacticalChunk? _chunk;

    public void Bind(TacticalChunk chunk)
    {
        _chunk = chunk;
        Position = new Vector2(chunk.OriginX, chunk.OriginY);
        QueueRedraw();
    }

    public override void _Draw()
    {
        if (_chunk is null) return;

        int size = C.TACTICAL_CHUNK_SIZE;

        // Pass 1: surfaces.
        for (int ly = 0; ly < size; ly++)
        for (int lx = 0; lx < size; lx++)
        {
            ref var t = ref _chunk.Tiles[lx, ly];
            var tex = TacticalAtlas.GetSurface(t.Surface, t.Variant);
            DrawTextureRect(tex, new Rect2(lx, ly, 1, 1), false);
        }

        // Pass 2: decos on top.
        for (int ly = 0; ly < size; ly++)
        for (int lx = 0; lx < size; lx++)
        {
            ref var t = ref _chunk.Tiles[lx, ly];
            var tex = TacticalAtlas.GetDeco(t.Deco, t.Variant);
            if (tex is null) continue;
            DrawTextureRect(tex, new Rect2(lx, ly, 1, 1), false);
        }
    }
}
