"""Jellyseerr HTTP API client.

Jellyseerr is optional. When configured, it can enrich the Jellyfin user list
with email addresses, avatars, permissions, and request metadata.
"""

from __future__ import annotations

import logging
from typing import Any

import requests

logger = logging.getLogger(__name__)


class JellyseerrClient:
    """Small wrapper around the Jellyseerr REST API."""

    def __init__(self, base_url: str, api_key: str, timeout: int = 30):
        if not base_url:
            raise ValueError("Jellyseerr URL is required")
        if not api_key:
            raise ValueError("Jellyseerr API key is required")

        self.base_url = base_url.rstrip("/")
        if self.base_url.endswith("/api/v1"):
            self.base_url = self.base_url[:-7]
        self.api_key = api_key
        self.timeout = timeout
        self.session = requests.Session()
        self.session.headers.update(
            {
                "X-Api-Key": api_key,
                "Accept": "application/json",
            }
        )

    def get(self, path: str, **params: Any) -> Any:
        """GET a Jellyseerr endpoint and include useful response text on errors."""
        clean_params = {k: v for k, v in params.items() if v is not None and v != ""}
        logger.debug("Jellyseerr GET %s params=%s", path, sorted(clean_params.keys()))
        response = self.session.get(f"{self.base_url}/api/v1{path}", params=clean_params, timeout=self.timeout)
        try:
            response.raise_for_status()
        except requests.HTTPError as exc:
            detail = response.text[:500]
            logger.warning("Jellyseerr GET %s failed status=%s url=%s", path, response.status_code, response.url)
            raise requests.HTTPError(
                f"{response.status_code} for {response.url}: {detail}",
                response=response,
            ) from exc
        logger.debug("Jellyseerr GET %s ok status=%s", path, response.status_code)
        return response.json()

    def absolute_url(self, path: str | None) -> str:
        """Return an absolute URL for Jellyseerr-relative assets."""
        if not path:
            return ""
        if path.startswith("http://") or path.startswith("https://"):
            return path
        if not path.startswith("/"):
            path = f"/{path}"
        return f"{self.base_url}{path}"

    def jellyfin_users(self) -> list[dict[str, Any]]:
        """Return Jellyfin-linked users known to Jellyseerr.

        Jellyseerr has used both a top-level list payload and a wrapped
        `{ "users": [...] }` payload in different versions/docs, so accept
        either shape.
        """
        payload = self.get("/settings/jellyfin/users")
        if isinstance(payload, list):
            users = [item for item in payload if isinstance(item, dict)]
            logger.info("Jellyseerr returned %s Jellyfin-linked users", len(users))
            return users
        if isinstance(payload, dict):
            users = payload.get("users")
            if isinstance(users, list):
                mapped = [item for item in users if isinstance(item, dict)]
                logger.info("Jellyseerr returned %s Jellyfin-linked users (wrapped payload)", len(mapped))
                return mapped
        logger.info("Jellyseerr returned no Jellyfin-linked users")
        return []

    def users(self, page_size: int = 1000) -> list[dict[str, Any]]:
        """Return Jellyseerr users via the paginated /user list endpoint.

        Jellyseerr's list endpoint uses ``take`` and ``skip`` query params,
        not ``page``.
        """
        results: list[dict[str, Any]] = []
        take = max(1, int(page_size))
        skip = 0
        total_results: int | None = None

        while True:
            payload = self.get("/user", take=take, skip=skip)
            if not isinstance(payload, dict):
                return results

            page_results = payload.get("results") or []
            page_items = (
                [item for item in page_results if isinstance(item, dict)] if isinstance(page_results, list) else []
            )
            results.extend(page_items)

            page_info = payload.get("pageInfo") or {}
            if isinstance(page_info, dict):
                try:
                    page_total = int(page_info.get("results") or 0)
                    if page_total:
                        total_results = page_total
                except (TypeError, ValueError):
                    pass

            logger.debug(
                "Jellyseerr user page skip=%s take=%s -> %s results (total=%s)",
                skip,
                take,
                len(page_items),
                total_results if total_results is not None else "unknown",
            )

            if not page_items:
                break
            skip += len(page_items)
            if len(page_items) < take:
                break
            if total_results is not None and skip >= total_results:
                break

        logger.info("Jellyseerr returned %s users", len(results))
        return results
