"""Document API schemas."""

from datetime import datetime
from typing import List, Literal, Optional
from uuid import UUID

from pydantic import BaseModel, Field


class DocumentUploadResponse(BaseModel):
    """Response schema for document upload endpoint.

    Attributes:
        document_id: UUID of the created document.
        filename: Original filename of the uploaded file.
        status: Current processing status (e.g., "pending").
        message: Human-readable status message.
    """

    document_id: UUID = Field(
        ...,
        description="Unique identifier for the uploaded document",
    )
    filename: str = Field(
        ...,
        description="Original filename of the uploaded file",
    )
    status: str = Field(
        ...,
        description="Current processing status of the document",
    )
    message: str = Field(
        ...,
        description="Human-readable status message",
    )

    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "document_id": "550e8400-e29b-41d4-a716-446655440000",
                    "filename": "sample.xlsx",
                    "status": "pending",
                    "message": "Document uploaded successfully and queued for processing",
                }
            ]
        }
    }


class DocumentStatus(BaseModel):
    """Status information for a single document in a batch upload.

    Attributes:
        document_id: UUID of the created document.
        filename: Original filename of the uploaded file.
        status: Current processing status (e.g., "accepted").
    """

    document_id: UUID = Field(
        ...,
        description="Unique identifier for the uploaded document",
    )
    filename: str = Field(
        ...,
        description="Original filename of the uploaded file",
    )
    status: str = Field(
        ...,
        description="Status indicator for this document (e.g., 'accepted')",
    )

    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "document_id": "550e8400-e29b-41d4-a716-446655440000",
                    "filename": "file1.xlsx",
                    "status": "accepted",
                }
            ]
        }
    }


class ValidationErrorDetail(BaseModel):
    """Error details for a failed file validation in batch upload.

    Attributes:
        filename: Name of the file that failed validation.
        code: Error code indicating the type of validation failure.
        message: Human-readable error message.
    """

    filename: str = Field(
        ...,
        description="Name of the file that failed validation",
    )
    code: str = Field(
        ...,
        description="Error code (e.g., INVALID_EXTENSION, FILE_TOO_LARGE)",
    )
    message: str = Field(
        ...,
        description="Human-readable error message",
    )

    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "filename": "invalid.txt",
                    "code": "INVALID_EXTENSION",
                    "message": "File extension must be .xlsx or .xls, got .txt",
                }
            ]
        }
    }


class BatchUploadResponse(BaseModel):
    """Response schema for batch document upload endpoint.

    Attributes:
        batch_id: UUID for tracking this batch upload.
        documents: List of successfully accepted documents.
        errors: List of validation errors for failed files.
        message: Human-readable summary message.
    """

    batch_id: UUID = Field(
        ...,
        description="Unique identifier for this batch upload",
    )
    documents: List[DocumentStatus] = Field(
        ...,
        description="List of successfully accepted documents",
    )
    errors: List[ValidationErrorDetail] = Field(
        ...,
        description="List of validation errors for failed files",
    )
    message: str = Field(
        ...,
        description="Human-readable batch upload summary",
    )

    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "batch_id": "650e8400-e29b-41d4-a716-446655440000",
                    "documents": [
                        {
                            "document_id": "550e8400-e29b-41d4-a716-446655440000",
                            "filename": "file1.xlsx",
                            "status": "accepted",
                        },
                        {
                            "document_id": "660e8400-e29b-41d4-a716-446655440001",
                            "filename": "file2.xlsx",
                            "status": "accepted",
                        },
                    ],
                    "errors": [
                        {
                            "filename": "invalid.txt",
                            "code": "INVALID_EXTENSION",
                            "message": "File extension must be .xlsx or .xls, got .txt",
                        }
                    ],
                    "message": "Batch accepted: 2 documents queued for processing, 1 failed validation",
                }
            ]
        }
    }


class DocumentProgress(BaseModel):
    """Progress information for a document being processed.

    Attributes:
        stage: Current processing stage.
        sheets_processed: Number of sheets processed so far.
        sheets_total: Total number of sheets to process.
    """

    stage: Literal["validating", "extracting_tables", "resolving_symbols", "indexing"] = Field(
        ...,
        description="Current processing stage",
    )
    sheets_processed: int = Field(
        ...,
        ge=0,
        description="Number of sheets processed so far",
    )
    sheets_total: int = Field(
        ...,
        ge=0,
        description="Total number of sheets to process",
    )

    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "stage": "extracting_tables",
                    "sheets_processed": 3,
                    "sheets_total": 10,
                }
            ]
        }
    }


