"""Schemas for the penjualan (sales shift report) module."""

from datetime import date, datetime
from decimal import Decimal
from typing import Literal

from pydantic import BaseModel, ConfigDict

from app.models.operational import StatusLaporan


class PenjualanNozzleInput(BaseModel):
    """Input payload for a single nozzle row when creating/updating a laporan."""

    nozzle_id: int
    teller_awal_manual: Decimal
    teller_akhir_manual: Decimal
    teller_awal_digital: Decimal
    teller_akhir_digital: Decimal
    flag_reset_teller: bool = False
    harga_jual_override: Decimal | None = None  # Admin price override


class PenjualanNozzleResponse(BaseModel):
    """Enriched response for a single nozzle row, with human-readable names."""

    model_config = ConfigDict(from_attributes=True)

    id: int
    nozzle_id: int
    nozzle_nama: str
    island_nama: str
    produk_id: int
    produk_nama: str
    produk_kode: str
    teller_awal_manual: Decimal
    teller_akhir_manual: Decimal
    teller_awal_digital: Decimal
    teller_akhir_digital: Decimal
    flag_reset_teller: bool
    primary_teller: str
    volume: Decimal
    harga_jual: Decimal
    nilai: Decimal


class KasPaymentInput(BaseModel):
    """Cash denomination amounts + non-cash payment totals for a shift."""

    kas_100k: Decimal = Decimal("0")
    kas_50k: Decimal = Decimal("0")
    kas_20k: Decimal = Decimal("0")
    kas_10k: Decimal = Decimal("0")
    kas_5k: Decimal = Decimal("0")
    kas_2k: Decimal = Decimal("0")
    kas_1k: Decimal = Decimal("0")
    kas_logam: Decimal = Decimal("0")
    pembayaran_kartu: Decimal = Decimal("0")
    pembayaran_qr: Decimal = Decimal("0")
    pembayaran_instansi: Decimal = Decimal("0")


class LaporanShiftCreate(BaseModel):
    """Payload to create a new laporan shift."""

    tanggal: date
    shift_id: int
    nozzles: list[PenjualanNozzleInput]
    source_foto_url: str | None = None
    kas: KasPaymentInput = KasPaymentInput()


class LaporanShiftUpdate(BaseModel):
    """Payload to edit a draft laporan shift (replaces all nozzle rows)."""

    nozzles: list[PenjualanNozzleInput]
    source_foto_url: str | None = None
    kas: KasPaymentInput = KasPaymentInput()


class ReviewRequest(BaseModel):
    """Payload for reviewing (approving or rejecting) a submitted laporan."""

    action: Literal["approve", "reject"]
    catatan: str | None = None


class UnlockRequest(BaseModel):
    """Payload for unlocking an approved/locked laporan."""

    alasan: str


class LaporanShiftResponse(BaseModel):
    """Summary response for a laporan shift (list view — no nozzle detail)."""

    model_config = ConfigDict(from_attributes=True)

    id: int
    spbu_id: int
    shift_id: int
    shift_nama: str
    tanggal: date
    status: StatusLaporan
    submitted_by_name: str | None
    submitted_at: datetime | None
    reviewed_by_name: str | None
    reviewed_at: datetime | None
    catatan_review: str | None
    recalled_by_name: str | None
    recalled_at: datetime | None
    unlocked_by_name: str | None
    unlocked_at: datetime | None
    total_volume: Decimal
    total_nilai: Decimal
    nozzle_count: int
    source_foto_url: str | None = None
    # Cash & payment breakdown
    kas_100k: Decimal = Decimal("0")
    kas_50k: Decimal = Decimal("0")
    kas_20k: Decimal = Decimal("0")
    kas_10k: Decimal = Decimal("0")
    kas_5k: Decimal = Decimal("0")
    kas_2k: Decimal = Decimal("0")
    kas_1k: Decimal = Decimal("0")
    kas_logam: Decimal = Decimal("0")
    pembayaran_kartu: Decimal = Decimal("0")
    pembayaran_qr: Decimal = Decimal("0")
    pembayaran_instansi: Decimal = Decimal("0")


class LaporanShiftDetailResponse(LaporanShiftResponse):
    """Detail response for a single laporan shift, including all nozzle rows."""

    nozzles: list[PenjualanNozzleResponse]
    unlock_reason: str | None


class TellerInitResponse(BaseModel):
    """Pre-filled teller readings for each nozzle when starting a new shift report."""

    nozzle_id: int
    teller_awal_manual: Decimal   # from nozzle.teller_terakhir_manual, or 0 if None
    teller_awal_digital: Decimal  # from nozzle.teller_terakhir_digital, or 0 if None
    primary_teller: str           # 'manual' or 'digital' — from nozzle.primary_teller
    is_first_time: bool           # True when both teller_terakhir_* are None (no prior shift)
