from __future__ import annotations

from datetime import date
from decimal import Decimal, ROUND_HALF_UP
from typing import List, Optional, Self

from pydantic import BaseModel, ConfigDict, Field, model_validator


def _calculate_preco_final(preco_venda: float) -> float:
    if preco_venda <= 0:
        return 0.0
    value = Decimal(str(preco_venda)) * Decimal("1.12")
    return float(value.quantize(Decimal("0.01"), rounding=ROUND_HALF_UP))


class ProdutoVendaBase(BaseModel):
    catalogo_id: str = Field(
        min_length=1,
        max_length=255,
        description="Identificador do produto no catálogo",
        examples=["produto_catalogo_123"],
    )
    nome: str = Field(
        min_length=1,
        max_length=255,
        description="Nome do produto para exibição",
        examples=["Kit Inverno"],
    )
    preco_venda: float = Field(
        gt=0,
        description="Preço base de venda",
        examples=[79.9],
    )
    preco_final: float | None = Field(
        default=None,
        gt=0,
        description="Preço final de venda com acréscimo de 12%",
        examples=[89.49],
    )

    @model_validator(mode="after")
    def _sync_preco_final(self) -> Self:
        self.preco_final = _calculate_preco_final(self.preco_venda)
        return self
    qtdade_estoque: int = Field(
        ge=0,
        description="Quantidade disponível em estoque",
        examples=[144],
    )
    observacoes: str | None = Field(
        default=None,
        max_length=200,
        description="Observações adicionais (máx. 200 caracteres)",
        examples=["Lote exclusivo para campanhas de inverno."],
    )
    data_validade: date = Field(
        description="Data de validade do item",
        examples=["2025-12-31"],
    )
    empresa_id: str = Field(
        min_length=1,
        max_length=255,
        description="Identificador da empresa proprietária do produto",
        examples=["empresa_001"],
    )


class ProdutoVendaCreate(ProdutoVendaBase):
    """Payload com os dados do produto de venda a serem armazenados."""


class ProdutoVendaCreateRequest(BaseModel):
    document_id: str = Field(default="unique()", alias="documentId")
    data: ProdutoVendaCreate

    model_config = ConfigDict(populate_by_name=True)


class ProdutoVendaUpdate(BaseModel):
    catalogo_id: str | None = Field(
        default=None,
        min_length=1,
        max_length=255,
        description="Identificador do produto no catálogo",
    )
    nome: str | None = Field(
        default=None,
        min_length=1,
        max_length=255,
        description="Nome do produto para exibição",
    )
    preco_venda: float | None = Field(
        default=None,
        gt=0,
        description="Preço base de venda",
    )
    preco_final: float | None = Field(
        default=None,
        gt=0,
        description="Preço final de venda com acréscimo de 12%",
    )

    @model_validator(mode="after")
    def _sync_preco_final(self) -> Self:
        if self.preco_venda is not None:
            self.preco_final = _calculate_preco_final(self.preco_venda)
        return self
    qtdade_estoque: int | None = Field(
        default=None,
        ge=0,
        description="Quantidade disponível em estoque",
    )
    observacoes: str | None = Field(
        default=None,
        max_length=200,
        description="Observações adicionais (máx. 200 caracteres)",
    )
    data_validade: date | None = Field(
        default=None,
        description="Data de validade do item",
    )
    empresa_id: str | None = Field(
        default=None,
        min_length=1,
        max_length=255,
        description="Identificador da empresa proprietária do produto",
    )


class ProdutoVendaOut(BaseModel):
    id: str
    catalogo_id: str
    nome: str
    preco_venda: float
    preco_final: float
    qtdade_estoque: int
    observacoes: Optional[str]
    data_validade: str
    empresa_id: str | None = None
    createdAt: str
    updatedAt: str

    model_config = ConfigDict(
        from_attributes=True,
        json_schema_extra={
            "example": {
                "id": "venda_01",
                "catalogo_id": "produto_catalogo_123",
                "nome": "Kit Inverno",
                "preco_venda": 79.9,
                "preco_final": 89.49,
                "qtdade_estoque": 144,
                "observacoes": "Campanha de inverno.",
                "data_validade": "2025-12-31",
                "empresa_id": "empresa_001",
                "createdAt": "2025-01-10T15:00:00.000Z",
                "updatedAt": "2025-01-10T15:00:00.000Z",
            }
        },
    )


class PaginatedProdutosVenda(BaseModel):
    items: List[ProdutoVendaOut]
    total: int

    model_config = ConfigDict(
        json_schema_extra={
            "example": {
                "items": [
                    {
                        "id": "venda_01",
                        "catalogo_id": "produto_catalogo_123",
                        "nome": "Kit Inverno",
                        "preco_venda": 79.9,
                        "preco_final": 89.49,
                        "qtdade_estoque": 144,
                        "observacoes": "Campanha de inverno.",
                        "data_validade": "2025-12-31",
                        "empresa_id": "empresa_001",
                        "createdAt": "2025-01-10T15:00:00.000Z",
                        "updatedAt": "2025-01-10T15:00:00.000Z",
                    }
                ],
                "total": 1,
            }
        }
    )
