import base64
import binascii
from typing import Any, Literal, Optional

from pydantic import (
    BaseModel,
    Field,
    PrivateAttr,
    StrictBool,
    field_validator,
    model_validator,
)


class Info(BaseModel):
    _decoded_file: bytes = PrivateAttr(default=b"")

    file: str  # base64 string
    type: Literal["png", "jpg", "jpeg", "gif"]  # image type like 'png', 'jpg'
    skip_text_detection: Optional[StrictBool] = Field(False)
    skip_table_detection: Optional[StrictBool] = Field(False)
    recognize_math: Optional[StrictBool] = Field(False)
    ocr_with_boxes: Optional[StrictBool] = Field(True)

    @field_validator("type", mode="before")
    @classmethod
    def normalize_type(cls, value: str) -> str:
        if not isinstance(value, str):
            raise ValueError("type must be a string")
        return value.lower()

    @model_validator(mode="after")
    def decode_base64_file(self):
        if not self.file:
            raise ValueError("file must be a non-empty base64 string")
        try:
            self._decoded_file = base64.b64decode(self.file, validate=True)
        except binascii.Error as exc:
            raise ValueError("file must be valid base64") from exc
        return self


class ApiResponse(BaseModel):
    data: Any
    message: str
    code: int
