# retoor <retoor@molodetz.nl>

import logging
from pathlib import Path

from fastapi import APIRouter, Request
from fastapi.responses import FileResponse, JSONResponse

from devplacepy.services.jobs import queue
from devplacepy.services.jobs.zip_service import ZIPS_DIR
from devplacepy.schemas import ZipJobOut
from devplacepy.utils import not_found

logger = logging.getLogger(__name__)
router = APIRouter()

RETENTION_EXTEND_SECONDS = 7 * 24 * 60 * 60


def _status_payload(job: dict) -> dict:
    result = job.get("result", {})
    done = job.get("status") == queue.DONE
    return {
        "uid": job.get("uid", ""),
        "kind": job.get("kind", ""),
        "status": job.get("status", ""),
        "preferred_name": job.get("preferred_name"),
        "download_url": result.get("download_url") if done else None,
        "error": job.get("error") or None,
        "bytes_in": int(job.get("bytes_in") or 0),
        "bytes_out": int(job.get("bytes_out") or 0),
        "item_count": int(job.get("item_count") or 0),
        "file_count": int(result.get("file_count") or 0),
        "dir_count": int(result.get("dir_count") or 0),
        "created_at": job.get("created_at"),
        "completed_at": job.get("completed_at") or None,
    }


@router.get("/{uid}")
async def zip_status(request: Request, uid: str):
    job = queue.get_job(uid)
    if not job or job.get("kind") != "zip":
        raise not_found("Job not found")
    return JSONResponse(
        ZipJobOut.model_validate(_status_payload(job)).model_dump(mode="json")
    )


@router.get("/{uid}/download")
async def zip_download(request: Request, uid: str):
    job = queue.get_job(uid)
    if not job or job.get("kind") != "zip" or job.get("status") != queue.DONE:
        raise not_found("Archive not available")
    result = job.get("result", {})
    local_path = result.get("local_path", "")
    resolved = Path(local_path).resolve()
    if (
        not local_path
        or not resolved.is_relative_to(ZIPS_DIR.resolve())
        or not resolved.is_file()
    ):
        raise not_found("Archive not available")
    queue.touch_job(uid, RETENTION_EXTEND_SECONDS)
    return FileResponse(
        resolved,
        filename=result.get("final_name", "download.zip"),
        media_type="application/zip",
    )
