"""Penerimaan models — BBM receipt from Pertamina truck."""

import enum
from datetime import date, datetime, time
from decimal import Decimal

from sqlalchemy import (
    Date,
    DateTime,
    ForeignKey,
    Index,
    Numeric,
    String,
    Text,
    Time,
)
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.models.base import Base, TimestampMixin


class TipeFotoEnum(str, enum.Enum):
    truck = "truck"
    stick_t3 = "stick_t3"
    compartment_buka = "compartment_buka"
    compartment_kosong = "compartment_kosong"
    surat_jalan = "surat_jalan"
    stick_awal = "stick_awal"
    stick_akhir = "stick_akhir"
    dipstick_sebelum = "dipstick_sebelum"
    dipstick_sesudah = "dipstick_sesudah"
    atg_sebelum = "atg_sebelum"
    atg_sesudah = "atg_sesudah"


class StatusPenerimaan(str, enum.Enum):
    DRAFT = "draft"
    SUBMITTED = "submitted"
    APPROVED = "approved"
    REJECTED = "rejected"


class Penerimaan(Base, TimestampMixin):
    """One BBM receipt event — truck arrives, BBM pumped into underground tanks."""

    __tablename__ = "penerimaan"

    __table_args__ = (
        Index("ix_penerimaan_spbu_tanggal", "spbu_id", "tanggal"),
        Index("ix_penerimaan_penebusan_id", "penebusan_id"),
    )

    id: Mapped[int] = mapped_column(primary_key=True)
    spbu_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu.id", ondelete="CASCADE"), nullable=False, index=True
    )
    penebusan_id: Mapped[int] = mapped_column(
        ForeignKey("penebusan.id", ondelete="RESTRICT"), nullable=False
    )

    # Truck / delivery info (from Surat Pengantar Pertamina)
    tanggal: Mapped[date] = mapped_column(Date, nullable=False)
    tgl_jam_keluar_terminal: Mapped[datetime | None] = mapped_column(
        DateTime(timezone=True), nullable=True
    )
    jam_tiba: Mapped[time | None] = mapped_column(Time, nullable=True)
    jam_berangkat: Mapped[time | None] = mapped_column(Time, nullable=True)
    no_polisi: Mapped[str | None] = mapped_column(String(20), nullable=True)
    shipment_no: Mapped[str | None] = mapped_column(String(50), nullable=True)
    nama_pengemudi: Mapped[str | None] = mapped_column(Text, nullable=True)
    no_lo: Mapped[str | None] = mapped_column(String(100), nullable=True)

    # Density & Temperature
    density_obs: Mapped[Decimal | None] = mapped_column(Numeric(8, 4), nullable=True)
    temp_obs: Mapped[Decimal | None] = mapped_column(Numeric(6, 2), nullable=True)
    density_ons: Mapped[Decimal | None] = mapped_column(Numeric(8, 4), nullable=True)
    temp_ons: Mapped[Decimal | None] = mapped_column(Numeric(6, 2), nullable=True)

    catatan: Mapped[str | None] = mapped_column(Text, nullable=True)

    created_by_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_user.id", ondelete="SET NULL"), nullable=True
    )

    # Approval flow fields
    status: Mapped[str] = mapped_column(String(20), nullable=False, default=StatusPenerimaan.DRAFT)
    submitted_by_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_user.id", ondelete="SET NULL"), nullable=True
    )
    submitted_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)
    catatan_review: Mapped[str | None] = mapped_column(Text, nullable=True)
    unlocked_by_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_user.id", ondelete="SET NULL"), nullable=True
    )
    unlocked_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
    unlock_reason: Mapped[str | None] = mapped_column(Text, nullable=True)

    # Relationships
    penebusan: Mapped["Penebusan"] = relationship(foreign_keys=[penebusan_id])
    created_by: Mapped["User | None"] = relationship(foreign_keys=[created_by_id])
    submitted_by: Mapped["User | None"] = relationship(foreign_keys=[submitted_by_id])
    reviewed_by: Mapped["User | None"] = relationship(foreign_keys=[reviewed_by_id])
    unlocked_by: Mapped["User | None"] = relationship(foreign_keys=[unlocked_by_id])
    items: Mapped[list["PenerimaanItem"]] = relationship(
        back_populates="penerimaan", cascade="all, delete-orphan"
    )
    fotos: Mapped[list["PenerimaanFoto"]] = relationship(
        back_populates="penerimaan", cascade="all, delete-orphan"
    )


