"""SQLAlchemy ORM models for users and duties."""

from sqlalchemy import Boolean, ForeignKey, Integer, BigInteger, Text
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, relationship


class Base(DeclarativeBase):
    """Declarative base for all models."""

    pass


class Role(Base):
    """Role for access control: 'user' (miniapp access), 'admin' (admin actions)."""

    __tablename__ = "roles"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    name: Mapped[str] = mapped_column(Text, nullable=False, unique=True)

    users: Mapped[list["User"]] = relationship("User", back_populates="role")


class User(Base):
    """Telegram user and display name; may have telegram_user_id=None for import-only users."""

    __tablename__ = "users"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    telegram_user_id: Mapped[int | None] = mapped_column(
        BigInteger, unique=True, nullable=True
    )
    full_name: Mapped[str] = mapped_column(Text, nullable=False)
    username: Mapped[str | None] = mapped_column(Text, nullable=True)
    first_name: Mapped[str | None] = mapped_column(Text, nullable=True)
    last_name: Mapped[str | None] = mapped_column(Text, nullable=True)
    phone: Mapped[str | None] = mapped_column(Text, nullable=True)
    name_manually_edited: Mapped[bool] = mapped_column(
        Boolean, nullable=False, server_default="0", default=False
    )
    role_id: Mapped[int | None] = mapped_column(
        Integer, ForeignKey("roles.id"), nullable=True
    )

    role: Mapped["Role | None"] = relationship("Role", back_populates="users")
    duties: Mapped[list["Duty"]] = relationship("Duty", back_populates="user")


class CalendarSubscriptionToken(Base):
    """One active calendar subscription token per user; token_hash is unique."""

    __tablename__ = "calendar_subscription_tokens"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    user_id: Mapped[int] = mapped_column(
        Integer, ForeignKey("users.id"), nullable=False
    )
    token_hash: Mapped[str] = mapped_column(Text, nullable=False, unique=True)
    created_at: Mapped[str] = mapped_column(Text, nullable=False)


class Duty(Base):
    """Single duty/unavailable/vacation slot (UTC start_at/end_at, event_type)."""

    __tablename__ = "duties"

    id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
    user_id: Mapped[int] = mapped_column(
        Integer, ForeignKey("users.id"), nullable=False
    )
    # UTC, ISO 8601 with Z suffix (e.g. 2025-01-15T09:00:00Z)
    start_at: Mapped[str] = mapped_column(Text, nullable=False)
    end_at: Mapped[str] = mapped_column(Text, nullable=False)
    # duty | unavailable | vacation
    event_type: Mapped[str] = mapped_column(Text, nullable=False, server_default="duty")

    user: Mapped["User"] = relationship("User", back_populates="duties")


class GroupDutyPin(Base):
    """Stores which message to update in each group for the pinned duty notice."""

    __tablename__ = "group_duty_pins"

    chat_id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
    message_id: Mapped[int] = mapped_column(Integer, nullable=False)


class TrustedGroup(Base):
    """Groups authorized to receive duty information."""

    __tablename__ = "trusted_groups"

    chat_id: Mapped[int] = mapped_column(BigInteger, primary_key=True)
    added_by_user_id: Mapped[int | None] = mapped_column(BigInteger, nullable=True)
    added_at: Mapped[str] = mapped_column(Text, nullable=False)
