"""Endpoints for typed scheduled-action status and history."""

from __future__ import annotations

import time
from typing import Any

from fastapi import APIRouter, Depends, HTTPException, Query, status

from media_library_viewer_api.dependencies import get_settings_store
from media_library_viewer_api.models.scheduler import (  # type: ignore[reportMissingImports]
    SchedulerManualRunResponse,
    SchedulerRun,
    SchedulerRunsResponse,
    SchedulerSamplesResponse,
    SchedulerStatus,
)
from media_library_viewer_api.services.qbittorrent_store import QbittorrentSampleStore
from media_library_viewer_api.services.scheduler import (  # type: ignore[reportMissingImports]
    SchedulerBusyError,
    get_scheduler,
)
from media_library_viewer_api.services.scheduler_actions import (
    QBITTORRENT_SPEED_ACTION,  # type: ignore[reportMissingImports]
)
from media_library_viewer_api.services.scheduler_store import SchedulerRunStore  # type: ignore[reportMissingImports]
from media_library_viewer_api.services.settings_store import SettingsStore

router = APIRouter(prefix="/api/scheduler", tags=["scheduler"])


def _safe_int(value: Any, default: int = 0) -> int:
    try:
        return int(value)
    except (TypeError, ValueError):
        return default


def _require_qbittorrent(service_id: str, store: SettingsStore) -> dict[str, Any]:
    service = store.get_service(service_id)
    if not service or service.get("service_type") != "qbittorrent":
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="qBittorrent service not found")
    return service


@router.get("/services/{service_id}/status", response_model=SchedulerStatus)
def get_scheduler_status(
    service_id: str,
    store: SettingsStore = Depends(get_settings_store),
) -> SchedulerStatus:
    _require_qbittorrent(service_id, store)
    try:
        return SchedulerStatus(**get_scheduler().status(service_id, store))
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=str(exc)) from exc


@router.get("/services/{service_id}/runs", response_model=SchedulerRunsResponse)
def get_scheduler_runs(
    service_id: str,
    status_filter: str | None = Query(default=None, alias="status"),
    trigger: str | None = None,
    limit: int = Query(default=50, ge=1, le=100),
    offset: int = Query(default=0, ge=0),
    store: SettingsStore = Depends(get_settings_store),
) -> SchedulerRunsResponse:
    _require_qbittorrent(service_id, store)
    items, total = SchedulerRunStore().list_runs(
        service_id,
        QBITTORRENT_SPEED_ACTION,
        status=status_filter,
        trigger=trigger,
        limit=limit,
        offset=offset,
    )
    return SchedulerRunsResponse(
        items=[SchedulerRun(**item) for item in items],
        total=total,
        limit=limit,
        offset=offset,
    )


@router.post("/services/{service_id}/run", response_model=SchedulerManualRunResponse)
def run_scheduler_action(
    service_id: str,
    store: SettingsStore = Depends(get_settings_store),
) -> SchedulerManualRunResponse:
    _require_qbittorrent(service_id, store)
    try:
        result = get_scheduler().run_now(service_id, store)
    except SchedulerBusyError as exc:
        raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=str(exc)) from exc
    except ValueError as exc:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from exc
    return SchedulerManualRunResponse(
        run=SchedulerRun(**result["run"]),
        status=SchedulerStatus(**result["status"]),
    )


@router.get("/services/{service_id}/samples", response_model=SchedulerSamplesResponse)
def get_scheduler_samples(
    service_id: str,
    window_seconds: int = Query(default=1_800, ge=60, le=86_400),
    store: SettingsStore = Depends(get_settings_store),
) -> SchedulerSamplesResponse:
    _require_qbittorrent(service_id, store)
    since_ts = _safe_int(time.time()) - window_seconds
    samples = QbittorrentSampleStore().window(service_id, since_ts=since_ts)
    return SchedulerSamplesResponse(
        service_id=service_id,
        window_seconds=window_seconds,
        samples=samples,
    )


__all__ = ["router"]
