"""Scheduler API endpoints for Aniworld.

This module provides endpoints for managing scheduled tasks such as
automatic anime library rescans.
"""
import logging
from typing import Any, Dict, Optional

from fastapi import APIRouter, Depends, HTTPException, status

from src.server.models.config import SchedulerConfig
from src.server.services.config_service import ConfigServiceError, get_config_service
from src.server.services.scheduler_service import get_scheduler_service
from src.server.utils.dependencies import require_auth

logger = logging.getLogger(__name__)

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


def _build_response(config: SchedulerConfig) -> Dict[str, Any]:
    """Build a standardised GET/POST response combining config + runtime status."""
    scheduler_service = get_scheduler_service()
    runtime = scheduler_service.get_status()

    return {
        "success": True,
        "config": {
            "enabled": config.enabled,
            "interval_minutes": config.interval_minutes,
            "schedule_time": config.schedule_time,
            "schedule_days": config.schedule_days,
            "auto_download_after_rescan": config.auto_download_after_rescan,
            "folder_scan_enabled": config.folder_scan_enabled,
        },
        "status": {
            "is_running": runtime.get("is_running", False),
            "next_run": runtime.get("next_run"),
            "last_run": runtime.get("last_run"),
            "scan_in_progress": runtime.get("scan_in_progress", False),
        },
    }


@router.get("/config")
def get_scheduler_config(
    auth: Optional[dict] = Depends(require_auth),
) -> Dict[str, Any]:
    """Get current scheduler configuration along with runtime status.

    Returns:
        Combined config and status response.

    Raises:
        HTTPException: 500 if configuration cannot be loaded.
    """
    try:
        config_service = get_config_service()
        app_config = config_service.load_config()
        return _build_response(app_config.scheduler)
    except ConfigServiceError as exc:
        logger.error("Failed to load scheduler config: %s", exc)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to load scheduler configuration: {exc}",
        ) from exc


@router.post("/config")
def update_scheduler_config(
    scheduler_config: SchedulerConfig,
    auth: dict = Depends(require_auth),
) -> Dict[str, Any]:
    """Update scheduler configuration and apply changes immediately.

    Accepts the full SchedulerConfig body; any fields not supplied default
    to their model defaults (backward compatible).

    Returns:
        Combined config and status response reflecting the saved config.

    Raises:
        HTTPException: 422 on validation errors (handled by FastAPI/Pydantic),
            500 on save or scheduler failure.
    """
    try:
        config_service = get_config_service()
        app_config = config_service.load_config()
        app_config.scheduler = scheduler_config
        config_service.save_config(app_config)

        logger.info(
            "Scheduler config updated by %s: time=%s days=%s auto_dl=%s",
            auth.get("username", "unknown"),
            scheduler_config.schedule_time,
            scheduler_config.schedule_days,
            scheduler_config.auto_download_after_rescan,
        )

        # Apply changes to the running scheduler without restart
        try:
            sched_svc = get_scheduler_service()
            sched_svc.reload_config(scheduler_config)
        except Exception as sched_exc:  # pylint: disable=broad-exception-caught
            logger.error("Scheduler reload after config update failed: %s", sched_exc)
            # Config was saved — don't fail the request, just warn

        return _build_response(scheduler_config)

    except ConfigServiceError as exc:
        logger.error("Failed to update scheduler config: %s", exc)
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to update scheduler configuration: {exc}",
        ) from exc


@router.post("/trigger-rescan", response_model=Dict[str, str])
async def trigger_rescan(auth: dict = Depends(require_auth)) -> Dict[str, str]:
    """Manually trigger a library rescan (and auto-download if configured).

    Args:
        auth: Authentication token (required)

    Returns:
        Dict with success message

    Raises:
        HTTPException: If rescan cannot be triggered
    """
    try:
        from src.server.utils.dependencies import get_series_app  # noqa: PLC0415

        series_app = get_series_app()
        if not series_app:
            raise HTTPException(
                status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
                detail="SeriesApp not initialized",
            )

        logger.info(
            "Manual rescan triggered by %s", auth.get("username", "unknown")
        )

        from src.server.api.anime import trigger_rescan as do_rescan  # noqa: PLC0415

        return await do_rescan()

    except HTTPException:
        raise
    except Exception as exc:
        logger.exception("Failed to trigger manual rescan")
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Failed to trigger rescan: {exc}",
        ) from exc
