from __future__ import annotations

from typing import Any, Literal
from urllib.parse import urlparse

from pydantic import BaseModel, ConfigDict, Field, field_validator


SUPPORTED_MODES = {"standard", "artwork", "photo", "illustration"}
SUPPORTED_FORMATS = {"webp", "png", "jpg"}
SUPPORTED_SCALES = {2, 4}


class UpscaleRequest(BaseModel):
    job_id: int = Field(..., gt=0)
    source_url: str
    scale: Literal[2, 4]
    mode: Literal["standard", "artwork", "photo", "illustration"]
    output_format: Literal["webp", "png", "jpg"] = "webp"

    @field_validator("source_url")
    @classmethod
    def validate_source_url(cls, value: str) -> str:
        candidate = value.strip()

        if candidate == "":
            raise ValueError("source_url is required")

        if candidate.startswith(("/", "./", "../", "file://")):
            raise ValueError("source_url must be an http or https URL")

        parsed = urlparse(candidate)

        if parsed.scheme not in {"http", "https"} or parsed.netloc == "":
            raise ValueError("source_url must be an http or https URL")

        return candidate


class HealthResponse(BaseModel):
    status: str
    service: str
    engine: str
    device: str
    models_loaded: bool
    max_input_width: int
    max_input_height: int
    max_output_width: int
    max_output_height: int
    realesrgan: dict[str, Any] | None = None


class UpscaleResponse(BaseModel):
    success: bool
    job_id: int
    output_url: str | None = None
    output_base64: str | None = None
    width: int
    height: int
    filesize: int
    mime: str
    metadata: dict[str, Any] = Field(default_factory=dict)

    model_config = ConfigDict(extra="forbid")