from __future__ import annotations

import argparse

from ..context import CliContext
from ..interaction import cancelled_result, resolve_interactive_selection
from ..terminal_ui import SelectionOption
from .common import raise_config_error


def register(subparsers: argparse._SubParsersAction[argparse.ArgumentParser]) -> None:
    parser = subparsers.add_parser("workspace", help="工作区")
    workspace_subparsers = parser.add_subparsers(dest="workspace_command", required=True)

    list_parser = workspace_subparsers.add_parser("list", help="列出工作区")
    list_parser.add_argument("--page", type=int, default=1)
    list_parser.add_argument("--page-size", type=int, default=20)
    list_parser.add_argument("--include-external", action="store_true")
    list_parser.set_defaults(handler=_handle_list, format_hint="workspace_list")

    get_parser = workspace_subparsers.add_parser("get", help="读取工作区详情")
    get_parser.add_argument("--ws-id", type=int, default=0)
    get_parser.set_defaults(handler=_handle_get, format_hint="workspace_get")

    select_parser = workspace_subparsers.add_parser("select", help="切换当前工作区")
    select_parser.add_argument("--ws-id", type=int, default=0, help="不传时在交互终端中选择工作区")
    select_parser.set_defaults(handler=_handle_select, format_hint="workspace_select")


def _handle_list(args: argparse.Namespace, context: CliContext) -> dict:
    return context.workspace.workspace_list(
        profile=args.profile,
        page_num=args.page,
        page_size=args.page_size,
        include_external=bool(args.include_external),
    )


def _handle_get(args: argparse.Namespace, context: CliContext) -> dict:
    return context.workspace.workspace_get(
        profile=args.profile,
        ws_id=args.ws_id if int(args.ws_id or 0) > 0 else None,
    )


def _handle_select(args: argparse.Namespace, context: CliContext) -> dict:
    if int(args.ws_id or 0) <= 0:
        selection = _choose_workspace_interactively(args, context)
        if selection.status == "unavailable":
            raise_config_error(
                "workspace select requires --ws-id, or an interactive terminal to choose a workspace",
                fix_hint="Retry in an interactive terminal, or pass `--ws-id WS_ID` explicitly.",
            )
        if selection.status == "empty":
            raise_config_error(
                selection.message or "workspace select could not open a selector because no workspaces are available.",
                fix_hint="Run `workspace list` to confirm visible workspaces, or retry with `--ws-id WS_ID`.",
            )
        if selection.status == "cancelled":
            return cancelled_result(selection.message or "已取消")
        args.ws_id = int(selection.value or 0)
    return context.workspace.workspace_select(
        profile=args.profile,
        ws_id=int(args.ws_id),
    )


def _choose_workspace_interactively(args: argparse.Namespace, context: CliContext):
    current_ws_id = None
    sessions = getattr(context, "sessions", None)
    if sessions is not None and hasattr(sessions, "get_profile"):
        try:
            session_profile = sessions.get_profile(args.profile)
        except Exception:
            session_profile = None
        current_ws_id = getattr(session_profile, "selected_ws_id", None) if session_profile is not None else None
    def load_options() -> list[SelectionOption[int]]:
        page = context.workspace.workspace_list(
            profile=args.profile,
            page_num=1,
            page_size=100,
            include_external=False,
        ).get("page")
        items = page.get("list") if isinstance(page, dict) and isinstance(page.get("list"), list) else []
        options: list[SelectionOption[int]] = []
        for item in items:
            if not isinstance(item, dict):
                continue
            ws_id = int(item.get("wsId") or 0)
            if ws_id <= 0:
                continue
            workspace_name = str(item.get("workspaceName") or item.get("wsName") or f"Workspace {ws_id}")
            remark = str(item.get("remark") or "").strip()
            label = workspace_name
            if remark:
                label = f"{workspace_name} - {remark}"
            hint = f"ws_id={ws_id}"
            if current_ws_id == ws_id:
                hint += " · 当前"
            options.append(SelectionOption(value=ws_id, label=label, hint=hint))
        return options

    return resolve_interactive_selection(
        args,
        title="选择工作区",
        unavailable_message="workspace select requires --ws-id, or an interactive terminal to choose a workspace",
        empty_message="workspace select could not open a selector because no visible workspaces were returned.",
        load_options=load_options,
    )
