from __future__ import annotations

import logging
from datetime import datetime
from enum import Enum
from typing import Optional

from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session

from src.apps.admin.capabilities import AdminCap
from src.apps.admin.dependencies import require_admin_capability
from src.apps.auth.utils.auth import get_current_superuser
from src.core.database import get_session
from src.apps.admin.schemas.scheduler_schemas import (
    HealthSummaryResponse,
    SchedulerDetail,
    SchedulerLogListResponse,
    SchedulerLogResponse,
    SchedulerSummary,
    TriggerSchedulerRequest,
    UpdateSchedulerConfigRequest,
)
from src.apps.admin.scheduler_crud import get_scheduler_logs
from src.apps.admin.scheduler_services import (
    get_health_summary,
    get_scheduler_detail,
    get_scheduler_list,
    pause_resume_scheduler,
    retry_scheduler_log,
    trigger_scheduler,
    update_scheduler_config,
)

logger = logging.getLogger(__name__)

router = APIRouter()


class RunStatusFilter(str, Enum):
    SUCCESS = "SUCCESS"
    FAILED = "FAILED"
    RUNNING = "RUNNING"
    SKIPPED = "SKIPPED"


# ── Literal routes FIRST — must precede /{task_name} to avoid shadowing ──────

@router.get("", response_model=list[SchedulerSummary])
async def list_schedulers(
    current_user=Depends(get_current_superuser),
    _cap=Depends(require_admin_capability(AdminCap.SCHEDULERS_READ)),
    db: Session = Depends(get_session),
):
    """List all known schedulers with last-run stats."""
    return get_scheduler_list(db)


@router.get("/health-summary", response_model=HealthSummaryResponse)
async def health_summary(
    current_user=Depends(get_current_superuser),
    _cap=Depends(require_admin_capability(AdminCap.SCHEDULERS_READ)),
    db: Session = Depends(get_session),
):
    """Aggregate health card for the dashboard."""
    summary = get_health_summary(db)
    return HealthSummaryResponse(
        total=summary["total"],
        healthy=summary["healthy"],
        failing=summary["failing"],
        paused=summary["paused"],
        recent_failures=[
            SchedulerLogResponse.model_validate(f) for f in summary["recent_failures"]
        ],
    )


@router.get("/logs", response_model=SchedulerLogListResponse)
async def all_logs(
    status: Optional[RunStatusFilter] = Query(None),
    start_date: Optional[datetime] = Query(None),
    end_date: Optional[datetime] = Query(None),
    merchant_id: Optional[int] = Query(None),
    page: int = Query(1, ge=1),
    page_size: int = Query(20, ge=1, le=100),
    current_user=Depends(get_current_superuser),
    _cap=Depends(require_admin_capability(AdminCap.SCHEDULERS_READ)),
    db: Session = Depends(get_session),
):
    """All scheduler logs, paginated and filterable across all tasks."""
    logs, total = get_scheduler_logs(
        db,
        status=status.value if status else None,
        start_date=start_date,
        end_date=end_date,
        merchant_id=merchant_id,
        page=page,
        page_size=page_size,
    )
    return SchedulerLogListResponse(
        items=[SchedulerLogResponse.model_validate(lg) for lg in logs],
        total=total,
        page=page,
        page_size=page_size,
    )


@router.post("/logs/{log_id}/retry")
async def retry_log(
    log_id: int,
    current_user=Depends(get_current_superuser),
    _cap=Depends(require_admin_capability(AdminCap.SCHEDULERS_MANAGE)),
    db: Session = Depends(get_session),
):
    """Retry a failed scheduler run."""
    return retry_scheduler_log(db, log_id, current_user)


# ── Parameterised routes AFTER all literal routes ────────────────────────────

@router.get("/{task_name}", response_model=SchedulerDetail)
async def scheduler_detail(
    task_name: str,
    current_user=Depends(get_current_superuser),
    _cap=Depends(require_admin_capability(AdminCap.SCHEDULERS_READ)),
    db: Session = Depends(get_session),
):
    """Detail view: config, 30-day stats, and recent logs."""
    return get_scheduler_detail(db, task_name)


@router.patch("/{task_name}/config")
async def update_config(
    task_name: str,
    body: UpdateSchedulerConfigRequest,
    current_user=Depends(get_current_superuser),
    _cap=Depends(require_admin_capability(AdminCap.SCHEDULERS_MANAGE)),
    db: Session = Depends(get_session),
):
    """Update is_enabled, alert_threshold_ms, or log_retention_days."""
    config = update_scheduler_config(db, task_name, body, current_user)
    return {"task_name": config.task_name, "is_enabled": config.is_enabled,
            "alert_threshold_ms": config.alert_threshold_ms,
            "log_retention_days": config.log_retention_days}


@router.post("/{task_name}/trigger")
async def trigger(
    task_name: str,
    body: TriggerSchedulerRequest,
    current_user=Depends(get_current_superuser),
    _cap=Depends(require_admin_capability(AdminCap.SCHEDULERS_MANAGE)),
    db: Session = Depends(get_session),
):
    """Manually trigger a scheduler task."""
    return trigger_scheduler(db, task_name, body, current_user)


@router.get("/{task_name}/logs", response_model=SchedulerLogListResponse)
async def scheduler_logs(
    task_name: str,
    status: Optional[RunStatusFilter] = Query(None),
    start_date: Optional[datetime] = Query(None),
    end_date: Optional[datetime] = Query(None),
    merchant_id: Optional[int] = Query(None),
    page: int = Query(1, ge=1),
    page_size: int = Query(20, ge=1, le=100),
    current_user=Depends(get_current_superuser),
    _cap=Depends(require_admin_capability(AdminCap.SCHEDULERS_READ)),
    db: Session = Depends(get_session),
):
    """Logs for a specific scheduler task, paginated and filterable."""
    logs, total = get_scheduler_logs(
        db,
        task_name=task_name,
        status=status.value if status else None,
        start_date=start_date,
        end_date=end_date,
        merchant_id=merchant_id,
        page=page,
        page_size=page_size,
    )
    return SchedulerLogListResponse(
        items=[SchedulerLogResponse.model_validate(lg) for lg in logs],
        total=total,
        page=page,
        page_size=page_size,
    )
