"""Rekonsiliasi Harian model — daily sounding-based stock reconciliation per tank."""

from __future__ import annotations

import enum
from datetime import date
from decimal import Decimal
from typing import TYPE_CHECKING

from sqlalchemy import Date, ForeignKey, Index, Numeric, String, UniqueConstraint
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.models.base import Base, TimestampMixin

if TYPE_CHECKING:
    from app.models.spbu import Tangki
    from app.models.user import User


class StatusRekonsiliasi(str, enum.Enum):
    PENDING = "pending"
    BALANCED = "balanced"
    APPROVED = "approved"


class RekonsiliasiHarian(Base, TimestampMixin):
    """One reconciliation record per SPBU per day.

    Contains per-tank breakdown via RekonsiliasiTangki children.
    Can only be run when all shifts for the day have been submitted.
    """

    __tablename__ = "rekonsiliasi_harian"

    __table_args__ = (
        UniqueConstraint("spbu_id", "tanggal", name="uq_rekonsiliasi_spbu_tanggal"),
        Index("ix_rekonsiliasi_spbu_id", "spbu_id"),
    )

    id: Mapped[int] = mapped_column(primary_key=True)
    spbu_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu.id", ondelete="CASCADE"), nullable=False
    )
    tanggal: Mapped[date] = mapped_column(Date, nullable=False)
    status: Mapped[str] = mapped_column(
        String(20), nullable=False, default=StatusRekonsiliasi.PENDING
    )

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

    # Relationships
    items: Mapped[list["RekonsiliasiTangki"]] = relationship(
        back_populates="rekonsiliasi", cascade="all, delete-orphan"
    )
    run_by: Mapped["User | None"] = relationship(foreign_keys=[run_by_id])
    approved_by: Mapped["User | None"] = relationship(foreign_keys=[approved_by_id])


class RekonsiliasiTangki(Base):
    """Per-tank reconciliation detail within a daily reconciliation."""

    __tablename__ = "rekonsiliasi_tangki"

    __table_args__ = (
        UniqueConstraint(
            "rekonsiliasi_harian_id", "tangki_id",
            name="uq_rekonsiliasi_tangki"
        ),
    )

    id: Mapped[int] = mapped_column(primary_key=True)
    rekonsiliasi_harian_id: Mapped[int] = mapped_column(
        ForeignKey("rekonsiliasi_harian.id", ondelete="CASCADE"), nullable=False
    )
    tangki_id: Mapped[int] = mapped_column(
        ForeignKey("master_spbu_tangki.id", ondelete="RESTRICT"), nullable=False
    )

    stok_awal: Mapped[Decimal] = mapped_column(
        Numeric(15, 3), nullable=False, default=Decimal("0")
    )
    penerimaan: Mapped[Decimal] = mapped_column(
        Numeric(15, 3), nullable=False, default=Decimal("0")
    )
    pemindahan_in: Mapped[Decimal] = mapped_column(
        Numeric(15, 3), nullable=False, default=Decimal("0")
    )
    pemindahan_out: Mapped[Decimal] = mapped_column(
        Numeric(15, 3), nullable=False, default=Decimal("0")
    )
    penjualan: Mapped[Decimal] = mapped_column(
        Numeric(15, 3), nullable=False, default=Decimal("0")
    )
    stok_teoritis: Mapped[Decimal] = mapped_column(
        Numeric(15, 3), nullable=False, default=Decimal("0")
    )
    stok_aktual: Mapped[Decimal] = mapped_column(
        Numeric(15, 3), nullable=False, default=Decimal("0")
    )
    losses: Mapped[Decimal] = mapped_column(
        Numeric(15, 3), nullable=False, default=Decimal("0")
    )

    # Relationships
    rekonsiliasi: Mapped["RekonsiliasiHarian"] = relationship(back_populates="items")
    tangki: Mapped["Tangki"] = relationship(foreign_keys=[tangki_id])
