namespace Theriapolis.Core.Tactical;

/// <summary>
/// Tactical-scale ground class. One tile = 1 world pixel.
/// Phase 4 keeps this enum tight; richer typing (subtypes per biome, special
/// surface effects) lands in later phases when art shows up.
/// </summary>
public enum TacticalSurface : byte
{
    None = 0,
    Grass,
    TallGrass,
    Dirt,
    Sand,
    Mud,
    Snow,
    Rock,
    Cobble,        // city plaza / highway / post road
    Gravel,        // footpath
    TroddenDirt,   // dirt road — visually distinct from wild Dirt biome ground
    ShallowWater,  // wadeable
    DeepWater,     // impassable
    Marsh,
    Floor,         // building interior placeholder
    Wall,          // building wall (impassable)
    // ── Phase 7 M1: dungeon surfaces ─────────────────────────────────────
    // Distinct from settlement Floor / Wall so the renderer can pick the
    // right tile-art family per dungeon type, and so the savegame can tell
    // a building floor apart from a dungeon floor when (eventually) building
    // deltas and dungeon state share a chunk-coord namespace.
    DungeonFloor,   // generic dungeon-interior floor (Imperium / general)
    DungeonRubble,  // damaged / collapsed floor — slows movement
    DungeonTile,    // mosaic / inlay floor (narrative rooms)
    Cave,           // natural-cave floor (Cult Den / Natural Cave dungeon types)
    MineFloor,      // worked tunnel floor (Abandoned Mine)
}

/// <summary>
/// Decoration on top of the ground (rendered above surface, may affect walkability).
/// </summary>
public enum TacticalDeco : byte
{
    None = 0,
    Tree,
    Bush,        // slows but does not block
    Rock,        // small — does not block
    Boulder,     // blocks
    Flower,
    Crop,
    Reed,
    Snag,
    // Phase 6 M0 — interior decorations stamped by SettlementStamper.
    Door     = 16,   // walkable, marks a building entrance
    Counter,         // shop / inn furniture, blocks movement
    Bed,             // furniture, blocks
    Hearth,          // furniture, blocks
    Sign,            // outdoor signpost, blocks (one tile)
    // ── Phase 7 M1: dungeon decorations ─────────────────────────────────
    // Stairs is the PoI-entrance interaction tile on the surface chunk
    // *and* the dungeon-exit interaction tile inside a dungeon. The
    // PlayScreen tells them apart by the active scene (chunk vs dungeon).
    Stairs    = 32,  // walkable; player E to enter / exit
    DungeonDoor,     // walkable when open; lockable per RoomDoor
    Container,       // chest / sarcophagus / locked box (loot)
    Trap,            // tripwire (Phase 7 only ships this kind)
    Brazier,         // light source furniture, blocks
    Pillar,          // structural pillar, blocks
    ImperiumStatue,  // Imperium-themed deco, blocks (cover; flavour)
}

/// <summary>
/// Per-tactical-tile data. 16 bytes (well below the 64-byte cache line) so a
/// 64×64 chunk fits comfortably in L1.
/// </summary>
public struct TacticalTile
{
    public TacticalSurface Surface;
    public TacticalDeco    Deco;
    public byte            Variant;       // small RNG nibble for visual variation
    public byte            Flags;         // packed bool flags, see TacticalFlags

    public bool IsWalkable
    {
        get
        {
            if ((Flags & (byte)TacticalFlags.Impassable) != 0) return false;
            return Surface switch
            {
                TacticalSurface.Wall        => false,
                TacticalSurface.DeepWater   => false,
                _                            => true,
            }
            && Deco != TacticalDeco.Tree && Deco != TacticalDeco.Boulder
            && Deco != TacticalDeco.Counter && Deco != TacticalDeco.Bed
            && Deco != TacticalDeco.Hearth  && Deco != TacticalDeco.Sign
            // Phase 7 M1 — dungeon decos that block movement.
            && Deco != TacticalDeco.Brazier && Deco != TacticalDeco.Pillar
            && Deco != TacticalDeco.ImperiumStatue && Deco != TacticalDeco.Container;
        }
    }

    public bool SlowsMovement
        => (Flags & (byte)TacticalFlags.Slow) != 0
        || Deco == TacticalDeco.Bush
        || Surface == TacticalSurface.ShallowWater
        || Surface == TacticalSurface.Marsh
        || Surface == TacticalSurface.Mud
        // Phase 7 M1 — dungeon rubble slows movement.
        || Surface == TacticalSurface.DungeonRubble;
}

[Flags]
public enum TacticalFlags : byte
{
    None        = 0,
    Impassable  = 1 << 0,
    Slow        = 1 << 1,
    Bridge      = 1 << 2, // walkable even though water is below
    River       = 1 << 3, // burned in by a river polyline
    Road        = 1 << 4, // burned in by a road polyline
    Settlement  = 1 << 5, // inside a settlement footprint
    // Phase 6 M0 — building structure flags. Interior is derived
    // (Settlement && Building && Surface==Floor) so we don't waste a bit.
    Building    = 1 << 6, // building wall or floor (subset of Settlement)
    Doorway     = 1 << 7, // walkable building entrance (subset of Building)
}
