"""Corpse — a container left behind when an entity dies."""

from __future__ import annotations

import time
from dataclasses import dataclass

from mudlib.container import Container
from mudlib.entity import Mob
from mudlib.loot import LootEntry, roll_loot
from mudlib.mobs import despawn_mob
from mudlib.zone import Zone

# Module-level registry of active corpses
active_corpses: list[Corpse] = []


@dataclass(eq=False)
class Corpse(Container):
    """A corpse left behind when an entity dies.

    Corpses are containers that hold the deceased entity's inventory.
    They are not portable (can't be picked up) and are always open.
    They have a decompose_at timestamp for eventual cleanup.
    """

    portable: bool = False
    closed: bool = False
    decompose_at: float = 0.0


def create_corpse(
    mob: Mob, zone: Zone, ttl: int = 300, loot_table: list[LootEntry] | None = None
) -> Corpse:
    """Create a corpse from a defeated mob.

    Args:
        mob: The mob that died
        zone: The zone where the corpse will be placed
        ttl: Time to live in seconds (default 300)
        loot_table: Optional loot table to roll for additional items

    Returns:
        The created corpse with the mob's inventory and loot
    """
    # Create corpse at mob's position
    corpse = Corpse(
        name=f"{mob.name}'s corpse",
        location=zone,
        x=mob.x,
        y=mob.y,
        decompose_at=time.monotonic() + ttl,
    )

    # Transfer mob's inventory to corpse
    for item in list(mob._contents):
        item.move_to(corpse)

    # Roll and add loot
    if loot_table:
        for item in roll_loot(loot_table):
            item.move_to(corpse)

    # Remove mob from world
    despawn_mob(mob)

    # Register corpse for decomposition tracking
    active_corpses.append(corpse)

    return corpse


async def process_decomposing() -> None:
    """Remove expired corpses and broadcast decomposition messages."""
    now = time.monotonic()

    for corpse in active_corpses[:]:  # copy to allow modification
        if now >= corpse.decompose_at:
            # Broadcast to entities at the same tile
            zone = corpse.location
            if isinstance(zone, Zone) and corpse.x is not None and corpse.y is not None:
                from mudlib.entity import Entity

                for obj in zone.contents_at(corpse.x, corpse.y):
                    if isinstance(obj, Entity):
                        await obj.send(f"{corpse.name} decomposes.\r\n")

            # Clear contents — items rot with the corpse
            for item in list(corpse._contents):
                item.move_to(None)
            # Remove corpse from world
            corpse.move_to(None)
            active_corpses.remove(corpse)
