from datetime import date, datetime
from decimal import Decimal

from pydantic import BaseModel, ConfigDict, Field, computed_field


# ----- Quote items -----

class QuoteItemBase(BaseModel):
    concept: str = Field(..., max_length=60)
    description: str | None = Field(None, max_length=255)
    supplier_id: int | None = None
    quantity: Decimal = Field(Decimal(1), ge=0, max_digits=12, decimal_places=2)
    unit_cost: Decimal = Field(Decimal(0), ge=0, max_digits=14, decimal_places=2)
    unit_sale: Decimal = Field(Decimal(0), ge=0, max_digits=14, decimal_places=2)
    currency: str | None = Field(None, max_length=3)


class QuoteItemCreate(QuoteItemBase):
    quote_id: int


class QuoteItemUpdate(BaseModel):
    concept: str | None = Field(None, max_length=60)
    description: str | None = Field(None, max_length=255)
    supplier_id: int | None = None
    quantity: Decimal | None = Field(None, ge=0, max_digits=12, decimal_places=2)
    unit_cost: Decimal | None = Field(None, ge=0, max_digits=14, decimal_places=2)
    unit_sale: Decimal | None = Field(None, ge=0, max_digits=14, decimal_places=2)
    currency: str | None = Field(None, max_length=3)


class QuoteItemResponse(QuoteItemBase):
    model_config = ConfigDict(from_attributes=True)

    id: int
    quote_id: int
    tenant_id: int
    company_id: int

    @computed_field
    @property
    def line_cost(self) -> Decimal:
        return (self.quantity or Decimal(0)) * (self.unit_cost or Decimal(0))

    @computed_field
    @property
    def line_sale(self) -> Decimal:
        return (self.quantity or Decimal(0)) * (self.unit_sale or Decimal(0))


# ----- Quotes -----

class QuoteBase(BaseModel):
    reference: str | None = Field(None, max_length=40)
    service_request_id: int | None = None
    account_id: int | None = None
    currency: str = Field("USD", max_length=3)
    load_type: str | None = Field(None, max_length=10)  # FCL | LCL (variante de la comparación "Ambas")
    issue_date: date | None = None
    valid_until: date | None = None
    notes: str | None = None
    terms: str | None = None
    owner_user_id: str | None = Field(None, max_length=64)


class QuoteCreate(QuoteBase):
    pass


class QuoteUpdate(BaseModel):
    reference: str | None = Field(None, max_length=40)
    service_request_id: int | None = None
    account_id: int | None = None
    currency: str | None = Field(None, max_length=3)
    load_type: str | None = Field(None, max_length=10)
    issue_date: date | None = None
    valid_until: date | None = None
    notes: str | None = None
    terms: str | None = None
    owner_user_id: str | None = Field(None, max_length=64)


class QuoteResponse(QuoteBase):
    model_config = ConfigDict(from_attributes=True)

    id: int
    service_request_reference: str | None = None  # folio de la solicitud referenciada
    case_id: int | None = None
    status: str
    total_cost: Decimal
    total_sale: Decimal
    pdf_file_key: str | None = None
    sent_at: datetime | None = None
    accepted_at: datetime | None = None
    rejected_at: datetime | None = None
    created_by: str | None = None
    updated_by: str | None = None
    tenant_id: int
    company_id: int
    created_at: datetime
    updated_at: datetime

    @computed_field
    @property
    def margin(self) -> Decimal:
        return (self.total_sale or Decimal(0)) - (self.total_cost or Decimal(0))


# ----- Configuración de marca del formato de cotización -----

class QuoteSettingsInput(BaseModel):
    emitter_name: str | None = Field(None, max_length=255)
    emitter_rfc: str | None = Field(None, max_length=13)
    emitter_address: str | None = None
    emitter_phone: str | None = Field(None, max_length=60)
    emitter_email: str | None = Field(None, max_length=255)
    emitter_website: str | None = Field(None, max_length=255)
    accent_color: str | None = Field(None, max_length=9)
    quote_prefix: str | None = Field(None, max_length=12)
    default_terms: str | None = None
    footer_note: str | None = None


class QuoteSettingsResponse(QuoteSettingsInput):
    model_config = ConfigDict(from_attributes=True)
    id: int | None = None
    logo_file_key: str | None = None


class SendQuoteEmailRequest(BaseModel):
    to: str | None = None
    subject: str | None = None
    message: str | None = None
