namespace TD.Core
{
    /// <summary>
    /// How a tower's attack damage is typed. Determines which lingering effect is applied
    /// on hit and how enemy resistances/weaknesses are calculated (Phase 1.5+).
    /// </summary>
    public enum DamageType : byte
    {
        Physical = 0,
        Piercing  = 1,
        Cold      = 2,
        Fire      = 3,
        Poison    = 4,
        Holy      = 5,
        Electric  = 6,
    }

    /// <summary>
    /// How a tower selects which enemy in range to attack.
    /// </summary>
    public enum TargetPriority : byte
    {
        /// <summary>Nearest enemy to the tower's center.</summary>
        Closest   = 0,
        /// <summary>Enemy with the lowest current HP.</summary>
        Weakest   = 1,
        /// <summary>Enemy with the highest current HP.</summary>
        Strongest = 2,
    }

    /// <summary>
    /// How a tower's damage is distributed across enemies.
    /// Orthogonal to <see cref="TowerDefinition.ProjectilePrefab"/>: any target type
    /// can be delivered by a projectile or hitscan.
    /// </summary>
    public enum TargetType : byte
    {
        /// <summary>Hits one enemy for full damage.</summary>
        Single = 0,
        /// <summary>Hits the primary target, then all enemies within SplashRadius.</summary>
        Splash = 1,
        /// <summary>Chains damage to up to ChainCount additional nearby enemies.</summary>
        Chain  = 2,
        /// <summary>Hits EVERY enemy within the tower's Range each attack (e.g. Tesla Coil).
        /// Hitscan only — pairs with a null ProjectilePrefab.</summary>
        AllInRange = 3,
    }


    /// <summary>
    /// Paint color applied to a built tower by the Paint tool. Orthogonal to the owner's
    /// player color: <see cref="None"/> means "unpainted" and the tower shows its owner
    /// color; any other value overrides the visual tint and (in a later iteration) drives
    /// projectile behavior (splash / poison-DoT / slow). Backed by byte for compact
    /// NetworkVariable replication.
    /// </summary>
    public enum PaintColor : byte
    {
        /// <summary>Unpainted — tower shows its owner color. Also the Reset brush.</summary>
        None  = 0,
        Red   = 1,
        Green = 2,
        Blue  = 3,
    }

    /// <summary>
    /// Identifies a player slot in a match. Backed by byte to keep grid arrays compact.
    /// </summary>
    /// <remarks>
    /// <c>None</c> is a sentinel value used in <c>OwnerGrid</c> to mark tiles not owned by any player zone.
    /// Player1..Player9 cover the maximum supported player count. Maps using fewer players use a
    /// contiguous prefix (e.g., a 3-player map uses Player1, Player2, Player3 only).
    /// </remarks>
    /// <summary>
    /// Global phase of a match, driven by <c>MatchState</c>.
    /// </summary>
    /// <remarks>
    /// Transitions are server-authoritative. Clients react to
    /// <c>NetworkVariable&lt;MatchPhase&gt;.OnValueChanged</c>.
    /// </remarks>
    public enum MatchPhase : byte
    {
        /// <summary>Pre-match; players are connecting and the server hasn't started the countdown.</summary>
        Lobby = 0,
        /// <summary>Brief count-down before waves begin. Placement is still allowed.</summary>
        CountDown = 1,
        /// <summary>Waves are in progress; normal gameplay.</summary>
        Playing = 2,
        /// <summary>All waves cleared; co-op win state.</summary>
        Victory = 3,
        /// <summary>All lives lost; co-op defeat state.</summary>
        Defeat = 4,
    }

    /// <summary>
    /// Stable identifier per race. Values 1-16 reserve slots for the planned
    /// 16-race grid in the lobby; only races with a corresponding
    /// <c>RaceDefinition</c> asset registered with <c>RaceRegistry</c> are
    /// playable. Unregistered slots render as "Coming Soon" in the selection UI.
    ///
    /// Names are intentionally generic so display names / lore can be authored
    /// on the asset without renaming the enum — renaming would change byte
    /// values and break save data once persistence lands.
    /// </summary>
    public enum RaceId : byte
    {
        /// <summary>No race selected yet (lobby / pre-pick).</summary>
        None = 0,

        Race1  = 1,  Race2  = 2,  Race3  = 3,  Race4  = 4,
        Race5  = 5,  Race6  = 6,  Race7  = 7,  Race8  = 8,
        Race9  = 9,  Race10 = 10, Race11 = 11, Race12 = 12,
        Race13 = 13, Race14 = 14, Race15 = 15, Race16 = 16,
    }

    public enum PlayerSlot : byte
    {
        None = 0,
        Player1 = 1,
        Player2 = 2,
        Player3 = 3,
        Player4 = 4,
        Player5 = 5,
        Player6 = 6,
        Player7 = 7,
        Player8 = 8,
        Player9 = 9,
    }

    /// <summary>
    /// Whether a volume permits tower placement on the tiles it covers.
    /// </summary>
    /// <remarks>
    /// Defaults: <c>Allowed</c> for <see cref="TD.Levels.PlayerZoneVolume"/>, <c>Invalid</c> for
    /// <see cref="TD.Levels.SpawnerVolume"/>, <see cref="TD.Levels.LeakExitVolume"/>, and
    /// <see cref="TD.Levels.GoalVolume"/>.
    /// Composition rule when volumes overlap: "Invalid wins" — any tile covered by an Invalid volume
    /// becomes <see cref="PlacementState.Restricted"/> regardless of other volumes covering it.
    /// </remarks>
    public enum PlacementValidity
    {
        Invalid = 0,
        Allowed = 1,
    }

    /// <summary>
    /// Cardinal direction for spawner facing. Used by gizmos (direction arrow) and may be used
    /// at runtime to bias initial enemy movement direction out of a spawner.
    /// </summary>
    public enum Direction
    {
        North,
        South,
        East,
        West,
    }

    /// <summary>
    /// Per-tile placement state in the baked <c>PlacementGrid</c>.
    /// </summary>
    /// <remarks>
    /// Backed by byte so default-initialized arrays (all zero) start as <c>Outside</c>, which is
    /// the correct default for any tile not covered by an authoring volume.
    /// </remarks>
    public enum PlacementState : byte
    {
        /// <summary>Tile is not covered by any authoring volume. Towers cannot be placed.</summary>
        Outside = 0,

        /// <summary>Tile is inside a player zone and not covered by any Invalid-validity volume.
        /// Towers can be placed here (subject to runtime checks: ownership, footprint, gold, path).</summary>
        Buildable = 1,

        /// <summary>Tile is covered by at least one Invalid-validity volume (spawner, leak exit, goal).
        /// Towers cannot be placed here. Note: this affects placement only; pathfinding still treats
        /// the tile as walkable.</summary>
        Restricted = 2,
    }

    /// <summary>
    /// Outcome of a bake operation, recorded on the baked <see cref="TD.Levels.LevelData"/> asset.
    /// </summary>
    /// <remarks>
    /// Failure is not represented here because failed bakes do not persist any state to the asset —
    /// the previous successful bake (if any) remains on disk untouched. Failure state lives in
    /// editor-only memory and is not part of the data schema.
    /// </remarks>
    public enum BakeOutcome
    {
        Success,
        SuccessWithWarnings,
    }
}
