import datetime
import uuid

from sqlalchemy import ForeignKey, UniqueConstraint
from sqlalchemy import Enum as SAEnum
from sqlalchemy.orm import Mapped, mapped_column, relationship

from idlemaxx.models.base import IdlemaxBase
from idlemaxx.models.combat import CombatArea, EquipmentSlot, Monster
from idlemaxx.models.items import Item
from idlemaxx.models.utils import now_utc


class CharacterEquipment(IdlemaxBase):
    __tablename__ = "character_equipment"
    character_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("characters.id"))
    slot: Mapped[EquipmentSlot] = mapped_column(SAEnum(EquipmentSlot))
    item: Mapped[Item] = mapped_column(SAEnum(Item))
    quantity: Mapped[int] = mapped_column(default=1)  # >1 only for FOOD slot

    __table_args__ = (UniqueConstraint("character_id", "slot", name="character_id_slot_uc"),)


class CharacterCombatSession(IdlemaxBase):
    __tablename__ = "character_combat_sessions"
    character_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("characters.id"))
    area: Mapped[CombatArea] = mapped_column(SAEnum(CombatArea))
    started_at: Mapped[datetime.datetime] = mapped_column(default_factory=now_utc, init=False)
    ended_at: Mapped[datetime.datetime | None] = mapped_column(default=None, init=False)
    died_at: Mapped[datetime.datetime | None] = mapped_column(default=None, init=False)
    items_recovered: Mapped[bool] = mapped_column(default=False, init=False)

    kills: Mapped[list["CharacterCombatSessionKill"]] = relationship(default_factory=list, cascade="all, delete-orphan")


class CharacterCombatSessionKill(IdlemaxBase):
    __tablename__ = "character_combat_session_kills"
    session_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("character_combat_sessions.id"))
    monster: Mapped[Monster] = mapped_column(SAEnum(Monster))
    xp_attack: Mapped[int]
    xp_strength: Mapped[int]
    xp_hitpoints: Mapped[int]

    loot: Mapped[list["CharacterCombatSessionKillLoot"]] = relationship(
        default_factory=list, cascade="all, delete-orphan"
    )


class CharacterCombatSessionKillLoot(IdlemaxBase):
    __tablename__ = "character_combat_session_kill_loot"
    kill_id: Mapped[uuid.UUID] = mapped_column(ForeignKey("character_combat_session_kills.id"))
    item: Mapped[Item] = mapped_column(SAEnum(Item))
    quantity: Mapped[int]
