"""HTML Cleaner tool using generated API client."""

from pathlib import Path
from typing import Optional

from .._config import SDKConfig
from .._api.client import (
    BaseResource,
    AsyncBaseResource,
    SyncCleanerCleanerAPI,
    CleanerCleanerAPI,
)
from .._api.generated.cleaner.cleaner__api__cleaner.models import (
    CleanRequestRequest,
    CleanResponse,
    CleaningRequestDetail,
    CleaningStats,
)
from .._api.generated.cleaner.enums import (
    CleanRequestRequestOutputFormat,
    CleaningRequestDetailStatus,
    CleaningRequestListStatus,
)


class CleanerResource(BaseResource):
    """HTML Cleaner tool (sync).

    Uses generated SyncCleanerCleanerAPI client.
    """

    def __init__(self, config: SDKConfig):
        super().__init__(config)
        self._api = SyncCleanerCleanerAPI(self._http_client)

    def clean(
        self,
        html: bytes | str,
        *,
        filename: str = "input.html",
        output_format: CleanRequestRequestOutputFormat | str = CleanRequestRequestOutputFormat.HTML,
        max_tokens: int = 10000,
        remove_scripts: bool = True,
        remove_styles: bool = True,
        remove_comments: bool = True,
        remove_hidden: bool = True,
        filter_classes: bool = True,
        class_threshold: float = 0.3,
        try_hydration: bool = True,
        preserve_selectors: Optional[list[str]] = None,
    ) -> CleanResponse:
        """Clean HTML content via API."""
        if isinstance(html, str):
            content = html.encode("utf-8")
        else:
            content = html

        # Handle string or enum for output_format
        format_value = output_format.value if hasattr(output_format, "value") else output_format

        files = {"file": (filename, content, "text/html")}
        form_data = {
            "output_format": format_value,
            "max_tokens": str(max_tokens),
            "remove_scripts": str(remove_scripts).lower(),
            "remove_styles": str(remove_styles).lower(),
            "remove_comments": str(remove_comments).lower(),
            "remove_hidden": str(remove_hidden).lower(),
            "filter_classes": str(filter_classes).lower(),
            "class_threshold": str(class_threshold),
            "try_hydration": str(try_hydration).lower(),
        }
        if preserve_selectors:
            form_data["preserve_selectors"] = ",".join(preserve_selectors)

        response = self._http_client.post("/api/cleaner/clean/", files=files, data=form_data)
        response.raise_for_status()
        return CleanResponse.model_validate(response.json())

    def clean_file(self, file_path: str | Path, **kwargs) -> CleanResponse:
        """Clean HTML file."""
        path = Path(file_path)
        content = path.read_bytes()
        filename = kwargs.pop("filename", path.name)
        return self.clean(content, filename=filename, **kwargs)

    def get(self, uuid: str) -> CleaningRequestDetail:
        """Get cleaning request details."""
        return self._api.retrieve(uuid)

    def list(self):
        """List cleaning requests."""
        return self._api.list()

    def stats(self) -> CleaningStats:
        """Get cleaning statistics."""
        return self._api.stats_retrieve()


class AsyncCleanerResource(AsyncBaseResource):
    """HTML Cleaner tool (async).

    Uses generated CleanerCleanerAPI client.
    """

    def __init__(self, config: SDKConfig):
        super().__init__(config)
        self._api = CleanerCleanerAPI(self._http_client)

    async def clean(
        self,
        html: bytes | str,
        *,
        filename: str = "input.html",
        output_format: CleanRequestRequestOutputFormat | str = CleanRequestRequestOutputFormat.HTML,
        max_tokens: int = 10000,
        remove_scripts: bool = True,
        remove_styles: bool = True,
        remove_comments: bool = True,
        remove_hidden: bool = True,
        filter_classes: bool = True,
        class_threshold: float = 0.3,
        try_hydration: bool = True,
        preserve_selectors: Optional[list[str]] = None,
    ) -> CleanResponse:
        """Clean HTML content via API."""
        if isinstance(html, str):
            content = html.encode("utf-8")
        else:
            content = html

        # Handle string or enum for output_format
        format_value = output_format.value if hasattr(output_format, "value") else output_format

        files = {"file": (filename, content, "text/html")}
        form_data = {
            "output_format": format_value,
            "max_tokens": str(max_tokens),
            "remove_scripts": str(remove_scripts).lower(),
            "remove_styles": str(remove_styles).lower(),
            "remove_comments": str(remove_comments).lower(),
            "remove_hidden": str(remove_hidden).lower(),
            "filter_classes": str(filter_classes).lower(),
            "class_threshold": str(class_threshold),
            "try_hydration": str(try_hydration).lower(),
        }
        if preserve_selectors:
            form_data["preserve_selectors"] = ",".join(preserve_selectors)

        response = await self._http_client.post("/api/cleaner/clean/", files=files, data=form_data)
        response.raise_for_status()
        return CleanResponse.model_validate(response.json())

    async def clean_file(self, file_path: str | Path, **kwargs) -> CleanResponse:
        """Clean HTML file."""
        path = Path(file_path)
        content = path.read_bytes()
        filename = kwargs.pop("filename", path.name)
        return await self.clean(content, filename=filename, **kwargs)

    async def get(self, uuid: str) -> CleaningRequestDetail:
        """Get cleaning request details."""
        return await self._api.retrieve(uuid)

    async def list(self):
        """List cleaning requests."""
        return await self._api.list()

    async def stats(self) -> CleaningStats:
        """Get cleaning statistics."""
        return await self._api.stats_retrieve()


__all__ = [
    "CleanerResource",
    "AsyncCleanerResource",
    # Models
    "CleanRequestRequest",
    "CleanResponse",
    "CleaningRequestDetail",
    "CleaningStats",
    # Enums
    "CleanRequestRequestOutputFormat",
    "CleaningRequestDetailStatus",
    "CleaningRequestListStatus",
]
