from __future__ import annotations

from datetime import datetime
from urllib.parse import quote_plus

from fastapi import APIRouter, HTTPException, Request
from starlette.responses import RedirectResponse

from app.db import crud
from app.db.engine import get_session
from app.db.models import JobStatus
from app.tasks.execute import execute_job


router = APIRouter()

def _redirect_with_error(referer: str, msg: str) -> RedirectResponse:
    sep = "&" if "?" in referer else "?"
    return RedirectResponse(f"{referer}{sep}error={quote_plus(msg)}", status_code=303)


@router.post("/admin/joblogs/{log_id}/retry")
def retry_joblog(request: Request, log_id: int):
    session = get_session()
    try:
        log = crud.get_job_log(session, log_id)
        if not log:
            raise HTTPException(status_code=404, detail="JobLog not found")
        if log.status == JobStatus.RUNNING:
            referer = request.headers.get("Referer") or str(request.url_for("admin:details", identity="joblog", pk=str(log_id)))
            return _redirect_with_error(referer, "该任务日志正在运行中，请结束后再重试。")

        # 创建新的 RUNNING JobLog，并跳转到该条详情页
        snapshot = dict(log.snapshot_params or {})
        meta = dict(snapshot.get("meta") or {})
        meta["trigger"] = "retry"
        meta["started_at"] = datetime.utcnow().isoformat()
        snapshot["meta"] = meta

        new_log = crud.create_job_log(
            session,
            job_id=str(log.job_id),
            status=JobStatus.RUNNING,
            snapshot_params=snapshot,
            message="运行中",
            traceback="",
            run_log="",
            celery_task_id="",
            attempt=0,
            started_at=datetime.utcnow(),
            finished_at=None,
        )
        execute_job.delay(snapshot_params=snapshot, log_id=int(new_log.id))
        url = request.url_for("admin:details", identity="joblog", pk=str(new_log.id))
        return RedirectResponse(url, status_code=303)
    finally:
        session.close()

@router.post("/admin/jobs/{job_id}/run")
def run_job(request: Request, job_id: str):
    session = get_session()
    try:
        job = crud.get_job(session, job_id)
        if not job:
            raise HTTPException(status_code=404, detail="Job not found")

        snapshot = {
            "job_id": job.id,
            "handler_path": job.handler_path,
            "public_cfg": job.public_cfg or {},
            "secret_cfg": job.secret_cfg or "",
            "meta": {"trigger": "run_now", "started_at": datetime.utcnow().isoformat()},
        }
        new_log = crud.create_job_log(
            session,
            job_id=str(job.id),
            status=JobStatus.RUNNING,
            snapshot_params=snapshot,
            message="运行中",
            traceback="",
            run_log="",
            celery_task_id="",
            attempt=0,
            started_at=datetime.utcnow(),
            finished_at=None,
        )
        execute_job.delay(job_id=job.id, log_id=int(new_log.id))
        url = request.url_for("admin:details", identity="joblog", pk=str(new_log.id))
        return RedirectResponse(url, status_code=303)
    finally:
        session.close()


