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

from typing import Optional

import typer

from dattos_cli.client import ApiError
from dattos_cli.main import get_client, handle_api_error
from dattos_cli.output import is_tty, print_json
from dattos_cli.table import print_record, print_table

app = typer.Typer(help="Manage and execute workflows.", no_args_is_help=True)


def _flatten_workflow(item: dict) -> dict:
    """Flatten nested workflow API response into a flat dict for table display."""
    wf = item.get("Workflow") or {}
    ex = item.get("ExecutionWorkflow") or {}
    return {
        "Id": wf.get("Id"),
        "Name": wf.get("Name"),
        "Status": ex.get("Status"),
    }


WORKFLOWS_COLUMNS = [
    ("ID",     "Id",     None),
    ("Name",   "Name",   None),
    ("Status", "Status", None),
]


@app.command("list")
def list_workflows(
    name: Optional[str] = typer.Option(None, "--name", "-n", help="Filter by workflow name"),
    page: int = typer.Option(0, "--page", help="Page number (0-indexed)"),
    page_size: int = typer.Option(50, "--page-size", help="Results per page"),
    folder_id: Optional[str] = typer.Option(None, "--folder-id", help="Folder ID to scope the query"),
    raw: bool = typer.Option(False, "--raw", help="Output raw JSON."),
):
    """List workflows with their latest execution info."""
    client = get_client(folder_id)
    params = {
        "pageInfo.page": page,
        "pageInfo.pageSize": page_size,
    }
    if name:
        params["name"] = name
    try:
        resp = client.get("/api/Workflow/Management/Search", params=params)
        raw_list = resp.get("Data", resp.get("data", resp)) if isinstance(resp, dict) else resp
        flat = [_flatten_workflow(item) for item in raw_list]
        if raw or not is_tty():
            print_json(flat)
        else:
            print_table(flat, WORKFLOWS_COLUMNS, label="workflows")
    except ApiError as e:
        handle_api_error(e)


@app.command("get")
def get_workflow(
    workflow_id: int = typer.Argument(help="Workflow ID"),
    folder_id: Optional[str] = typer.Option(None, "--folder-id", help="Folder ID to scope the query"),
    raw: bool = typer.Option(False, "--raw", help="Output raw JSON."),
):
    """Get workflow details with latest execution info."""
    client = get_client(folder_id)
    try:
        result = client.get(f"/api/Workflow/Management/{workflow_id}")
        if raw or not is_tty():
            print_json(result)
        else:
            print_record(result)
    except ApiError as e:
        handle_api_error(e)


@app.command("start")
def start_workflow(
    workflow_id: int = typer.Argument(help="Workflow ID"),
    date: str = typer.Option(..., "--date", "-d", help="Reference date (YYYY-MM-DD)"),
    folder_id: Optional[str] = typer.Option(None, "--folder-id", help="Folder ID to scope the query"),
):
    """Start a workflow execution for a reference date."""
    client = get_client(folder_id)
    try:
        result = client.post(f"/api/Workflow/Management/Start/{workflow_id}", json=date)
        if not result:
            result = {"status": "started", "workflowId": workflow_id, "referenceDate": date}
        print_json(result)
    except ApiError as e:
        handle_api_error(e)


@app.command("stop")
def stop_workflow(
    execution_id: int = typer.Argument(help="Execution workflow ID (not workflow ID)"),
    folder_id: Optional[str] = typer.Option(None, "--folder-id", help="Folder ID to scope the query"),
):
    """Stop a running workflow execution."""
    client = get_client(folder_id)
    try:
        result = client.post(f"/api/Workflow/Management/Stop/{execution_id}")
        if not result:
            result = {"status": "stopped", "executionId": execution_id}
        print_json(result)
    except ApiError as e:
        handle_api_error(e)


@app.command("history")
def workflow_history(
    workflow_id: int = typer.Argument(help="Workflow ID"),
    page: int = typer.Option(0, "--page", help="Page number (0-indexed)"),
    page_size: int = typer.Option(20, "--page-size", help="Results per page"),
    folder_id: Optional[str] = typer.Option(None, "--folder-id", help="Folder ID to scope the query"),
):
    """List execution history for a workflow."""
    client = get_client(folder_id)
    params = {
        "pageInfo.page": page,
        "pageInfo.pageSize": page_size,
    }
    try:
        result = client.get(
            f"/api/Workflow/Management/{workflow_id}/SearchHistoryExecutions",
            params=params,
        )
        print_json(result)
    except ApiError as e:
        handle_api_error(e)


@app.command("logs")
def workflow_logs(
    task_id: int = typer.Argument(help="Execution workflow task ID"),
    folder_id: Optional[str] = typer.Option(None, "--folder-id", help="Folder ID to scope the query"),
):
    """Get logs for a workflow execution task."""
    client = get_client(folder_id)
    try:
        result = client.get(
            f"/api/Workflow/Management/Executions/Tasks/{task_id}/Logs"
        )
        print_json(result)
    except ApiError as e:
        handle_api_error(e)