class DocumentStatusResponse(BaseModel):
    """Response schema for document status endpoint.

    Attributes:
        document_id: UUID of the document.
        filename: Original filename of the document.
        status: Current processing status.
        created_at: Timestamp when document was uploaded.
        processed_at: Timestamp when processing completed (if completed).
        progress: Progress information (if processing).
        sheet_count: Number of sheets in document (if completed).
        record_count: Number of records extracted (if completed).
        symbols_found: Number of symbols detected (if completed).
        cross_references: Number of cross-references found (if completed).
        error_message: Error details (if failed).
    """

    document_id: UUID = Field(
        ...,
        description="Unique identifier for the document",
    )
    filename: str = Field(
        ...,
        description="Original filename of the document",
    )
    status: Literal["pending", "processing", "completed", "failed"] = Field(
        ...,
        description="Current processing status of the document",
    )
    created_at: datetime = Field(
        ...,
        description="Timestamp when document was uploaded",
    )

    # Optional fields based on status
    processed_at: Optional[datetime] = Field(
        None,
        description="Timestamp when processing completed",
    )
    progress: Optional[DocumentProgress] = Field(
        None,
        description="Progress information (only present when status is 'processing')",
    )
    sheet_count: Optional[int] = Field(
        None,
        ge=0,
        description="Number of sheets in document (only present when status is 'completed')",
    )
    record_count: Optional[int] = Field(
        None,
        ge=0,
        description="Number of records extracted (only present when status is 'completed')",
    )
    symbols_found: Optional[int] = Field(
        None,
        ge=0,
        description="Number of symbols detected (only present when status is 'completed')",
    )
    cross_references: Optional[int] = Field(
        None,
        ge=0,
        description="Number of cross-references found (only present when status is 'completed')",
    )
    error_message: Optional[str] = Field(
        None,
        description="Error details (only present when status is 'failed')",
    )

    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "document_id": "550e8400-e29b-41d4-a716-446655440000",
                    "filename": "file.xlsx",
                    "status": "pending",
                    "created_at": "2025-11-26T10:00:00Z",
                },
                {
                    "document_id": "550e8400-e29b-41d4-a716-446655440000",
                    "filename": "file.xlsx",
                    "status": "processing",
                    "created_at": "2025-11-26T10:00:00Z",
                    "progress": {
                        "stage": "extracting_tables",
                        "sheets_processed": 3,
                        "sheets_total": 10,
                    },
                },
                {
                    "document_id": "550e8400-e29b-41d4-a716-446655440000",
                    "filename": "file.xlsx",
                    "status": "completed",
                    "created_at": "2025-11-26T10:00:00Z",
                    "processed_at": "2025-11-26T10:00:45Z",
                    "sheet_count": 10,
                    "record_count": 1250,
                    "symbols_found": 15,
                    "cross_references": 32,
                },
                {
                    "document_id": "550e8400-e29b-41d4-a716-446655440000",
                    "filename": "file.xlsx",
                    "status": "failed",
                    "created_at": "2025-11-26T10:00:00Z",
                    "error_message": "Unable to detect table boundaries in sheet 'Data'",
                },
            ]
        }
    }


class DocumentDeletionResponse(BaseModel):
    """Response schema for document deletion endpoint.

    Attributes:
        document_id: UUID of the deleted document.
        status: Deletion status (always "deleted").
        message: Deletion confirmation message.
    """

    document_id: UUID = Field(
        ...,
        description="Unique identifier of the deleted document",
    )
    status: Literal["deleted"] = Field(
        ...,
        description="Deletion status",
    )
    message: str = Field(
        ...,
        description="Deletion confirmation message",
    )

    model_config = {
        "json_schema_extra": {
            "examples": [
                {
                    "document_id": "550e8400-e29b-41d4-a716-446655440000",
                    "status": "deleted",
                    "message": "Document and all associated data removed",
                }
            ]
        }
    }
