from __future__ import annotations
from typing import Literal, Optional
from pydantic import BaseModel

DocumentType = Literal["text", "pdf", "web", "markdown", "word"]


class TextSegment(BaseModel):
    text: str
    charOffset: int
    pageNumber: Optional[int] = None
    x: Optional[float] = None
    y: Optional[float] = None
    width: Optional[float] = None
    height: Optional[float] = None


class DocumentContent(BaseModel):
    rawText: str
    segments: list[TextSegment]
    pageCount: Optional[int] = None
    pageDimensions: Optional[list[dict]] = None


class Citation(BaseModel):
    quoteText: str
    charOffset: int
    length: int
    confidence: Literal["exact", "normalized", "fuzzy"]
    pageNumber: Optional[int] = None


class Fact(BaseModel):
    id: str
    text: str
    citations: list[Citation]


class Document(BaseModel):
    id: str
    title: str
    type: str
    content: DocumentContent
    sourceUrl: Optional[str] = None
    originalFileName: Optional[str] = None
    pdfData: Optional[str] = None
    createdAt: str


class DocumentSummary(BaseModel):
    id: str
    title: str
    type: str
    sourceUrl: Optional[str] = None
    createdAt: str


class TokenUsage(BaseModel):
    inputTokens: int
    outputTokens: int
    costUsd: float


class ExtractionResult(BaseModel):
    id: Optional[str] = None
    documentId: str
    facts: list[Fact]
    prompt: Optional[str] = None
    noMentionFound: Optional[bool] = None
    absenceEvidence: Optional[str] = None
    usage: Optional[TokenUsage] = None
    extractedAt: str


# Internal Claude output types
class ClaudeCitation(BaseModel):
    exact_quote: str


class ClaudeFact(BaseModel):
    fact: str
    citations: list[ClaudeCitation]


class ClaudeExtraction(BaseModel):
    facts: list[ClaudeFact]
    no_mention_found: Optional[bool] = None
    absence_evidence: Optional[str] = None
