import mimetypes
from typing import Optional

from fastapi import APIRouter, HTTPException
from fastapi.responses import FileResponse

from nexus_agent.core.workspace_manager import workspace_manager
from nexus_agent.models.workspace import (
    CreateWorkspaceRequest,
    EditFileRequest,
    FileContent,
    FileTreeNode,
    UpdateWorkspaceRequest,
    WorkspaceInfo,
    WriteFileRequest,
)

router = APIRouter()


@router.get("/", response_model=list[WorkspaceInfo])
async def list_workspaces():
    return workspace_manager.get_all()


@router.post("/", response_model=WorkspaceInfo)
async def create_workspace(req: CreateWorkspaceRequest):
    try:
        return workspace_manager.create_workspace(req.name, req.path, req.description)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/{workspace_id}", response_model=WorkspaceInfo)
async def get_workspace(workspace_id: str):
    ws = workspace_manager.get_workspace(workspace_id)
    if not ws:
        raise HTTPException(status_code=404, detail="Workspace not found")
    return ws


@router.patch("/{workspace_id}", response_model=WorkspaceInfo)
async def update_workspace(workspace_id: str, req: UpdateWorkspaceRequest):
    ws = workspace_manager.update_workspace(workspace_id, name=req.name, description=req.description)
    if not ws:
        raise HTTPException(status_code=404, detail="Workspace not found")
    return ws


@router.delete("/{workspace_id}")
async def delete_workspace(workspace_id: str):
    if not workspace_manager.delete_workspace(workspace_id):
        raise HTTPException(status_code=404, detail="Workspace not found")
    return {"status": "deleted"}


@router.post("/{workspace_id}/activate", response_model=WorkspaceInfo)
async def activate_workspace(workspace_id: str):
    ws = workspace_manager.set_active(workspace_id)
    if not ws:
        raise HTTPException(status_code=404, detail="Workspace not found")
    return ws


@router.post("/deactivate")
async def deactivate_workspace():
    workspace_manager.deactivate()
    return {"status": "deactivated"}


@router.get("/{workspace_id}/tree", response_model=list[FileTreeNode])
async def get_file_tree(
    workspace_id: str,
    path: str = ".",
    max_depth: int = 3,
):
    try:
        return workspace_manager.get_file_tree(workspace_id, path, max_depth)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.get("/{workspace_id}/file", response_model=FileContent)
async def read_file(
    workspace_id: str,
    path: str,
    offset: int = 0,
    limit: Optional[int] = None,
):
    try:
        return workspace_manager.read_file(workspace_id, path, offset, limit)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


# 개발 파일 확장자 MIME 오버라이드 (.ts → video/mp2t 방지 등)
_MIME_OVERRIDES = {
    ".ts": "text/plain", ".tsx": "text/plain", ".jsx": "text/plain",
    ".md": "text/markdown", ".yml": "text/yaml", ".yaml": "text/yaml",
    ".toml": "text/plain", ".rs": "text/plain", ".go": "text/plain",
    ".vue": "text/plain", ".svelte": "text/plain",
}


@router.get("/{workspace_id}/raw")
async def get_raw_file(workspace_id: str, path: str, download: bool = False):
    try:
        file_path = workspace_manager.get_raw_file_path(workspace_id, path)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))

    ext = file_path.suffix.lower()
    media_type = _MIME_OVERRIDES.get(ext)
    if not media_type:
        guessed, _ = mimetypes.guess_type(str(file_path))
        media_type = guessed or "application/octet-stream"

    return FileResponse(
        path=str(file_path),
        media_type=media_type,
        filename=file_path.name,
        content_disposition_type="attachment" if download else "inline",
    )


@router.post("/{workspace_id}/file")
async def write_file(workspace_id: str, req: WriteFileRequest):
    try:
        result = workspace_manager.write_file(workspace_id, req.path, req.content)
        return {"status": "ok", "message": result}
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))


@router.post("/{workspace_id}/edit")
async def edit_file(workspace_id: str, req: EditFileRequest):
    try:
        result = workspace_manager.edit_file(workspace_id, req)
        return {"status": "ok", "message": result}
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
