"""Chat workspace picker: which host directories a NEW dashboard chat can start in.

The dashboard's ``/chat`` tab used to spawn every fresh TUI in the dashboard process's own
launch directory, so from a phone or browser there was no way to say "work in ~/code/foo".
This lists the same projects and discovered repositories the Desktop sidebar shows (the
per-profile ``projects.db`` plus session-derived and scanned git roots) so the SPA can offer
a picker, and ``/api/pty?cwd=`` (``chat_ws``) honours the choice.
"""

from __future__ import annotations

import os
from pathlib import Path
from typing import Optional

from fastapi import APIRouter, HTTPException

from hermes_cli.web_deps import late
from hermes_cli.web_routers._common import http_failure, scoped_to_thread

router = APIRouter()

_open_session_db_for_profile = late("_open_session_db_for_profile", "hermes_cli.web_server_sessions")


def resolve_chat_cwd(raw: Optional[str]) -> Optional[str]:
    """Validate a ``?cwd=`` for a fresh chat: an existing host directory, or None when unset.

    A dead or relative path fails closed (400) instead of silently falling back to the launch
    dir — the user picked a workspace and would otherwise get a session in the wrong place.
    """
    text = (raw or "").strip()
    if not text:
        return None
    resolved = os.path.abspath(os.path.expanduser(text))
    if not os.path.isdir(resolved):
        raise HTTPException(status_code=400, detail=f"Working directory does not exist: {text}")
    return resolved


def _collect_workspaces(profile: Optional[str], scan: bool) -> dict:
    # The dashboard hosts the in-process gateway (``web_server`` imports ``tui_gateway.server``
    # at startup), so the sidebar's repo-discovery helpers are already bound there.
    import tui_gateway.server as gateway
    from hermes_cli import projects_db as pdb

    db = _open_session_db_for_profile(profile, read_only=True)
    try:
        with pdb.connect_closing() as conn:
            policy = gateway._repo_discovery_policy()
            if scan and policy["enabled"]:
                gateway._scan_discovered_repos_remote(conn, policy)
            projects = [p.to_dict() for p in pdb.list_projects(conn)]
            repos = gateway._discover_repos_payload(
                db, conn=conn, backfill=False, include_cached=policy["enabled"])
    finally:
        db.close()
    default_cwd = gateway._completion_cwd({"profile": profile} if profile else {})
    return {
        "projects": projects, "repos": repos, "default_cwd": default_cwd,
        "home": str(Path.home()), "scan_enabled": bool(policy["enabled"])}


@router.get("/api/chat/workspaces")
async def get_chat_workspaces(profile: Optional[str] = None, scan: bool = False):
    """Projects + discovered repos a fresh chat may start in; ``scan=1`` rescans the
    configured discovery roots on the host first (headless installs have no Desktop to do it)."""
    with http_failure("GET /api/chat/workspaces failed", 500, "Failed to list workspaces"):
        return await scoped_to_thread(profile, lambda: _collect_workspaces(profile, scan))
