"""API routes for OpenClaw cron pool management."""

from datetime import datetime

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field
from sqlmodel import Session, select

from agenteval.intelligent_eval import cron_pool
from agenteval.intelligent_eval.openclaw_client import OpenClawClient
from agenteval.storage.db import OpenClawCronPoolDB, utc_now
from agenteval.web.deps import get_db

router = APIRouter()


class ScaleRequest(BaseModel):
    target_size: int = Field(ge=1, le=50)


class HeartbeatRequest(BaseModel):
    status: str  # idle / busy
    current_eval_id: str | None = None


@router.get("/cron-pool")
async def get_cron_pool_status(session: Session = Depends(get_db)) -> dict:
    """Get cron pool status."""
    status = cron_pool.get_pool_status(session)
    return {"pool": status}


@router.post("/cron-pool/scale")
async def scale_cron_pool(request: ScaleRequest, session: Session = Depends(get_db)) -> dict:
    """Manually scale cron pool to target size."""
    current_status = cron_pool.get_pool_status(session)
    current_size = current_status["total"]
    target_size = request.target_size

    client = OpenClawClient()

    if target_size > current_size:
        # Scale up
        count = target_size - current_size
        created = await cron_pool.scale_up(count, session, client)
        return {"success": True, "scaled_up": created, "current_size": current_size + created}
    elif target_size < current_size:
        # Scale down
        count = current_size - target_size
        deleted = await cron_pool.scale_down(count, session, client)
        return {"success": True, "scaled_down": deleted, "current_size": current_size - deleted}
    else:
        return {"success": True, "current_size": current_size, "message": "already at target size"}


@router.post("/cron-pool/sync")
async def sync_cron_states(session: Session = Depends(get_db)) -> dict:
    """Sync cron states from OpenClaw to platform DB."""
    client = OpenClawClient()
    synced = await cron_pool.sync_cron_states(session, client)
    return {"success": True, "synced": synced}


@router.post("/cron-pool/auto-scale")
async def auto_scale_pool(session: Session = Depends(get_db)) -> dict:
    """Trigger auto-scaling based on current load."""
    client = OpenClawClient()
    scaled_up, scaled_down = await cron_pool.auto_scale(session, client)
    return {
        "success": True,
        "scaled_up": scaled_up,
        "scaled_down": scaled_down,
    }


@router.post("/crons/{cron_id}/heartbeat")
async def report_heartbeat(
    cron_id: str,
    request: HeartbeatRequest,
    session: Session = Depends(get_db),
) -> dict:
    """Report cron heartbeat.

    Updates the cron's last_active_at timestamp and current status.
    """
    # Find cron by openclaw_cron_id
    cron = session.exec(
        select(OpenClawCronPoolDB).where(OpenClawCronPoolDB.openclaw_cron_id == cron_id)
    ).first()

    if cron is None:
        raise HTTPException(status_code=404, detail=f"cron {cron_id} not found")

    # Update heartbeat
    cron.last_active_at = utc_now()
    cron.status = request.status
    cron.current_eval_id = request.current_eval_id
    cron.updated_at = utc_now()

    session.commit()

    return {"success": True}


@router.get("/cron-pool/metrics")
async def get_cron_pool_metrics(session: Session = Depends(get_db)) -> dict:
    """Get cron pool metrics."""
    from agenteval.intelligent_eval.metrics import get_all_metrics

    metrics = get_all_metrics(session)
    return {"metrics": metrics}


@router.post("/cron-pool/check-alerts")
async def check_alerts(session: Session = Depends(get_db)) -> dict:
    """Check alert rules and create alerts if triggered."""
    from agenteval.intelligent_eval.alerts import AlertManager

    manager = AlertManager(session)
    alerts = manager.check_rules()

    return {
        "success": True,
        "alerts_triggered": len(alerts),
        "alerts": [
            {
                "id": alert.id,
                "alert_type": alert.alert_type,
                "severity": alert.severity,
                "message": alert.message,
                "metric_value": alert.metric_value,
                "threshold": alert.threshold,
                "created_at": alert.created_at.isoformat(),
            }
            for alert in alerts
        ],
    }


@router.get("/cron-pool/alerts")
async def get_alert_history(
    limit: int = 100,
    unresolved_only: bool = False,
    session: Session = Depends(get_db),
) -> dict:
    """Get alert history."""
    from agenteval.intelligent_eval.alerts import AlertManager

    manager = AlertManager(session)

    if unresolved_only:
        alerts = manager.get_unresolved_alerts()
    else:
        alerts = manager.get_alert_history(limit=limit)

    return {
        "alerts": [
            {
                "id": alert.id,
                "alert_type": alert.alert_type,
                "severity": alert.severity,
                "message": alert.message,
                "metric_value": alert.metric_value,
                "threshold": alert.threshold,
                "created_at": alert.created_at.isoformat(),
                "resolved_at": alert.resolved_at.isoformat() if alert.resolved_at else None,
                "webhook_sent": alert.webhook_sent,
            }
            for alert in alerts
        ]
    }


@router.post("/cron-pool/alerts/{alert_id}/resolve")
async def resolve_alert(alert_id: str, session: Session = Depends(get_db)) -> dict:
    """Resolve an alert."""
    from agenteval.intelligent_eval.alerts import AlertManager

    manager = AlertManager(session)
    resolved = manager.resolve_alert(alert_id)

    if not resolved:
        raise HTTPException(status_code=404, detail=f"alert {alert_id} not found")

    return {"success": True}
