"""Schemas for Automated 3-Way Matching Engine (PO - GRN/Ticket - Invoice)."""

from __future__ import annotations

from datetime import date
from decimal import Decimal
from enum import Enum

from pydantic import BaseModel, Field


class MatchStatusEnum(str, Enum):
    PERFECT_MATCH = "PERFECT_MATCH"
    PRICE_MISMATCH = "PRICE_MISMATCH"
    QUANTITY_MISMATCH = "QUANTITY_MISMATCH"
    PARTIAL_RECEIPT = "PARTIAL_RECEIPT"
    MISSING_GRN = "MISSING_GRN"
    MISSING_PO = "MISSING_PO"
    SUSPICIOUS_TAX_RISK = "SUSPICIOUS_TAX_RISK"


class PurchaseOrderSummary(BaseModel):
    po_code: str
    supplier_tax_id: str
    supplier_name: str
    project_code: str
    item_name: str
    ordered_quantity: Decimal = Field(default_factory=lambda: Decimal("0.0000"))
    unit_price: Decimal = Field(default_factory=lambda: Decimal("0.0000"))
    total_amount: Decimal = Field(default_factory=lambda: Decimal("0.0000"))
    unit: str


class GoodsReceiptSummary(BaseModel):
    grn_code: str
    weighbridge_ticket_number: str | None = None
    supplier_tax_id: str
    project_code: str
    item_name: str
    received_quantity: Decimal = Field(default_factory=lambda: Decimal("0.0000"))
    received_date: date
    receiver_name: str
    unit: str


class InvoiceMatchSummary(BaseModel):
    invoice_number: str
    invoice_date: date
    seller_tax_id: str
    seller_name: str
    item_name: str
    billed_quantity: Decimal = Field(default_factory=lambda: Decimal("0.0000"))
    unit_price: Decimal = Field(default_factory=lambda: Decimal("0.0000"))
    total_pre_tax: Decimal = Field(default_factory=lambda: Decimal("0.0000"))
    tax_amount: Decimal = Field(default_factory=lambda: Decimal("0.0000"))


class ThreeWayMatchResult(BaseModel):
    match_id: str
    match_status: MatchStatusEnum
    seller_tax_id: str
    seller_name: str
    project_code: str
    item_name: str
    po_ref: PurchaseOrderSummary | None = None
    grn_ref: GoodsReceiptSummary | None = None
    invoice_ref: InvoiceMatchSummary
    qty_variance: Decimal = Field(default_factory=lambda: Decimal("0.0000"))
    price_variance: Decimal = Field(default_factory=lambda: Decimal("0.0000"))
    amount_variance: Decimal = Field(default_factory=lambda: Decimal("0.0000"))
    discrepancy_explanation: str | None = None
    recommended_action: str  # AUTO_APPROVE, HOLD_FOR_REVIEW, REJECT_INVOICE


class MatchingDashboardResponse(BaseModel):
    as_of_date: date
    total_invoices_checked: int
    perfect_matches_count: int
    mismatches_count: int
    pending_approval_count: int
    total_discrepancy_amount: Decimal = Field(default_factory=lambda: Decimal("0.0000"))
    matches: list[ThreeWayMatchResult] = Field(default_factory=list)
