"""Domain Entities and Value Objects for Debt Clearing and Auto-Settlement."""

from __future__ import annotations

from datetime import date, datetime
from decimal import Decimal
from enum import Enum
from typing import Optional
from uuid import UUID, uuid4

from pydantic import BaseModel, ConfigDict, Field


class ClearingMethod(str, Enum):
    EXACT_INVOICE_NO = "EXACT_INVOICE_NO"
    EXACT_AMOUNT_PARTNER = "EXACT_AMOUNT_PARTNER"
    SUBSET_SUM_INVOICES = "SUBSET_SUM_INVOICES"
    FIFO_PARTNER = "FIFO_PARTNER"
    VPBANK_LOAN = "VPBANK_LOAN"
    NON_INVOICE_VAS_JOURNAL = "NON_INVOICE_VAS_JOURNAL"
    ADVANCE_DEPOSIT = "ADVANCE_DEPOSIT"
    MANUAL = "MANUAL"



class SettlementStatus(str, Enum):
    SETTLED = "settled"
    TENTATIVE = "tentative"
    REVERSED = "reversed"


class DebtSettlement(BaseModel):
    """Domain Entity đại diện cho một bản ghi cấn trừ gạch nợ (Clearing Settlement)."""

    model_config = ConfigDict(arbitrary_types_allowed=True)

    id: UUID = Field(default_factory=uuid4)
    company_id: UUID
    bank_transaction_id: UUID
    invoice_id: Optional[UUID] = None
    partner_id: Optional[UUID] = None
    partner_tax_code: Optional[str] = None
    partner_name: Optional[str] = None
    account_code: str = "331"  # 331 (Phải trả), 131 (Phải thu), 341 (Vay VPBank), 635 (Lãi vay)
    settlement_amount_vnd: Decimal
    settlement_date: date
    clearing_method: ClearingMethod = ClearingMethod.EXACT_AMOUNT_PARTNER
    confidence_score: Decimal = Decimal("1.0000")
    status: SettlementStatus = SettlementStatus.SETTLED
    notes: Optional[str] = None
    created_at: datetime = Field(default_factory=datetime.utcnow)


class ClearingResult(BaseModel):
    """Value Object tổng hợp kết quả của một đợt quét khớp nợ tự động."""

    model_config = ConfigDict(arbitrary_types_allowed=True)

    total_transactions_scanned: int = 0
    matched_count: int = 0
    total_cleared_amount_vnd: Decimal = Decimal("0")
    invoices_settled_count: int = 0
    invoices_partially_paid_count: int = 0
    dry_run: bool = False
    settlements: list[DebtSettlement] = []
