"""Session folder 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 discover_session_folders, discover_session_tree, scan_session_folder
from mixersystem.studio.session_paths import resolve_session_path, validate_session_name

router = APIRouter(prefix="/api/v1/session-folders", tags=["session-folders"])


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


def _folder_to_dict(info) -> dict:
    result = {
        "name": info.name,
        "path": str(info.path),
        "artifacts": info.artifacts,
        "has_questions": info.has_questions,
        "current_stage": info.current_stage,
        "last_activity": info.last_activity,
    }
    if info.trace_summary:
        result["cost_summary"] = {
            "total_calls": info.trace_summary.total_calls,
            "total_duration_seconds": round(info.trace_summary.total_duration_seconds, 2),
            "total_cost_usd": round(info.trace_summary.total_cost_usd, 4),
            "agents": info.trace_summary.agents,
        }
    # Include session.json metadata if present
    session_json = info.path / "session.json"
    if session_json.is_file():
        try:
            result["metadata"] = json.loads(session_json.read_text())
        except (json.JSONDecodeError, OSError):
            pass
    if info.children:
        result["children"] = [_folder_to_dict(c) for c in info.children]
    return result


@router.get("")
def list_session_folders(config: StudioConfig = Depends(get_config)):
    folders = discover_session_tree(config.sessions_dir)
    return [_folder_to_dict(f) for f in folders]


@router.get("/{name:path}")
def get_session_folder(name: str, config: StudioConfig = Depends(get_config)):
    folder_path = _resolve_session_path_or_400(config, name)
    if not folder_path.is_dir():
        raise HTTPException(status_code=404, detail=f"Session folder '{name}' not found")
    info = scan_session_folder(folder_path)
    return _folder_to_dict(info)


@router.post("", status_code=201)
def create_session_folder(name: str, config: StudioConfig = Depends(get_config)):
    folder_path = _resolve_session_path_or_400(config, name)
    validated_name = validate_session_name(name)
    if folder_path.exists():
        raise HTTPException(status_code=409, detail=f"Session folder '{name}' already exists")
    folder_path.mkdir(parents=True, exist_ok=True)
    from mixersystem.data.repository import init_session
    init_session(str(folder_path))
    return {"name": validated_name, "path": str(folder_path)}


@router.delete("/{name:path}", status_code=200)
def delete_session_folder(name: str, config: StudioConfig = Depends(get_config)):
    import shutil

    folder_path = _resolve_session_path_or_400(config, name)
    if not folder_path.is_dir():
        raise HTTPException(status_code=404, detail=f"Session folder '{name}' not found")
    shutil.rmtree(folder_path)
    return {"deleted": folder_path.name}


class RenameRequest(BaseModel):
    new_name: str


@router.patch("/{name:path}/rename")
def rename_session_folder(name: str, body: RenameRequest, config: StudioConfig = Depends(get_config)):
    folder_path = _resolve_session_path_or_400(config, name)
    if not folder_path.is_dir():
        raise HTTPException(status_code=404, detail=f"Session folder '{name}' not found")
    new_path = _resolve_session_path_or_400(config, body.new_name)
    if new_path.exists():
        raise HTTPException(status_code=409, detail=f"Session folder '{body.new_name}' already exists")
    folder_path.rename(new_path)
    return {"old_name": name, "new_name": validate_session_name(body.new_name)}


@router.post("/{name:path}/archive", status_code=200)
def archive_session_folder(name: str, config: StudioConfig = Depends(get_config)):
    folder_path = _resolve_session_path_or_400(config, name)
    if not folder_path.is_dir():
        raise HTTPException(status_code=404, detail=f"Session folder '{name}' not found")
    archive_dir = config.sessions_dir / "_archived"
    archive_dir.mkdir(parents=True, exist_ok=True)
    dest = archive_dir / folder_path.name
    if dest.exists():
        # Append timestamp to avoid collision
        from datetime import datetime
        ts = datetime.now().strftime("%Y%m%d-%H%M%S")
        dest = archive_dir / f"{folder_path.name}_{ts}"
    folder_path.rename(dest)
    return {"archived": name}


class UpdateModulesRequest(BaseModel):
    modules: list[str]


@router.patch("/{name:path}/modules")
def update_modules(name: str, body: UpdateModulesRequest, config: StudioConfig = Depends(get_config)):
    folder_path = _resolve_session_path_or_400(config, name)
    if not folder_path.is_dir():
        raise HTTPException(status_code=404, detail=f"Session folder '{name}' not found")
    from mixersystem.data.repository import update_session_json
    update_session_json(str(folder_path), modules=body.modules, modules_locked=True)
    return {"modules": body.modules}