class PenerimaanItem(Base):
    """One product/tangki line within a Penerimaan (one per truck compartment unloaded to one tank)."""

    __tablename__ = "penerimaan_item"

    __table_args__ = (
        Index("ix_penerimaan_item_penerimaan_id", "penerimaan_id"),
    )

    id: Mapped[int] = mapped_column(primary_key=True)
    penerimaan_id: Mapped[int] = mapped_column(
        ForeignKey("penerimaan.id", ondelete="CASCADE"), nullable=False
    )
    penebusan_item_id: Mapped[int | None] = mapped_column(
        ForeignKey("penebusan_item.id", ondelete="SET NULL"), nullable=True
    )
    produk_id: Mapped[int] = mapped_column(
        ForeignKey("master_produk.id", ondelete="RESTRICT"), nullable=False
    )
    tangki_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu_tangki.id", ondelete="RESTRICT"), nullable=False
    )

    dipstick_sebelum_mm: Mapped[Decimal] = mapped_column(Numeric(10, 1), nullable=False)
    volume_sebelum: Mapped[Decimal] = mapped_column(Numeric(15, 3), nullable=False)
    dipstick_sesudah_mm: Mapped[Decimal] = mapped_column(Numeric(10, 1), nullable=False)
    volume_sesudah: Mapped[Decimal] = mapped_column(Numeric(15, 3), nullable=False)
    volume_diterima: Mapped[Decimal] = mapped_column(Numeric(15, 3), nullable=False)
    atg_sebelum_mm: Mapped[Decimal | None] = mapped_column(Numeric(10, 1), nullable=True)
    atg_sesudah_mm: Mapped[Decimal | None] = mapped_column(Numeric(10, 1), nullable=True)

    # Relationships
    penerimaan: Mapped["Penerimaan"] = relationship(back_populates="items")
    penebusan_item: Mapped["PenebusanItem | None"] = relationship(foreign_keys=[penebusan_item_id])
    produk: Mapped["Produk"] = relationship(foreign_keys=[produk_id])
    tangki: Mapped["Tangki"] = relationship(foreign_keys=[tangki_id])
    fotos: Mapped[list["PenerimaanFoto"]] = relationship(
        back_populates="item",
        primaryjoin="PenerimaanFoto.penerimaan_item_id == PenerimaanItem.id",
        cascade="all, delete-orphan",
    )


class PenerimaanFoto(Base):
    """Photo attached to a Penerimaan (general or per-item)."""

    __tablename__ = "penerimaan_foto"

    __table_args__ = (
        Index("ix_penerimaan_foto_penerimaan_id", "penerimaan_id"),
    )

    id: Mapped[int] = mapped_column(primary_key=True)
    penerimaan_id: Mapped[int] = mapped_column(
        ForeignKey("penerimaan.id", ondelete="CASCADE"), nullable=False
    )
    penerimaan_item_id: Mapped[int | None] = mapped_column(
        ForeignKey("penerimaan_item.id", ondelete="CASCADE"), nullable=True
    )
    tipe: Mapped[str] = mapped_column(String(30), nullable=False)
    url: Mapped[str] = mapped_column(String(500), nullable=False)
    created_at: Mapped[datetime] = mapped_column(
        DateTime(timezone=True), server_default="now()", nullable=False
    )

    # Relationships
    penerimaan: Mapped["Penerimaan"] = relationship(
        back_populates="fotos",
        foreign_keys=[penerimaan_id],
    )
    item: Mapped["PenerimaanItem | None"] = relationship(
        back_populates="fotos",
        foreign_keys=[penerimaan_item_id],
    )


# Avoid circular imports
from app.models.penebusan import Penebusan, PenebusanItem  # noqa: E402, F401
from app.models.product import Produk  # noqa: E402, F401
from app.models.spbu import Tangki  # noqa: E402, F401
from app.models.user import User  # noqa: E402, F401
