from datetime import datetime
from enum import Enum
from sqlalchemy import String, Text, DateTime, ForeignKey, Integer, Boolean
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.core.database import Base


class MarathonStatus(str, Enum):
    PREPARING = "preparing"
    ACTIVE = "active"
    FINISHED = "finished"


class GameProposalMode(str, Enum):
    ALL_PARTICIPANTS = "all_participants"
    ORGANIZER_ONLY = "organizer_only"


class CertificationStatus(str, Enum):
    NONE = "none"
    PENDING = "pending"
    CERTIFIED = "certified"
    REJECTED = "rejected"


class Marathon(Base):
    __tablename__ = "marathons"

    id: Mapped[int] = mapped_column(primary_key=True)
    title: Mapped[str] = mapped_column(String(100), nullable=False)
    description: Mapped[str | None] = mapped_column(Text, nullable=True)
    creator_id: Mapped[int] = mapped_column(ForeignKey("users.id", ondelete="CASCADE"))
    status: Mapped[str] = mapped_column(String(20), default=MarathonStatus.PREPARING.value)
    invite_code: Mapped[str] = mapped_column(String(20), unique=True, nullable=False, index=True)
    is_public: Mapped[bool] = mapped_column(Boolean, default=False)
    game_proposal_mode: Mapped[str] = mapped_column(String(20), default=GameProposalMode.ALL_PARTICIPANTS.value)
    start_date: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
    end_date: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
    auto_events_enabled: Mapped[bool] = mapped_column(Boolean, default=True)
    cover_path: Mapped[str | None] = mapped_column(String(500), nullable=True)
    cover_url: Mapped[str | None] = mapped_column(String(500), nullable=True)
    created_at: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow)

    # Certification fields
    certification_status: Mapped[str] = mapped_column(String(20), default=CertificationStatus.NONE.value)
    certification_requested_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
    certified_at: Mapped[datetime | None] = mapped_column(DateTime, nullable=True)
    certified_by_id: Mapped[int | None] = mapped_column(ForeignKey("users.id", ondelete="SET NULL"), nullable=True)
    certification_rejection_reason: Mapped[str | None] = mapped_column(Text, nullable=True)

    # Shop/Consumables settings
    allow_skips: Mapped[bool] = mapped_column(Boolean, default=True)
    max_skips_per_participant: Mapped[int | None] = mapped_column(Integer, nullable=True)
    allow_consumables: Mapped[bool] = mapped_column(Boolean, default=True)

    # Relationships
    creator: Mapped["User"] = relationship(
        "User",
        back_populates="created_marathons",
        foreign_keys=[creator_id]
    )
    certified_by: Mapped["User | None"] = relationship(
        "User",
        foreign_keys=[certified_by_id]
    )
    participants: Mapped[list["Participant"]] = relationship(
        "Participant",
        back_populates="marathon",
        cascade="all, delete-orphan"
    )
    games: Mapped[list["Game"]] = relationship(
        "Game",
        back_populates="marathon",
        cascade="all, delete-orphan"
    )
    activities: Mapped[list["Activity"]] = relationship(
        "Activity",
        back_populates="marathon",
        cascade="all, delete-orphan"
    )
    events: Mapped[list["Event"]] = relationship(
        "Event",
        back_populates="marathon",
        cascade="all, delete-orphan"
    )

    @property
    def is_certified(self) -> bool:
        return self.certification_status == CertificationStatus.CERTIFIED.value
