"""
Schemas for AI record extraction (INDL-03 AC-09).

Every field is Optional — a scanned ledger card or death certificate will
rarely contain all of them, and a missing field must never fail the call.
Values are validated here (SAC-12) so that anything the model hallucinates
in the wrong shape is dropped rather than propagated into the create form.
"""
from datetime import date, time
from typing import List, Optional

from pydantic import BaseModel, ConfigDict, Field


class ExtractedContact(BaseModel):
    """A family contact read off the document. Mirrors CreateFamilyContactRequest."""

    model_config = ConfigDict(extra="forbid")

    relationship: Optional[str] = Field(None, max_length=100)
    first_name: Optional[str] = Field(None, max_length=100)
    last_name: Optional[str] = Field(None, max_length=100)
    email: Optional[str] = Field(None, max_length=255)
    phone: Optional[str] = Field(None, max_length=50)
    address: Optional[str] = Field(None, max_length=255)


class ExtractedRecord(BaseModel):
    """
    The structured payload the vision model must return.

    Field names and max_lengths deliberately mirror CreateRecordRequest /
    CreateBurialInfoRequest in src/apps/records/schemas/requests.py so that
    anything surviving validation here is guaranteed to survive the real
    create endpoint too.
    """

    model_config = ConfigDict(extra="forbid")

    # Personal
    first_name: Optional[str] = Field(None, max_length=100)
    middle_name: Optional[str] = Field(None, max_length=100)
    last_name: Optional[str] = Field(None, max_length=100)
    maiden_name: Optional[str] = Field(None, max_length=100)
    date_of_birth: Optional[date] = None
    date_of_death: Optional[date] = None
    gender: Optional[str] = Field(None, max_length=20)
    nationality: Optional[str] = Field(None, max_length=100)
    religion: Optional[str] = Field(None, max_length=100)
    is_veteran: Optional[bool] = None
    military_branch: Optional[str] = Field(None, max_length=100)

    # Burial
    interment_type: Optional[str] = Field(None, max_length=50)
    interment_date: Optional[date] = None
    interment_time: Optional[time] = None
    casket_type: Optional[str] = Field(None, max_length=100)
    depth_m: Optional[float] = Field(None, ge=0, le=999)
    officiant: Optional[str] = Field(None, max_length=255)
    attendees: Optional[int] = Field(None, ge=0, le=1_000_000)
    service_notes: Optional[str] = Field(None, max_length=2000)

    # Plot hint — free text off the document (e.g. "Section B, Lot 14").
    # Resolved to a real plot_id by the frontend typeahead, never trusted here.
    plot_reference: Optional[str] = Field(None, max_length=255)

    # Family
    contacts: List[ExtractedContact] = Field(default_factory=list)


class ExtractRecordResponse(BaseModel):
    """Envelope payload for POST /ai/extract-record."""

    record: ExtractedRecord
    dropped_fields: List[str] = Field(default_factory=list)
    warnings: List[str] = Field(default_factory=list)
