from pydantic import BaseModel, Field, constr
from typing import List, Optional
from enum import Enum


# ================= ENUMS =================

class VatCategory(str, Enum):
    S = "S"     # Standard rate
    E = "E"     # Exempt
    AE = "AE"   # Reverse charge
    O = "O"     # Outside scope


class CurrencyCode(str, Enum):
    EUR = "EUR"


class DateFormat(str, Enum):
    YYYYMMDD = "102"


# ================= ADDRESS =================

class Address(BaseModel):
    adr_l1: str
    adr_l2: Optional[str] = None
    adr_l3: Optional[str] = None
    postcode: str
    city: str
    country_id: constr(min_length=2, max_length=2)  # ISO alpha-2


# ================= PARTIES =================

class Company(BaseModel):
    name: str
    address: Address
    siren: Optional[str] = None
    vat: Optional[str] = None   # obligatoire si TVA S


class Partner(BaseModel):
    name: str
    address: Address
    siren: Optional[str] = None
    vat: Optional[str] = None


# ================= INVOICE =================

class Invoice(BaseModel):
    name: str
    order: str
    date: constr(min_length=8, max_length=8)  # YYYYMMDD
    expiration: constr(min_length=8, max_length=8)
    type_code: str = "380"
    date_format: DateFormat = DateFormat.YYYYMMDD
    currency: CurrencyCode = CurrencyCode.EUR
    reference: Optional[str] = None
    salesperson: Optional[str] = None
    description: Optional[List[str]] = None


# ================= VAT HEADER (optionnel) =================

class InvoiceHeader(BaseModel):
    tva_code: float = Field(ge=0)
    tva_texte: Optional[str] = None
    amount: Optional[float] = None


# ================= LINES =================

class InvoiceLine(BaseModel):
    product_code: Optional[str] = None
    product_description: str
    product_type: Optional[str] = None

    quantity: float = Field(gt=0)
    unit_price: float = Field(ge=0)

    tva_code: float = Field(ge=0)
    tva_type: VatCategory = VatCategory.S

    unit: Optional[str] = "C62"


# ================= FOOTER =================

class Footer(BaseModel):
    left: Optional[str] = None
    middle: Optional[str] = None
    right: Optional[str] = None
    bottom: Optional[str] = None


class Other(BaseModel):
    terms_url: Optional[str] = None


# ================= ROOT =================

class DevisData(BaseModel):
    company: Company
    partner: Partner
    invoice: Invoice
    invoice_lines: List[InvoiceLine]
    invoice_header: Optional[List[InvoiceHeader]] = None
    footer: Optional[Footer] = None
    other: Optional[Other] = None

    # 🔒 Validation EN16931 critique
    def validate_vat_rules(self):
        if any(line.tva_type == VatCategory.S for line in self.invoice_lines):
            if not self.company.vat:
                raise ValueError(
                    "Seller VAT number is required when VAT category is 'S'"
                )

    def model_post_init(self, __context):
        self.validate_vat_rules()