# src/dattos_cli/commands/folders.py
from __future__ import annotations

from typing import Optional

import typer

from dattos_cli.client import ApiError
from dattos_cli.config import ConfigError, get_config, save_folder
from dattos_cli.main import get_client, handle_api_error
from dattos_cli.output import is_tty, print_error, print_json
from dattos_cli.table import print_table

app = typer.Typer(help="List, select and inspect folders.", no_args_is_help=True)

FOLDERS_FLAT_COLUMNS = [
    ("ID",   "id",       None),
    ("Code", "code",     None),
    ("Name", "name",     None),
    ("Path", "fullPath", None),
]


def _flatten(nodes: list, depth: int = 0) -> list[dict]:
    """Flatten the folder tree into a list with depth info."""
    result = []
    for node in nodes:
        result.append({
            "id": node["Id"],
            "code": node.get("Code", ""),
            "name": node.get("Name", ""),
            "parentId": node.get("ParentId"),
            "fullPath": node.get("FullPath", node.get("Name", "")),
            "depth": depth,
        })
        children = node.get("Children", [])
        if children:
            result.extend(_flatten(children, depth + 1))
    return result


@app.command("list")
def list_folders(
    flat: bool = typer.Option(False, "--flat", help="Flatten the tree into a list with id, name, fullPath"),
    no_cache: bool = typer.Option(False, "--no-cache", help="Bypass cache, fetch fresh data."),
    raw: bool = typer.Option(False, "--raw", help="Output raw JSON (only affects --flat mode)."),
):
    """List all folders (returns the folder tree)."""
    client = get_client()
    try:
        result = client.get("/api/Folder/Tree", cache=not no_cache, cache_ttl=600)
        if flat:
            data = _flatten(result)
            if raw or not is_tty():
                print_json(data)
            else:
                print_table(data, FOLDERS_FLAT_COLUMNS, label="folders")
        else:
            # Tree output is always JSON
            print_json(result)
    except ApiError as e:
        handle_api_error(e)


@app.command("current")
def current_folder():
    """Show the currently selected folder."""
    try:
        cfg = get_config()
    except ConfigError:
        print_json({"folder_id": "(not set)", "folder_name": "(not set)"})
        return
    print_json({
        "folder_id": cfg.folder_id or "(not set)",
        "folder_name": cfg.folder_name or "(not set)",
    })


@app.command("select")
def select_folder(
    folder_id: Optional[str] = typer.Argument(None, help="Folder ID to select. Omit for interactive picker (TTY only)."),
):
    """Select a folder to use for all subsequent commands.

    Pass a folder ID directly: dattos folders select 42
    Or omit for interactive picker (TTY only): dattos folders select
    """
    client = get_client()
    try:
        tree = client.get("/api/Folder/Tree")
    except ApiError as e:
        handle_api_error(e)
        return

    flat = _flatten(tree)
    if not flat:
        print_error("no_folders", "No folders found in this organization", 1)
        raise typer.Exit(1)

    if folder_id is not None:
        match = next((f for f in flat if str(f["id"]) == folder_id), None)
        if not match:
            print_error("not_found", f"Folder ID {folder_id} not found", 1)
            raise typer.Exit(1)
        save_folder(str(match["id"]), match["name"])
        print_json({"folder_id": str(match["id"]), "folder_name": match["name"], "status": "selected"})
        return

    if not is_tty():
        print_error("not_interactive", "Folder ID required in non-interactive mode: dattos folders select <id>", 1)
        raise typer.Exit(1)

    typer.echo()
    typer.echo("Available folders:")
    typer.echo()
    for i, f in enumerate(flat, 1):
        indent = "  " * f["depth"]
        typer.echo(f"  {i:>3}. {indent}{f['name']} (id: {f['id']})")
    typer.echo()

    while True:
        choice = typer.prompt("Select folder [1-{}]".format(len(flat)))
        try:
            idx = int(choice)
            if 1 <= idx <= len(flat):
                break
        except ValueError:
            pass
        typer.echo(f"Invalid choice. Enter a number between 1 and {len(flat)}.")

    selected = flat[idx - 1]
    save_folder(str(selected["id"]), selected["name"])
    typer.echo()
    typer.echo(f"Folder set to \"{selected['name']}\" ({selected['id']})")
