"""DagRun API routes."""
from __future__ import annotations

from fastapi import APIRouter, HTTPException
from sqlalchemy import select

from crondag.models.base import get_session_factory
from crondag.models.dag_run import DagRunModel
from crondag.models.task_instance import TaskInstanceModel
from crondag.sdk.state import DagRunState

router = APIRouter(tags=["runs"])


@router.get("/dags/{dag_id}/runs")
async def list_runs(dag_id: str, limit: int = 20):
    """List runs for a DAG."""
    session_factory = get_session_factory()
    async with session_factory() as session:
        result = await session.execute(
            select(DagRunModel)
            .where(DagRunModel.dag_id == dag_id)
            .order_by(DagRunModel.created_at.desc())
            .limit(limit)
        )
        runs = result.scalars().all()
        return [
            {
                "id": r.id,
                "run_id": r.run_id,
                "state": r.state,
                "run_type": r.run_type,
                "logical_date": str(r.logical_date),
                "start_date": str(r.start_date),
                "end_date": str(r.end_date),
            }
            for r in runs
        ]


@router.get("/runs/{run_id}")
async def get_run(run_id: str):
    """Get run details with task instances."""
    session_factory = get_session_factory()
    async with session_factory() as session:
        result = await session.execute(
            select(DagRunModel).where(DagRunModel.run_id == run_id)
        )
        run = result.scalar_one_or_none()
        if not run:
            raise HTTPException(status_code=404, detail=f"Run '{run_id}' not found")

        ti_result = await session.execute(
            select(TaskInstanceModel).where(
                TaskInstanceModel.run_id == run_id,
                TaskInstanceModel.dag_id == run.dag_id,
            )
        )
        tasks = ti_result.scalars().all()

        return {
            "id": run.id,
            "dag_id": run.dag_id,
            "run_id": run.run_id,
            "state": run.state,
            "run_type": run.run_type,
            "logical_date": str(run.logical_date),
            "start_date": str(run.start_date),
            "end_date": str(run.end_date),
            "conf": run.conf,
            "tasks": [
                {
                    "id": ti.id,
                    "task_id": ti.task_id,
                    "state": ti.state,
                    "try_number": ti.try_number,
                    "start_date": str(ti.start_date),
                    "end_date": str(ti.end_date),
                    "duration": ti.duration,
                    "error": ti.error,
                }
                for ti in tasks
            ],
        }


@router.get("/runs/active")
async def active_runs():
    """List all active runs."""
    session_factory = get_session_factory()
    async with session_factory() as session:
        result = await session.execute(
            select(DagRunModel)
            .where(DagRunModel.state.in_([DagRunState.QUEUED, DagRunState.RUNNING]))
            .order_by(DagRunModel.created_at.desc())
        )
        runs = result.scalars().all()
        return [
            {
                "id": r.id,
                "dag_id": r.dag_id,
                "run_id": r.run_id,
                "state": r.state,
                "start_date": str(r.start_date),
            }
            for r in runs
        ]
