from typing import List, Optional

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

from nexus_agent.core.skill_manager import skill_manager
from nexus_agent.models.skill import (
    CreateSkillRequest,
    SkillDetail,
    SkillInfo,
    UpdateSkillRequest,
)

router = APIRouter()


@router.get("/", response_model=List[SkillInfo])
async def list_skills():
    return skill_manager.get_all_skills()


@router.get("/{name}", response_model=SkillDetail)
async def get_skill(name: str):
    detail = skill_manager.load_skill_content(name)
    if not detail:
        raise HTTPException(status_code=404, detail=f"Skill not found: {name}")
    return detail


@router.post("/", response_model=SkillInfo)
async def create_skill(req: CreateSkillRequest):
    try:
        return skill_manager.create_skill(req.name, req.description, req.instructions)
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.delete("/{name}")
async def delete_skill(name: str):
    if not skill_manager.delete_skill(name):
        raise HTTPException(status_code=404, detail=f"Skill not found: {name}")
    return {"status": "deleted", "name": name}


@router.patch("/{name}", response_model=SkillInfo)
async def update_skill(name: str, req: UpdateSkillRequest):
    result = skill_manager.update_skill(
        name,
        description=req.description,
        instructions=req.instructions,
        enabled=req.enabled,
    )
    if not result:
        raise HTTPException(status_code=404, detail=f"Skill not found: {name}")
    return result


@router.post("/{name}/execute")
async def execute_script(name: str, script: str, args: Optional[List[str]] = None):
    skill = skill_manager.get_skill(name)
    if not skill:
        raise HTTPException(status_code=404, detail=f"Skill not found: {name}")
    result = await skill_manager.execute_script(name, script, args)
    return result


@router.post("/reload")
async def reload_skills():
    if skill_manager._base_dirs:
        skill_manager.discover_skills([str(d) for d in skill_manager._base_dirs])
    return {"status": "reloaded", "count": len(skill_manager.get_all_skills())}


@router.post("/upload", response_model=SkillInfo)
async def upload_skill_zip(file: UploadFile = File(...)):
    """zip 파일을 업로드하여 스킬 등록"""
    if not file.filename or not file.filename.endswith(".zip"):
        raise HTTPException(status_code=400, detail="zip 파일만 업로드 가능합니다.")
    try:
        data = await file.read()
        return skill_manager.import_from_zip_bytes(data, file.filename)
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))


class ImportPathRequest(BaseModel):
    path: str


@router.post("/import", response_model=SkillInfo)
async def import_skill_from_path(req: ImportPathRequest):
    """로컬 경로의 스킬 폴더를 등록"""
    try:
        return skill_manager.import_from_path(req.path)
    except Exception as e:
        raise HTTPException(status_code=400, detail=str(e))
