from datetime import date, time
from decimal import Decimal

from sqlalchemy import Boolean, Date, ForeignKey, Integer, Numeric, String, Text, Time
from sqlalchemy.orm import Mapped, mapped_column, relationship

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


class Spbu(Base, TimestampMixin, SoftDeleteMixin):
    __tablename__ = "master_spbu"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(255))
    nomor_pertamina: Mapped[str] = mapped_column(String(50), unique=True, index=True)
    kode_internal: Mapped[str | None] = mapped_column(String(50), nullable=True)
    alamat: Mapped[str | None] = mapped_column(Text, nullable=True)
    no_telepon: Mapped[str | None] = mapped_column(String(30), nullable=True)
    nama_bank: Mapped[str | None] = mapped_column(String(100), nullable=True)
    no_rekening: Mapped[str | None] = mapped_column(String(50), nullable=True)
    atas_nama: Mapped[str | None] = mapped_column(String(255), nullable=True)
    # Threshold: % discrepancy between manual and digital teller readings
    teller_discrepancy_threshold_pct: Mapped[Decimal] = mapped_column(
        Numeric(6, 3), default=Decimal("0.300")
    )
    is_active: Mapped[bool] = mapped_column(Boolean, default=True)

    shifts: Mapped[list["Shift"]] = relationship(
        back_populates="spbu", cascade="all, delete-orphan"
    )
    islands: Mapped[list["Island"]] = relationship(
        back_populates="spbu", cascade="all, delete-orphan"
    )
    tangkis: Mapped[list["Tangki"]] = relationship(
        back_populates="spbu", cascade="all, delete-orphan"
    )
    assignments: Mapped[list["UserSpbuAssignment"]] = relationship(
        back_populates="spbu", cascade="all, delete-orphan"
    )


class Shift(Base, TimestampMixin, SoftDeleteMixin):
    __tablename__ = "master_spbu_shift"

    id: Mapped[int] = mapped_column(primary_key=True)
    spbu_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu.id", ondelete="CASCADE"), index=True
    )
    nama: Mapped[str] = mapped_column(String(100))
    jam_mulai: Mapped[time] = mapped_column(Time)
    jam_selesai: Mapped[time] = mapped_column(Time)
    is_active: Mapped[bool] = mapped_column(Boolean, default=True)

    spbu: Mapped["Spbu"] = relationship(back_populates="shifts")


class Island(Base, TimestampMixin, SoftDeleteMixin):
    __tablename__ = "master_spbu_island"

    id: Mapped[int] = mapped_column(primary_key=True)
    spbu_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu.id", ondelete="CASCADE"), index=True
    )
    nama: Mapped[str] = mapped_column(String(100))
    urutan: Mapped[int] = mapped_column(Integer, default=1)
    is_active: Mapped[bool] = mapped_column(Boolean, default=True)

    spbu: Mapped["Spbu"] = relationship(back_populates="islands")
    nozzles: Mapped[list["Nozzle"]] = relationship(
        back_populates="island", cascade="all, delete-orphan"
    )


class Nozzle(Base, TimestampMixin, SoftDeleteMixin):
    __tablename__ = "master_spbu_nozzle"

    id: Mapped[int] = mapped_column(primary_key=True)
    island_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu_island.id", ondelete="CASCADE"), index=True
    )
    nama: Mapped[str] = mapped_column(String(50))
    produk_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_produk.id", ondelete="SET NULL"), nullable=True
    )
    tangki_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_spbu_tangki.id", ondelete="SET NULL"), nullable=True
    )
    # Which teller is primary for volume calculation ('manual' or 'digital')
    primary_teller: Mapped[str] = mapped_column(String(10), default="manual", nullable=False)
    is_active: Mapped[bool] = mapped_column(Boolean, default=True)

    island: Mapped["Island"] = relationship(back_populates="nozzles")
    produk: Mapped["Produk | None"] = relationship()
    tangki: Mapped["Tangki | None"] = relationship(back_populates="nozzles")


class Tangki(Base, TimestampMixin, SoftDeleteMixin):
    __tablename__ = "master_spbu_tangki"

    id: Mapped[int] = mapped_column(primary_key=True)
    spbu_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu.id", ondelete="CASCADE"), index=True
    )
    nama: Mapped[str] = mapped_column(String(100))
    kode_kalibrasi: Mapped[str | None] = mapped_column(String(50), nullable=True)
    kapasitas_liter: Mapped[Decimal] = mapped_column(Numeric(15, 3))
    produk_id: Mapped[int | None] = mapped_column(
        ForeignKey("master_produk.id", ondelete="SET NULL"), nullable=True
    )
    is_active: Mapped[bool] = mapped_column(Boolean, default=True)

    spbu: Mapped["Spbu"] = relationship(back_populates="tangkis")
    produk: Mapped["Produk | None"] = relationship()
    kalibrasi: Mapped[list["KalibrasiTangki"]] = relationship(
        back_populates="tangki", cascade="all, delete-orphan", order_by="KalibrasiTangki.tinggi_mm"
    )
    nozzles: Mapped[list["Nozzle"]] = relationship(back_populates="tangki")


class KalibrasiTangki(Base):
    __tablename__ = "master_spbu_kalibrasi"

    id: Mapped[int] = mapped_column(primary_key=True)
    tangki_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu_tangki.id", ondelete="CASCADE"), index=True
    )
    tinggi_mm: Mapped[Decimal] = mapped_column(Numeric(10, 1))
    volume_liter: Mapped[Decimal] = mapped_column(Numeric(15, 3))

    tangki: Mapped["Tangki"] = relationship(back_populates="kalibrasi")


class Tenant(Base, TimestampMixin, SoftDeleteMixin):
    __tablename__ = "master_spbu_tenant"

    id: Mapped[int] = mapped_column(primary_key=True)
    spbu_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu.id", ondelete="CASCADE"), index=True
    )
    nama: Mapped[str] = mapped_column(String(255))
    jenis_usaha: Mapped[str | None] = mapped_column(String(100), nullable=True)
    luas_m2: Mapped[Decimal | None] = mapped_column(Numeric(10, 2), nullable=True)
    kontak: Mapped[str | None] = mapped_column(String(255), nullable=True)
    is_active: Mapped[bool] = mapped_column(Boolean, default=True)

    kontrak: Mapped[list["KontrakSewa"]] = relationship(
        back_populates="tenant", cascade="all, delete-orphan"
    )


class KontrakSewa(Base, TimestampMixin, SoftDeleteMixin):
    __tablename__ = "master_spbu_kontrak"

    id: Mapped[int] = mapped_column(primary_key=True)
    tenant_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu_tenant.id", ondelete="CASCADE"), index=True
    )
    nilai_bulanan: Mapped[Decimal] = mapped_column(Numeric(15, 3))
    tanggal_mulai: Mapped[date] = mapped_column(Date)
    tanggal_akhir: Mapped[date] = mapped_column(Date)
    status: Mapped[str] = mapped_column(String(20), default="active")
    dokumen_url: Mapped[str | None] = mapped_column(Text, nullable=True)

    tenant: Mapped["Tenant"] = relationship(back_populates="kontrak")


from app.models.product import Produk  # noqa: E402, F401
from app.models.role import UserSpbuAssignment  # noqa: E402, F401
