import os
import subprocess

from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from pydantic import BaseModel
from onako.tmux_orchestrator import TmuxOrchestrator
from onako.worktree_manager import WorktreeManager

app = FastAPI()
session_name = os.environ.get("ONAKO_SESSION", "onako")
skip_permissions_default = os.environ.get("ONAKO_SKIP_PERMISSIONS") == "1"
orch = TmuxOrchestrator(session_name=session_name)
static_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "static")

# Initialize worktree manager only if in a git repo
worktree_manager = WorktreeManager(os.getcwd()) if os.path.exists(os.path.join(os.getcwd(), ".git")) else None


class CreateTaskRequest(BaseModel):
    prompt: str
    working_dir: str | None = None
    skip_permissions: bool | None = None
    branch: str | None = None
    base_branch: str | None = None


class SendMessageRequest(BaseModel):
    message: str


@app.get("/")
def dashboard():
    return FileResponse(os.path.join(static_dir, "index.html"))


@app.get("/health")
def health():
    return {"status": "ok", "skip_permissions": skip_permissions_default}


@app.post("/tasks")
def create_task(req: CreateTaskRequest):
    skip = req.skip_permissions if req.skip_permissions is not None else skip_permissions_default
    from onako.task_service import create_task as _create_task
    try:
        return _create_task(
            orch, prompt=req.prompt, working_dir=req.working_dir, skip_permissions=skip,
            branch=req.branch, base_branch=req.base_branch, worktree_manager=worktree_manager,
        )
    except subprocess.CalledProcessError as e:
        raise HTTPException(status_code=400, detail=f"Failed to create worktree: {e.stderr.decode() if e.stderr else str(e)}")


@app.get("/tasks")
def list_tasks():
    return orch.list_tasks()


@app.get("/tasks/{task_id}")
def get_task(task_id: str):
    if task_id not in orch.tasks:
        raise HTTPException(status_code=404, detail="Task not found")
    task = orch.tasks[task_id].copy()
    if task["status"] in ("done", "hidden") and task.get("last_output"):
        task["output"] = task["last_output"]
    else:
        task["output"] = orch.get_output(task_id)
    return task


@app.get("/tasks/{task_id}/raw")
def get_task_raw(task_id: str):
    if task_id not in orch.tasks:
        raise HTTPException(status_code=404, detail="Task not found")
    task = orch.tasks[task_id].copy()
    task["output"] = orch.get_raw_output(task_id)
    return task


@app.post("/tasks/{task_id}/message")
def send_message(task_id: str, req: SendMessageRequest):
    if task_id not in orch.tasks:
        raise HTTPException(status_code=404, detail="Task not found")
    orch.send_message(task_id, req.message)
    return {"status": "sent"}


@app.post("/tasks/{task_id}/interrupt")
def interrupt_task(task_id: str):
    if task_id not in orch.tasks:
        raise HTTPException(status_code=404, detail="Task not found")
    orch.send_interrupt(task_id)
    return {"status": "interrupted"}


@app.post("/tasks/{task_id}/resume")
def resume_task(task_id: str):
    if task_id not in orch.tasks:
        raise HTTPException(status_code=404, detail="Task not found")
    try:
        task = orch.resume_task(task_id, skip_permissions=skip_permissions_default, worktree_manager=worktree_manager)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    return task


@app.post("/tasks/{task_id}/hide")
def hide_task(task_id: str):
    if task_id not in orch.tasks:
        raise HTTPException(status_code=404, detail="Task not found")
    try:
        orch.hide_task(task_id)
    except ValueError as e:
        raise HTTPException(status_code=400, detail=str(e))
    return orch.tasks[task_id]


@app.delete("/tasks/{task_id}")
def delete_task(task_id: str):
    if task_id not in orch.tasks:
        raise HTTPException(status_code=404, detail="Task not found")
    if orch.window_count() <= 1:
        raise HTTPException(status_code=400, detail="Cannot kill the last window")
    orch.kill_task(task_id)
    return {"status": "deleted"}


@app.get("/worktrees")
def list_worktrees():
    if not worktree_manager:
        return []
    return [{"branch": wt["branch"], "path": str(wt["path"])} for wt in worktree_manager.list_worktrees()]


@app.delete("/worktrees/{branch:path}")
def delete_worktree(branch: str):
    if not worktree_manager:
        raise HTTPException(status_code=400, detail="Not in a git repository")
    try:
        worktree_manager.delete_worktree(branch)
    except subprocess.CalledProcessError as e:
        detail = e.stderr.strip() if e.stderr else f"Failed to remove worktree for branch '{branch}'"
        raise HTTPException(status_code=400, detail=detail)
    return {"status": "deleted"}


@app.get("/stats")
def get_stats():
    return orch.get_stats()


app.mount("/static", StaticFiles(directory=static_dir), name="static")
