from typing import Literal

from pydantic import BaseModel, Field


FiscalDocumentType = Literal["unknown", "invoice", "instant_invoice", "delivery_note"]
FiscalDocumentStatus = Literal["processing", "ready", "error"]
FiscalMatchingStatus = Literal["pending", "not_started", "ready_for_match"]
FiscalReviewStatus = Literal["to_review", "reviewed"]
FiscalDocumentInboxSyncStatus = Literal["imported", "unsupported", "error"]
FiscalDocumentOrderMatchStatus = Literal["matched", "no_candidate", "no_document_lines"]


class FiscalDocumentLineItemRead(BaseModel):
    line_index: int
    product_code: str | None = None
    iso_code: str | None = None
    description: str
    category_code: str | None = None
    unit_code: str | None = None
    pack_count: float | None = None
    quantity: float | None = None
    gross_quantity: float | None = None
    tare_quantity: float | None = None
    net_quantity: float | None = None
    unit_price: float | None = None
    line_total: float | None = None
    vat_code: str | None = None
    raw_row_text: str = ""


class FiscalDocumentOrderMatchLineRead(BaseModel):
    status: Literal["exact", "partial", "missing", "extra", "over_delivered"]
    confidence: float = 0.0
    order_item_id: int | None = None
    order_product_name: str | None = None
    order_lot_code: str | None = None
    order_supplier_name: str | None = None
    ordered_quantity: float | None = None
    delivered_quantity: float | None = None
    comparable_delivered_quantity: float | None = None
    missing_quantity: float | None = None
    extra_quantity: float | None = None
    document_line_index: int | None = None
    document_description: str | None = None
    document_raw_row_text: str | None = None
    document_unit_code: str | None = None
    document_quantity: float | None = None


class FiscalDocumentOrderMatchRead(BaseModel):
    status: FiscalDocumentOrderMatchStatus
    matched_batch_id: int | None = None
    matched_batch_confirmed_at: str | None = None
    matched_batch_staff: str | None = None
    matched_supplier_name: str | None = None
    score: float = 0.0
    line_match_count: int = 0
    exact_line_count: int = 0
    missing_line_count: int = 0
    extra_line_count: int = 0
    can_apply_storno: bool = False
    lines: list[FiscalDocumentOrderMatchLineRead] = Field(default_factory=list)


class FiscalDocumentRead(BaseModel):
    id: str
    original_name: str
    display_name: str
    mime_type: str
    kind: str
    file_size_bytes: int
    document_type: FiscalDocumentType
    document_number: str | None = None
    document_date: str | None = None
    supplier_name: str | None = None
    total_amount: float | None = None
    currency: str = "EUR"
    summary_text: str = ""
    extracted_text: str = ""
    preview_text: str = ""
    drive_file_id: str | None = None
    drive_web_url: str | None = None
    drive_uploaded_at: str | None = None
    covered_by_document_id: str | None = None
    covered_by_document_name: str | None = None
    line_items: list[FiscalDocumentLineItemRead] = Field(default_factory=list)
    order_match: FiscalDocumentOrderMatchRead | None = None
    status: FiscalDocumentStatus
    matching_status: FiscalMatchingStatus = "pending"
    review_status: FiscalReviewStatus = "to_review"
    error_detail: str | None = None
    created_at: str
    updated_at: str


class FiscalDocumentsListResponse(BaseModel):
    items: list[FiscalDocumentRead] = Field(default_factory=list)
    total_count: int = 0
    archive_total_count: int = 0
    invoice_count: int = 0
    instant_invoice_count: int = 0
    delivery_note_count: int = 0
    to_review_count: int = 0
    limit: int = 50
    offset: int = 0
    has_more: bool = False


class FiscalDocumentNotificationSummary(BaseModel):
    discrepancy_count: int = 0


class FiscalDocumentSettingsRead(BaseModel):
    inbound_email: str | None = None
    mailbox_configured: bool = False
    updated_at: str | None = None


class FiscalDocumentSettingsUpdatePayload(BaseModel):
    inbound_email: str | None = None


class FiscalDocumentInboxStatusRead(BaseModel):
    mailbox_configured: bool = False
    inbound_email: str | None = None
    google_configured: bool = False
    google_connected: bool = False
    google_account_email: str | None = None
    gmail_scope_granted: bool = False
    mailbox_matches_google_account: bool = False
    ready_for_sync: bool = False
    next_step: str


class FiscalDocumentInboxItemRead(BaseModel):
    id: str
    message_id: str
    attachment_id: str
    subject: str = ""
    sender: str | None = None
    received_at: str | None = None
    attachment_name: str
    mime_type: str
    sync_status: FiscalDocumentInboxSyncStatus
    document_id: str | None = None
    error_detail: str | None = None
    created_at: str
    updated_at: str


class FiscalDocumentInboxListResponse(BaseModel):
    items: list[FiscalDocumentInboxItemRead] = Field(default_factory=list)
    total_count: int = 0
    imported_count: int = 0
    unsupported_count: int = 0
    error_count: int = 0
