"""Job management API endpoints."""

from __future__ import annotations

import json
import uuid
from typing import Optional

from fastapi import APIRouter, HTTPException, Query

from radix_edge.api.schemas import JobSubmitRequest, JobResponse
from radix_edge.db import get_db
from radix_edge.models import Job

router = APIRouter(prefix="/v1/jobs", tags=["jobs"])


@router.post("", status_code=201)
async def submit_job(req: JobSubmitRequest) -> JobResponse:
    """Submit a new job to the queue."""
    job_id = f"job-{uuid.uuid4().hex[:12]}"

    with get_db() as db:
        db.execute(
            """INSERT INTO jobs (job_id, user_id, name, image, command, args, env,
                job_type, priority, num_gpus, gpu_mem_required_mb, timeout_seconds, metadata)
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)""",
            (
                job_id,
                req.user_id,
                req.name,
                req.image,
                json.dumps(req.command) if req.command else None,
                json.dumps(req.args) if req.args else None,
                json.dumps(req.env) if req.env else None,
                req.job_type,
                req.priority,
                req.num_gpus,
                req.gpu_mem_required_mb,
                req.timeout_seconds,
                json.dumps(req.metadata) if req.metadata else None,
            ),
        )

    return JobResponse(job_id=job_id, status="queued", message="Job submitted successfully")


@router.get("")
async def list_jobs(
    status: Optional[str] = Query(None, description="Filter by status"),
    user_id: Optional[str] = Query(None, description="Filter by user"),
    limit: int = Query(100, ge=1, le=1000),
):
    """List jobs with optional filters."""
    query = "SELECT * FROM jobs WHERE 1=1"
    params: list = []

    if status:
        query += " AND status = ?"
        params.append(status)
    if user_id:
        query += " AND user_id = ?"
        params.append(user_id)

    query += " ORDER BY created_at DESC LIMIT ?"
    params.append(limit)

    with get_db() as db:
        rows = db.execute(query, params).fetchall()
        return {"jobs": [Job.from_row(r).to_dict() for r in rows]}


@router.get("/{job_id}")
async def get_job(job_id: str):
    """Get a single job's details."""
    with get_db() as db:
        row = db.execute("SELECT * FROM jobs WHERE job_id = ?", (job_id,)).fetchone()
        if not row:
            raise HTTPException(status_code=404, detail=f"Job {job_id} not found")
        return Job.from_row(row).to_dict()


@router.delete("/{job_id}")
async def cancel_job(job_id: str) -> JobResponse:
    """Cancel a job. Removes if queued, cancels if running."""
    with get_db() as db:
        row = db.execute("SELECT status FROM jobs WHERE job_id = ?", (job_id,)).fetchone()
        if not row:
            raise HTTPException(status_code=404, detail=f"Job {job_id} not found")

        current_status = row["status"]

        if current_status in ("succeeded", "failed", "cancelled"):
            raise HTTPException(
                status_code=409,
                detail=f"Job {job_id} already in terminal state: {current_status}",
            )

        if current_status == "queued":
            db.execute(
                "UPDATE jobs SET status = 'cancelled', completed_at = strftime('%Y-%m-%dT%H:%M:%fZ','now') WHERE job_id = ?",
                (job_id,),
            )
            return JobResponse(job_id=job_id, status="cancelled", message="Job removed from queue")

        # For running/scheduled jobs, mark cancelled (executor will handle cleanup)
        db.execute(
            "UPDATE jobs SET status = 'cancelled', completed_at = strftime('%Y-%m-%dT%H:%M:%fZ','now') WHERE job_id = ?",
            (job_id,),
        )

        # Release any allocated GPUs
        from radix_edge.executor.gpu_allocator import release
        freed = release(job_id)

        return JobResponse(
            job_id=job_id,
            status="cancelled",
            message=f"Job cancelled, freed GPUs: {freed}" if freed else "Job cancelled",
        )
