"""Artifact (markdown file) API routes."""

from __future__ import annotations

import json

from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel

from mixersystem.studio.config import StudioConfig
from mixersystem.studio.routes import get_config
from mixersystem.studio.scanner import WORKFLOW_STAGES
from mixersystem.studio.session_paths import resolve_session_path

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


class SaveArtifactBody(BaseModel):
    content: str


def _resolve_folder_or_400(config: StudioConfig, folder_name: str):
    try:
        return resolve_session_path(config.sessions_dir, folder_name)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e)) from e


def _load_runs(folder) -> dict:
    """Load runs dict from session.json."""
    session_json = folder / "session.json"
    if not session_json.is_file():
        return {}
    try:
        return json.loads(session_json.read_text()).get("runs", {})
    except (json.JSONDecodeError, OSError):
        return {}


def _last_run(all_runs: dict, stage: str):
    """Get the last run entry for a stage, or None."""
    entries = all_runs.get(stage, [])
    if isinstance(entries, list) and entries:
        return entries[-1]
    return None


@router.get("/{folder_name}")
def list_artifacts(folder_name: str, config: StudioConfig = Depends(get_config)):
    folder = _resolve_folder_or_400(config, folder_name)
    if not folder.is_dir():
        raise HTTPException(status_code=404, detail=f"Session folder '{folder_name}' not found")

    all_runs = _load_runs(folder)
    artifacts = {}
    for stage in WORKFLOW_STAGES:
        path = folder / f"{stage}.md"
        if path.is_file():
            artifacts[stage] = {
                "exists": True,
                "content": path.read_text(),
                "last_run": _last_run(all_runs, stage),
            }
        else:
            artifacts[stage] = {"exists": False}
    return artifacts


@router.get("/{folder_name}/{artifact}")
def get_artifact(
    folder_name: str,
    artifact: str,
    config: StudioConfig = Depends(get_config),
):
    folder = _resolve_folder_or_400(config, folder_name)
    if not folder.is_dir():
        raise HTTPException(status_code=404, detail=f"Session folder '{folder_name}' not found")

    # Ensure artifact is a valid stage name (prevent path traversal)
    base_name = artifact.removesuffix(".md")
    if base_name not in WORKFLOW_STAGES:
        raise HTTPException(status_code=400, detail=f"Invalid artifact '{artifact}'")

    path = folder / f"{base_name}.md"
    if not path.is_file():
        raise HTTPException(status_code=404, detail=f"Artifact '{artifact}' not found")

    all_runs = _load_runs(folder)
    return {"name": base_name, "content": path.read_text(), "last_run": _last_run(all_runs, base_name)}


@router.put("/{folder_name}/{artifact}")
def save_artifact(
    folder_name: str,
    artifact: str,
    body: SaveArtifactBody,
    config: StudioConfig = Depends(get_config),
):
    folder = _resolve_folder_or_400(config, folder_name)
    if not folder.is_dir():
        raise HTTPException(status_code=404, detail=f"Session folder '{folder_name}' not found")

    base_name = artifact.removesuffix(".md")
    if base_name not in WORKFLOW_STAGES:
        raise HTTPException(status_code=400, detail=f"Invalid artifact '{artifact}'")

    path = folder / f"{base_name}.md"
    path.write_text(body.content)
    return {"name": base_name, "saved": True}
