"""General Affairs models — JadwalShift and Absensi."""

from datetime import date, datetime

from sqlalchemy import Date, DateTime, ForeignKey, String, Text, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.models.base import Base, TimestampMixin, SoftDeleteMixin


class JadwalShift(Base, TimestampMixin, SoftDeleteMixin):
    __tablename__ = "jadwal_shift"
    __table_args__ = (
        UniqueConstraint("spbu_id", "user_id", "shift_id", "tanggal", name="uq_jadwal_shift"),
    )

    id: Mapped[int] = mapped_column(primary_key=True)
    spbu_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu.id", ondelete="CASCADE"), index=True
    )
    user_id: Mapped[int] = mapped_column(
        ForeignKey("master_user.id", ondelete="CASCADE")
    )
    shift_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu_shift.id", ondelete="CASCADE")
    )
    tanggal: Mapped[date] = mapped_column(Date)
    created_by_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_user.id", ondelete="SET NULL"), nullable=True
    )

    spbu: Mapped["Spbu"] = relationship(foreign_keys=[spbu_id])
    user: Mapped["User"] = relationship(foreign_keys=[user_id])
    shift: Mapped["Shift"] = relationship()
    created_by: Mapped["User | None"] = relationship(foreign_keys=[created_by_id])


class Absensi(Base, TimestampMixin):
    __tablename__ = "absensi"
    __table_args__ = (
        UniqueConstraint("spbu_id", "shift_id", "tanggal", name="uq_absensi"),
    )

    id: Mapped[int] = mapped_column(primary_key=True)
    spbu_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu.id", ondelete="CASCADE"), index=True
    )
    shift_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu_shift.id", ondelete="CASCADE")
    )
    tanggal: Mapped[date] = mapped_column(Date)
    foto_url: Mapped[str | None] = mapped_column(String(500), nullable=True)
    foto_eksif_waktu: Mapped[str | None] = mapped_column(String(50), nullable=True)
    uploaded_by_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_user.id", ondelete="SET NULL"), nullable=True
    )
    uploaded_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    status: Mapped[str] = mapped_column(String(20), default="pending")
    reviewed_by_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_user.id", ondelete="SET NULL"), nullable=True
    )
    reviewed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)

    spbu: Mapped["Spbu"] = relationship(foreign_keys=[spbu_id])
    shift: Mapped["Shift"] = relationship()
    uploaded_by: Mapped["User | None"] = relationship(foreign_keys=[uploaded_by_id])
    reviewed_by: Mapped["User | None"] = relationship(foreign_keys=[reviewed_by_id])


class Housekeeping(Base, TimestampMixin):
    __tablename__ = "housekeeping"
    __table_args__ = (
        UniqueConstraint("spbu_id", "tanggal", name="uq_housekeeping_tanggal"),
    )

    id: Mapped[int] = mapped_column(primary_key=True)
    spbu_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu.id", ondelete="CASCADE"), index=True
    )
    shift_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_spbu_shift.id", ondelete="SET NULL"), nullable=True
    )
    tanggal: Mapped[date] = mapped_column(Date)
    status: Mapped[str] = mapped_column(String(20), default="pending")
    uploaded_by_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_user.id", ondelete="SET NULL"), nullable=True
    )
    uploaded_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    reviewed_by_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_user.id", ondelete="SET NULL"), nullable=True
    )
    reviewed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)

    items: Mapped[list["HousekeepingItem"]] = relationship(
        back_populates="housekeeping", cascade="all, delete-orphan", order_by="HousekeepingItem.urutan"
    )
    fotos: Mapped[list["HousekeepingFoto"]] = relationship(
        back_populates="housekeeping", cascade="all, delete-orphan", order_by="HousekeepingFoto.urutan"
    )
    uploaded_by: Mapped["User | None"] = relationship(foreign_keys=[uploaded_by_id])
    reviewed_by: Mapped["User | None"] = relationship(foreign_keys=[reviewed_by_id])


class HousekeepingItem(Base):
    __tablename__ = "housekeeping_item"

    id: Mapped[int] = mapped_column(primary_key=True)
    housekeeping_id: Mapped[int] = mapped_column(
        ForeignKey("housekeeping.id", ondelete="CASCADE"), index=True
    )
    deskripsi: Mapped[str] = mapped_column(String(1000))
    urutan: Mapped[int] = mapped_column(default=0)

    housekeeping: Mapped["Housekeeping"] = relationship(back_populates="items")


class HousekeepingFoto(Base):
    __tablename__ = "housekeeping_foto"

    id: Mapped[int] = mapped_column(primary_key=True)
    housekeeping_id: Mapped[int] = mapped_column(
        ForeignKey("housekeeping.id", ondelete="CASCADE"), index=True
    )
    tipe: Mapped[str] = mapped_column(String(10), default="foto")  # 'foto'
    foto_url: Mapped[str] = mapped_column(String(500))
    urutan: Mapped[int] = mapped_column(default=0)

    housekeeping: Mapped["Housekeeping"] = relationship(back_populates="fotos")


class Sapras(Base, TimestampMixin):
    __tablename__ = "sapras"
    __table_args__ = (
        UniqueConstraint("spbu_id", "tanggal", name="uq_sapras_tanggal"),
    )

    id: Mapped[int] = mapped_column(primary_key=True)
    spbu_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu.id", ondelete="CASCADE"), index=True
    )
    tanggal: Mapped[date] = mapped_column(Date)
    catatan: Mapped[str | None] = mapped_column(Text, nullable=True)
    status: Mapped[str] = mapped_column(String(20), default="pending")
    uploaded_by_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_user.id", ondelete="SET NULL"), nullable=True
    )
    uploaded_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    reviewed_by_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_user.id", ondelete="SET NULL"), nullable=True
    )
    reviewed_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)

    items: Mapped[list["SaprasItem"]] = relationship(
        back_populates="sapras", cascade="all, delete-orphan", order_by="SaprasItem.urutan"
    )
    uploaded_by: Mapped["User | None"] = relationship(foreign_keys=[uploaded_by_id])
    reviewed_by: Mapped["User | None"] = relationship(foreign_keys=[reviewed_by_id])


class SaprasItem(Base):
    __tablename__ = "sapras_item"

    id: Mapped[int] = mapped_column(primary_key=True)
    sapras_id: Mapped[int] = mapped_column(
        ForeignKey("sapras.id", ondelete="CASCADE"), index=True
    )
    kegiatan: Mapped[str] = mapped_column(String(1000))
    foto_sebelum_url: Mapped[str | None] = mapped_column(String(500), nullable=True)
    foto_sesudah_url: Mapped[str | None] = mapped_column(String(500), nullable=True)
    urutan: Mapped[int] = mapped_column(default=0)

    sapras: Mapped["Sapras"] = relationship(back_populates="items")


from app.models.user import User  # noqa: E402, F401
from app.models.spbu import Spbu, Shift  # noqa: E402, F401
