"""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


def _split_folder_and_artifact(path: str) -> tuple[str, str]:
    """Split a path like 'parent/child/task' into ('parent/child', 'task')."""
    parts = path.rsplit("/", 1)
    if len(parts) != 2:
        raise HTTPException(status_code=400, detail="Invalid path")
    return parts[0], parts[1]


@router.get("/{folder_name:path}")
def list_or_get_artifact(folder_name: str, config: StudioConfig = Depends(get_config)):
    """List all artifacts, or get a single artifact if the last segment is a stage name."""
    # Check if the last segment is an artifact name
    parts = folder_name.rsplit("/", 1)
    if len(parts) == 2 and parts[1].removesuffix(".md") in WORKFLOW_STAGES:
        return _get_artifact(parts[0], parts[1], config)
    return _list_artifacts(folder_name, config)


def _list_artifacts(folder_name: str, config: StudioConfig):
    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


def _get_artifact(folder_name: str, artifact: str, config: StudioConfig):
    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"
    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.delete("/{path:path}")
def delete_artifact(path: str, config: StudioConfig = Depends(get_config)):
    folder_name, artifact = _split_folder_and_artifact(path)
    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}'")

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

    artifact_path.unlink()
    return {"name": base_name, "deleted": True}


@router.put("/{path:path}")
def save_artifact(path: str, body: SaveArtifactBody, config: StudioConfig = Depends(get_config)):
    folder_name, artifact = _split_folder_and_artifact(path)
    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}'")

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