"""Jellyfin service definition."""

from __future__ import annotations

from typing import TYPE_CHECKING, Any, Literal

from media_library_viewer_api.clients.jellyfin import JellyfinClient
from media_library_viewer_api.integrations.base import (
    SecretField,
    ServiceBaseUrl,
    ServiceConfigBase,
    ServiceDefinition,
    TestResult,
    WidgetConfigBase,
    translate_connection_error,
    widget_kind,
)

if TYPE_CHECKING:
    from media_library_viewer_api.services.settings_store import SettingsStore


def test_connection(
    config: dict[str, Any],
    secrets: dict[str, str],
    store: SettingsStore,
) -> TestResult:
    """Call JellyfinClient.users() — the lightest authenticated probe."""
    try:
        base_url = str(config.get("base_url") or "")
        api_key = str(secrets.get("api_key") or "")
        timeout = int(config.get("timeout_seconds") or 60)
        client = JellyfinClient(base_url, api_key, timeout=timeout)
        users = client.users()
        return TestResult(ok=True, detail="Connected to Jellyfin.", evidence=f"{len(users)} users")
    except Exception as exc:
        return translate_connection_error(exc, context="Jellyfin")


class JellyfinConfig(ServiceConfigBase):
    """Non-secret Jellyfin connection config.

    The optional ``jellyseerr_url`` field pairs a Jellyseerr companion with this
    Jellyfin instance; the matching ``jellyseerr_api_key`` is a secret field on
    the service. When both are set, the Jellyfin service page renders a Requests
    tab backed by Jellyseerr.
    """

    base_url: ServiceBaseUrl
    user_id: str = ""
    timeout_seconds: int = 60
    jellyseerr_url: str = ""


class JellyfinActivityWidgetConfig(WidgetConfigBase):
    """Live Jellyfin session activity."""

    # No user-overridable fields; the service record carries user_id.
    pass


class JellyfinNowPlayingWidgetConfig(WidgetConfigBase):
    """Only show sessions with active playback (not idle/paused)."""

    pass


class JellyfinRequestStatWidgetConfig(WidgetConfigBase):
    """A single Jellyseerr request stat (e.g. pending / approved / total)."""

    stat: Literal[
        "total",
        "pending",
        "approved",
        "declined",
        "processing",
        "available",
    ] = "pending"


class JellyfinRequestsOverviewWidgetConfig(WidgetConfigBase):
    """Grid of all Jellyseerr request stats + a recent-requests list."""

    pass


DEFINITION = ServiceDefinition(
    service_type="jellyfin",
    name="Jellyfin",
    description="Media server with live session activity.",
    config_model=JellyfinConfig,
    secret_fields=[
        SecretField(key="api_key", label="API key", required=True),
        SecretField(
            key="jellyseerr_api_key",
            label="Jellyseerr API key",
            required=False,
            helper="Enables the Requests tab + request-stats widgets (optional).",
        ),
    ],
    widget_kinds=[
        widget_kind(
            kind="activity",
            name="Activity",
            description="Live sessions and idle users.",
            model_cls=JellyfinActivityWidgetConfig,
            default_config={},
            refresh_interval_ms=30_000,
        ),
        widget_kind(
            kind="now_playing",
            name="Now Playing",
            description="Only sessions actively playing media.",
            model_cls=JellyfinNowPlayingWidgetConfig,
            default_config={},
            refresh_interval_ms=30_000,
        ),
        widget_kind(
            kind="stat",
            name="Request stat",
            description="A single Jellyseerr request statistic (e.g. pending requests).",
            model_cls=JellyfinRequestStatWidgetConfig,
            default_config={"stat": "pending"},
            refresh_interval_ms=60_000,
        ),
        widget_kind(
            kind="stats_overview",
            name="Requests overview",
            description="All Jellyseerr request stats plus a recent-requests list.",
            model_cls=JellyfinRequestsOverviewWidgetConfig,
            default_config={},
            refresh_interval_ms=60_000,
        ),
    ],
    test_callable=test_connection,
)
