"""Data models for the Unsiloed SDK."""

from typing import Optional, List, Dict, Any
from dataclasses import dataclass, fields


class _FlexibleInit:
    """Mixin that allows dataclasses to accept and ignore unknown fields."""

    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)

    @classmethod
    def from_dict(cls, data: Dict[str, Any]):
        known = {f.name for f in fields(cls)}
        filtered = {k: v for k, v in data.items() if k in known}
        return cls(**filtered)


@dataclass
class Category:
    """Represents a classification or split category."""

    name: str
    description: Optional[str] = None


@dataclass
class ParseResponse(_FlexibleInit):
    """Response from a parse operation."""

    job_id: str
    status: str
    file_name: Optional[str] = None
    file_type: Optional[str] = None
    page_count: Optional[int] = None
    pdf_url: Optional[str] = None
    created_at: Optional[str] = None
    started_at: Optional[str] = None
    finished_at: Optional[str] = None
    message: Optional[str] = None
    credit_used: Optional[int] = None
    quota_remaining: Optional[int] = None
    total_chunks: Optional[int] = None
    chunks: Optional[List[Dict[str, Any]]] = None
    error: Optional[str] = None
    result: Optional[Dict[str, Any]] = None
    merge_tables: Optional[bool] = None
    validate_table_segments: Optional[bool] = None
    keep_segment_types: Optional[str] = None
    configuration: Optional[Dict[str, Any]] = None


@dataclass
class ExtractResponse(_FlexibleInit):
    """Response from an extract operation."""

    job_id: str
    status: str
    file_name: Optional[str] = None
    created_at: Optional[str] = None
    updated_at: Optional[str] = None
    message: Optional[str] = None
    result: Optional[Dict[str, Any]] = None
    error: Optional[str] = None
    quota_remaining: Optional[int] = None
    metadata: Optional[Dict[str, Any]] = None


@dataclass
class ClassifyResponse(_FlexibleInit):
    """Response from a classify operation."""

    job_id: str
    status: str
    progress: Optional[str] = None
    message: Optional[str] = None
    result: Optional[Dict[str, Any]] = None
    error: Optional[str] = None
    quota_remaining: Optional[int] = None


@dataclass
class SplitResponse(_FlexibleInit):
    """Response from a split operation."""

    job_id: str
    status: str
    progress: Optional[str] = None
    file_url: Optional[str] = None
    file_name: Optional[str] = None
    parameters: Optional[Dict[str, Any]] = None
    result: Optional[Dict[str, Any]] = None
    error: Optional[str] = None
    quota_remaining: Optional[int] = None


@dataclass
class JobStatus(_FlexibleInit):
    """Generic job status response."""

    job_id: str
    status: str
    progress: Optional[str] = None
    result: Optional[Dict[str, Any]] = None
    error: Optional[str] = None
