from __future__ import annotations

from fastapi import APIRouter, Depends, Request
from fastapi.responses import JSONResponse

from app_dependencies import get_runtime
from card_store import normalize_card_id
from route_helpers import read_json_request
from session_store import normalize_session_chat_id
from web_runtime import WebAppRuntime
from workbench_store import (
    delete_workbench_item,
    load_workbench_items,
    persist_workbench_item,
    promote_workbench_item,
)

router = APIRouter()


@router.get("/workbench")
async def get_workbench(request: Request) -> JSONResponse:
    chat_id = normalize_session_chat_id(str(request.query_params.get("chat_id", "web") or "web"))
    if not chat_id:
        return JSONResponse({"error": "invalid chat id"}, status_code=400)
    try:
        items = load_workbench_items(chat_id)
    except ValueError as exc:
        return JSONResponse({"error": str(exc)}, status_code=400)
    except Exception as exc:
        return JSONResponse({"error": f"failed to load workbench: {exc}"}, status_code=500)
    return JSONResponse({"items": items})


@router.post("/workbench")
async def upsert_workbench(
    request: Request,
    runtime: WebAppRuntime = Depends(get_runtime),
) -> JSONResponse:
    try:
        payload = await read_json_request(request)
    except ValueError as exc:
        return JSONResponse({"error": str(exc)}, status_code=400)

    item = persist_workbench_item(payload)
    if item is None:
        return JSONResponse({"error": "invalid workbench payload"}, status_code=400)
    await runtime.publish_workbench_changed(item.get("chat_id"))
    return JSONResponse({"status": "ok", "item": item}, status_code=201)


@router.delete("/workbench/{item_id}")
async def delete_workbench(
    item_id: str,
    request: Request,
    runtime: WebAppRuntime = Depends(get_runtime),
) -> JSONResponse:
    chat_id = normalize_session_chat_id(str(request.query_params.get("chat_id", "web") or "web"))
    if not chat_id:
        return JSONResponse({"error": "invalid chat id"}, status_code=400)
    if not normalize_card_id(item_id):
        return JSONResponse({"error": "invalid workbench item id"}, status_code=400)
    try:
        removed = delete_workbench_item(chat_id, item_id)
    except ValueError as exc:
        return JSONResponse({"error": str(exc)}, status_code=400)
    except Exception as exc:
        return JSONResponse({"error": f"failed to delete workbench item: {exc}"}, status_code=500)
    if not removed:
        return JSONResponse({"error": "workbench item not found"}, status_code=404)
    await runtime.publish_workbench_changed(chat_id)
    return JSONResponse({"status": "ok", "item_id": item_id})


@router.post("/workbench/{item_id}/promote")
async def promote_workbench(
    item_id: str,
    request: Request,
    runtime: WebAppRuntime = Depends(get_runtime),
) -> JSONResponse:
    try:
        payload = await read_json_request(request)
    except ValueError:
        payload = {}

    chat_id = normalize_session_chat_id(str(payload.get("chat_id", "web") or "web"))
    if not chat_id:
        return JSONResponse({"error": "invalid chat id"}, status_code=400)
    if not normalize_card_id(item_id):
        return JSONResponse({"error": "invalid workbench item id"}, status_code=400)
    try:
        card = promote_workbench_item(chat_id, item_id)
    except FileNotFoundError:
        return JSONResponse({"error": "workbench item not found"}, status_code=404)
    except ValueError as exc:
        return JSONResponse({"error": str(exc)}, status_code=400)
    except RuntimeError as exc:
        return JSONResponse({"error": str(exc)}, status_code=500)
    except Exception as exc:
        return JSONResponse({"error": f"failed to promote workbench item: {exc}"}, status_code=500)
    await runtime.publish_workbench_changed(chat_id)
    await runtime.publish_cards_changed(card.get("chat_id"))
    return JSONResponse({"status": "ok", "card": card, "item_id": item_id})
