"""Skill registry CRUD endpoints + skill execution."""

from __future__ import annotations

from fastapi import APIRouter, HTTPException, UploadFile, File
from pydantic import BaseModel

from Project.Sanad.config import AUDIO_RECORDINGS_DIR
from Project.Sanad.dashboard.routes._safe_io import (
    safe_path_under, check_upload_size, atomic_write_bytes,
)

router = APIRouter()


class SkillCreate(BaseModel):
    id: str = ""
    audio_file: str = ""
    motion_file: str = ""
    callback: str = ""
    sync_mode: str = "parallel"
    enabled: bool = True
    description: str = ""


class SkillUpdate(BaseModel):
    audio_file: str | None = None
    motion_file: str | None = None
    callback: str | None = None
    sync_mode: str | None = None
    enabled: bool | None = None
    description: str | None = None


@router.get("/")
async def list_skills():
    from Project.Sanad.main import brain
    return {"skills": brain.registry.list_skills()}


@router.get("/{skill_id}")
async def get_skill(skill_id: str):
    from Project.Sanad.main import brain
    skill = brain.registry.get(skill_id)
    if skill is None:
        raise HTTPException(404, f"Skill not found: {skill_id}")
    return skill.to_dict()


@router.post("/")
async def create_skill(payload: SkillCreate):
    from Project.Sanad.main import brain
    from Project.Sanad.core.skill_registry import Skill
    try:
        skill = Skill(**payload.model_dump())
        created = brain.registry.add(skill)
    except ValueError as exc:
        raise HTTPException(400, str(exc))
    return {"ok": True, "skill": created.to_dict()}


@router.put("/{skill_id}")
async def update_skill(skill_id: str, payload: SkillUpdate):
    from Project.Sanad.main import brain
    updates = {k: v for k, v in payload.model_dump().items() if v is not None}
    try:
        updated = brain.registry.update(skill_id, updates)
    except ValueError as exc:
        raise HTTPException(400, str(exc))
    if updated is None:
        raise HTTPException(404, f"Skill not found: {skill_id}")
    return {"ok": True, "skill": updated.to_dict()}


@router.delete("/{skill_id}")
async def delete_skill(skill_id: str):
    from Project.Sanad.main import brain
    deleted = brain.registry.delete(skill_id)
    if not deleted:
        raise HTTPException(404, f"Skill not found: {skill_id}")
    return {"ok": True, "deleted": deleted}


@router.post("/{skill_id}/execute")
async def execute_skill(skill_id: str):
    from Project.Sanad.main import brain
    result = await brain.execute_skill(skill_id)
    return result


@router.post("/upload-audio")
async def upload_audio(file: UploadFile = File(...)):
    """Upload a .wav file for skill binding."""
    if not file.filename or not file.filename.lower().endswith(".wav"):
        raise HTTPException(400, "Only .wav files are accepted.")
    AUDIO_RECORDINGS_DIR.mkdir(parents=True, exist_ok=True)
    dest = safe_path_under(AUDIO_RECORDINGS_DIR, file.filename)
    content = await file.read()
    check_upload_size(content)
    atomic_write_bytes(dest, content)
    return {"ok": True, "path": str(dest), "size_bytes": len(content)}
