"""Sales response schemas."""
from datetime import datetime
from decimal import Decimal
from typing import Dict, List, Optional
from uuid import UUID
from pydantic import BaseModel, ConfigDict


class OpportunityResponse(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: UUID
    tenant_id: UUID
    family_name: Optional[str] = None
    care_type: Optional[str] = None
    contact_phone: Optional[str] = None
    contact_email: Optional[str] = None
    section_id: Optional[UUID] = None
    plot_id: Optional[UUID] = None
    estimated_value: Optional[Decimal] = None
    assigned_to: Optional[UUID] = None
    stage: str
    stage_entered_at: Optional[datetime] = None
    next_action: Optional[str] = None
    lost_reason: Optional[str] = None
    notes: Optional[str] = None
    deleted_at: Optional[datetime] = None
    created_at: datetime
    updated_at: datetime
    days_in_stage: int = 0


class KanbanResponse(BaseModel):
    inquiry: List[Dict] = []
    site_visit: List[Dict] = []
    proposal_sent: List[Dict] = []
    contract_signed: List[Dict] = []
    deposit_received: List[Dict] = []
    fully_paid: List[Dict] = []
    lost: List[Dict] = []


class ProposalLineItemResponse(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: UUID
    sort_order: int
    description: str
    quantity: Decimal
    unit_price: Decimal
    line_total: Decimal


class ProposalResponse(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: UUID
    tenant_id: UUID
    opportunity_id: Optional[UUID] = None
    quote_number: str
    to_email: str
    cc_email: Optional[str] = None
    subject: str
    cover_note: Optional[str] = None
    valid_days: int
    sales_owner_id: Optional[UUID] = None
    status: str
    subtotal: Decimal
    tax_rate: Decimal
    tax_amount: Decimal
    total_amount: Decimal
    sent_at: Optional[datetime] = None
    accepted_at: Optional[datetime] = None
    pdf_s3_key: Optional[str] = None
    deleted_at: Optional[datetime] = None
    created_at: datetime
    updated_at: datetime
    line_items: List[ProposalLineItemResponse] = []


class ContractLineItemResponse(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: UUID
    description: str
    fee_type: Optional[str] = None
    quantity: int
    unit_price: Decimal
    line_total: Decimal


class ContractResponse(BaseModel):
    """List-safe contract representation.

    Intentionally excludes:
    - ``purchaser_signature_b64`` — potentially hundreds of KB per row; never
      needed in a paginated list.
    - ``pdf_s3_key`` — raw S3 object key must never be exposed to clients;
      callers should request a presigned URL through a dedicated endpoint.
    """

    model_config = ConfigDict(from_attributes=True)

    id: UUID
    tenant_id: UUID
    contract_number: str
    opportunity_id: Optional[UUID] = None
    plot_id: Optional[UUID] = None
    section_id: Optional[UUID] = None
    created_by: Optional[UUID] = None
    contract_type: Optional[str] = None
    status: str
    purchaser_id: Optional[UUID] = None
    purchaser_name: Optional[str] = None
    purchaser_email: Optional[str] = None
    purchaser_phone: Optional[str] = None
    purchaser_address: Optional[str] = None
    payment_plan_type: Optional[str] = None
    deposit_amount: Optional[Decimal] = None
    payment_schedule: Optional[dict] = None
    total_amount: Decimal = Decimal("0")
    # NOTE: purchaser_signature_b64 deliberately omitted — use ContractDetailResponse
    witness_name: Optional[str] = None
    signed_at: Optional[datetime] = None
    # NOTE: pdf_s3_key deliberately omitted — raw S3 key must not leave the server
    pdf_available: bool = False  # True once a PDF has been generated; clients poll this
    deleted_at: Optional[datetime] = None
    created_at: datetime
    updated_at: datetime
    line_items: List[ContractLineItemResponse] = []

    @classmethod
    def from_orm_list(cls, contract: object) -> "ContractResponse":
        """Build a list-safe response, deriving ``pdf_available`` from the ORM object."""
        obj = cls.model_validate(contract)
        # pdf_s3_key is not in the schema; read it directly from the ORM object
        obj.pdf_available = bool(getattr(contract, "pdf_s3_key", None))
        return obj


class ContractDetailResponse(ContractResponse):
    """Full contract detail including the signature blob.

    Only returned by ``GET /contracts/{id}``.  Never used in list responses to
    avoid serialising large base64 payloads for every row in a paginated table.
    The raw ``pdf_s3_key`` is still omitted; use the presigned-URL endpoint.
    """

    purchaser_signature_b64: Optional[str] = None
