from __future__ import annotations

import msgspec

from .spawn_ids import CreatureFlags, CreatureTypeId, SpawnId, Tint


class SpawnTemplate(msgspec.Struct, frozen=True):
    spawn_id: SpawnId
    type_id: CreatureTypeId | None
    flags: CreatureFlags | None
    creature: str | None
    anim_note: str | None
    tint: Tint | None = None
    size: float | None = None
    move_speed: float | None = None


TYPE_ID_TO_NAME = {type_id.value: type_id.name.lower() for type_id in CreatureTypeId}

# For many template ids, tint/size/move_speed are randomized or derived from other fields.
# We only fill them in when the game uses fixed constants (and keep the rest as `None`).
SPAWN_TEMPLATES = [
    SpawnTemplate(
        spawn_id=SpawnId.ZOMBIE_BOSS_SPAWNER_00,
        type_id=CreatureTypeId.ZOMBIE,
        flags=CreatureFlags.ANIM_PING_PONG | CreatureFlags.ANIM_LONG_STRIP,
        creature="zombie",
        anim_note="long strip (0x40 overrides 0x4)",
        tint=(0.6, 0.6, 1.0, 0.8),
        size=64.0,
        move_speed=1.3,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP2_SPLITTER_01,
        type_id=CreatureTypeId.SPIDER_SP2,
        flags=CreatureFlags.SPLIT_ON_DEATH,
        creature="spider_sp2",
        anim_note=None,
        tint=(0.8, 0.7, 0.4, 1.0),
        size=80.0,
        move_speed=2.0,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_RANDOM_03,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=None,
        creature="spider_sp1",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.LIZARD_RANDOM_04,
        type_id=CreatureTypeId.LIZARD,
        flags=None,
        creature="lizard",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP2_RANDOM_05,
        type_id=CreatureTypeId.SPIDER_SP2,
        flags=None,
        creature="spider_sp2",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_RANDOM_06,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_SPAWNER_CHILD_1D_FAST_07,
        type_id=CreatureTypeId.ALIEN,
        flags=CreatureFlags.ANIM_PING_PONG,
        creature="alien",
        anim_note="short strip (ping-pong)",
        tint=(1.0, 1.0, 1.0, 1.0),
        size=50.0,
        move_speed=2.0,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_SPAWNER_CHILD_1D_SLOW_08,
        type_id=CreatureTypeId.ALIEN,
        flags=CreatureFlags.ANIM_PING_PONG,
        creature="alien",
        anim_note="short strip (ping-pong)",
        tint=(1.0, 1.0, 1.0, 1.0),
        size=50.0,
        move_speed=2.0,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_SPAWNER_CHILD_1D_LIMITED_09,
        type_id=CreatureTypeId.ALIEN,
        flags=CreatureFlags.ANIM_PING_PONG,
        creature="alien",
        anim_note="short strip (ping-pong)",
        tint=(1.0, 1.0, 1.0, 1.0),
        size=40.0,
        move_speed=2.0,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_SPAWNER_CHILD_32_SLOW_0A,
        type_id=CreatureTypeId.ALIEN,
        flags=CreatureFlags.ANIM_PING_PONG,
        creature="alien",
        anim_note="short strip (ping-pong)",
        tint=(0.8, 0.7, 0.4, 1.0),
        size=55.0,
        move_speed=1.5,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_SPAWNER_CHILD_3C_SLOW_0B,
        type_id=CreatureTypeId.ALIEN,
        flags=CreatureFlags.ANIM_PING_PONG,
        creature="alien",
        anim_note="short strip (ping-pong)",
        tint=(0.9, 0.1, 0.1, 1.0),
        size=65.0,
        move_speed=1.5,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_SPAWNER_CHILD_31_FAST_0C,
        type_id=CreatureTypeId.ALIEN,
        flags=CreatureFlags.ANIM_PING_PONG,
        creature="alien",
        anim_note="short strip (ping-pong)",
        tint=(0.9, 0.8, 0.4, 1.0),
        size=32.0,
        move_speed=2.8,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_SPAWNER_CHILD_31_SLOW_0D,
        type_id=CreatureTypeId.ALIEN,
        flags=CreatureFlags.ANIM_PING_PONG,
        creature="alien",
        anim_note="short strip (ping-pong)",
        tint=(0.9, 0.8, 0.4, 1.0),
        size=32.0,
        move_speed=1.3,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_SPAWNER_RING_24_0E,
        type_id=CreatureTypeId.ALIEN,
        flags=CreatureFlags.ANIM_PING_PONG,
        creature="alien",
        anim_note="short strip (ping-pong)",
        tint=(0.9, 0.8, 0.4, 1.0),
        size=32.0,
        move_speed=2.8,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_BROWN_TRANSPARENT_0F,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
        tint=(0.665, 0.385, 0.259, 0.56),
        size=50.0,
        move_speed=2.9,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_SPAWNER_CHILD_32_FAST_10,
        type_id=CreatureTypeId.ALIEN,
        flags=CreatureFlags.ANIM_PING_PONG,
        creature="alien",
        anim_note="short strip (ping-pong)",
        tint=(0.9, 0.8, 0.4, 1.0),
        size=32.0,
        move_speed=2.8,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.FORMATION_CHAIN_LIZARD_4_11,
        type_id=CreatureTypeId.LIZARD,
        flags=None,
        creature="lizard",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.FORMATION_RING_ALIEN_8_12,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.FORMATION_CHAIN_ALIEN_10_13,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.FORMATION_GRID_ALIEN_GREEN_14,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.FORMATION_GRID_ALIEN_WHITE_15,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.FORMATION_GRID_LIZARD_WHITE_16,
        type_id=CreatureTypeId.LIZARD,
        flags=None,
        creature="lizard",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.FORMATION_GRID_SPIDER_SP1_WHITE_17,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=None,
        creature="spider_sp1",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.FORMATION_GRID_ALIEN_BRONZE_18,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.FORMATION_RING_ALIEN_5_19,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.AI1_ALIEN_BLUE_TINT_1A,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.AI1_SPIDER_SP1_BLUE_TINT_1B,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=None,
        creature="spider_sp1",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.AI1_LIZARD_BLUE_TINT_1C,
        type_id=CreatureTypeId.LIZARD,
        flags=None,
        creature="lizard",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_RANDOM_1D,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_RANDOM_1E,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_RANDOM_1F,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_RANDOM_GREEN_20,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_PURPLE_GHOST_21,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_GREEN_GHOST_22,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_GREEN_GHOST_SMALL_23,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_GREEN_24,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
        tint=(0.1, 0.7, 0.11, 1.0),
        size=50.0,
        move_speed=2.0,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_GREEN_SMALL_25,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
        tint=(0.1, 0.8, 0.11, 1.0),
        size=30.0,
        move_speed=2.5,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_PALE_GREEN_26,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
        tint=(0.6, 0.8, 0.6, 1.0),
        size=45.0,
        move_speed=2.2,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_WEAPON_BONUS_27,
        type_id=CreatureTypeId.ALIEN,
        flags=CreatureFlags.BONUS_ON_DEATH,
        creature="alien",
        anim_note="bonus_id=WEAPON (3), duration_override=5 (packed in link_index)",
        tint=(1.0, 0.8, 0.1, 1.0),
        size=45.0,
        move_speed=2.1,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_PURPLE_28,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
        tint=(0.7, 0.1, 0.51, 1.0),
        size=55.0,
        move_speed=1.7,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_GREY_BRUTE_29,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
        tint=(0.8, 0.8, 0.8, 1.0),
        size=70.0,
        move_speed=2.5,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_GREY_FAST_2A,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
        tint=(0.3, 0.3, 0.3, 1.0),
        size=60.0,
        move_speed=3.1,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_RED_FAST_2B,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
        tint=(1.0, 0.3, 0.3, 1.0),
        size=35.0,
        move_speed=3.6,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_RED_BOSS_2C,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
        tint=(0.85, 0.2, 0.2, 1.0),
        size=80.0,
        move_speed=2.0,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_CONST_CYAN_AI2_2D,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
        tint=(0.0, 0.9, 0.8, 1.0),
        size=38.0,
        move_speed=3.1,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.LIZARD_RANDOM_2E,
        type_id=CreatureTypeId.LIZARD,
        flags=None,
        creature="lizard",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.LIZARD_CONST_GREY_2F,
        type_id=CreatureTypeId.LIZARD,
        flags=None,
        creature="lizard",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.LIZARD_CONST_YELLOW_BOSS_30,
        type_id=CreatureTypeId.LIZARD,
        flags=None,
        creature="lizard",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.LIZARD_RANDOM_31,
        type_id=CreatureTypeId.LIZARD,
        flags=None,
        creature="lizard",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_RANDOM_32,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=None,
        creature="spider_sp1",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_RANDOM_RED_33,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=None,
        creature="spider_sp1",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_RANDOM_GREEN_34,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=None,
        creature="spider_sp1",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP2_RANDOM_35,
        type_id=CreatureTypeId.SPIDER_SP2,
        flags=None,
        creature="spider_sp2",
        anim_note=None,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ALIEN_AI7_ORBITER_36,
        type_id=CreatureTypeId.ALIEN,
        flags=None,
        creature="alien",
        anim_note=None,
        tint=(0.65, None, 0.95, 1.0),
        size=50.0,
        move_speed=1.8,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP2_RANGED_VARIANT_37,
        type_id=CreatureTypeId.SPIDER_SP2,
        flags=CreatureFlags.RANGED_ATTACK_VARIANT,
        creature="spider_sp2",
        anim_note=None,
        tint=(1.0, 0.75, 0.1, 1.0),
        move_speed=3.2,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_AI7_TIMER_38,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=CreatureFlags.AI7_LINK_TIMER,
        creature="spider_sp1",
        anim_note=None,
        tint=(1.0, 0.75, 0.1, 1.0),
        move_speed=4.8,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_AI7_TIMER_WEAK_39,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=CreatureFlags.AI7_LINK_TIMER,
        creature="spider_sp1",
        anim_note=None,
        tint=(0.8, 0.65, 0.1, 1.0),
        move_speed=4.8,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_CONST_SHOCK_BOSS_3A,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=CreatureFlags.RANGED_ATTACK_SHOCK,
        creature="spider_sp1",
        anim_note="projectile_type=9",
        tint=(1.0, 1.0, 1.0, 1.0),
        size=64.0,
        move_speed=2.0,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_CONST_RED_BOSS_3B,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=None,
        creature="spider_sp1",
        anim_note=None,
        tint=(0.9, 0.0, 0.0, 1.0),
        size=70.0,
        move_speed=2.0,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_CONST_RANGED_VARIANT_3C,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=CreatureFlags.RANGED_ATTACK_VARIANT,
        creature="spider_sp1",
        anim_note="projectile_type=26 (packed in orbit_radius)",
        tint=(0.9, 0.1, 0.1, 1.0),
        size=40.0,
        move_speed=2.0,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_RANDOM_3D,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=None,
        creature="spider_sp1",
        anim_note=None,
        tint=(None, None, None, 1.0),
        move_speed=2.6,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_CONST_WHITE_FAST_3E,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=None,
        creature="spider_sp1",
        anim_note=None,
        tint=(1.0, 1.0, 1.0, 1.0),
        size=64.0,
        move_speed=2.8,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_CONST_BROWN_SMALL_3F,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=None,
        creature="spider_sp1",
        anim_note=None,
        tint=(0.7, 0.4, 0.1, 1.0),
        size=35.0,
        move_speed=2.3,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.SPIDER_SP1_CONST_BLUE_40,
        type_id=CreatureTypeId.SPIDER_SP1,
        flags=None,
        creature="spider_sp1",
        anim_note=None,
        tint=(0.5, 0.6, 0.9, 1.0),
        size=45.0,
        move_speed=2.2,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ZOMBIE_RANDOM_41,
        type_id=CreatureTypeId.ZOMBIE,
        flags=None,
        creature="zombie",
        anim_note=None,
        tint=(None, None, None, 1.0),
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ZOMBIE_CONST_GREY_42,
        type_id=CreatureTypeId.ZOMBIE,
        flags=None,
        creature="zombie",
        anim_note=None,
        tint=(0.9, 0.9, 0.9, 1.0),
        size=45.0,
        move_speed=1.7,
    ),
    SpawnTemplate(
        spawn_id=SpawnId.ZOMBIE_CONST_GREEN_BRUTE_43,
        type_id=CreatureTypeId.ZOMBIE,
        flags=None,
        creature="zombie",
        anim_note=None,
        tint=(0.2, 0.6, 0.1, 1.0),
        size=70.0,
        move_speed=2.1,
    ),
]

SPAWN_ID_TO_TEMPLATE = {entry.spawn_id: entry for entry in SPAWN_TEMPLATES}

