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="Monitor and manage imports.", no_args_is_help=True)

IMPORTS_COLUMNS = [
    ("ID",          "Id",               None),
    ("Status",      "Status",           None),
    ("Success",     "TotalSuccess",     None),
    ("Rejections",  "TotalRejections",  None),
]


@app.command("list")
def list_imports(
    date_from: Optional[str] = typer.Option(None, "--from", help="Start reference date (YYYY-MM-DD)"),
    date_to: Optional[str] = typer.Option(None, "--to", help="End reference date (YYYY-MM-DD)"),
    status: Optional[str] = typer.Option(None, "--status", "-s", help="Filter by status (Enqueued, Processing, Success, Error, Canceled, Canceling, PartiallyCanceled, Purged)"),
    include_canceled: bool = typer.Option(False, "--include-canceled", help="Include canceled imports"),
    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 imports with optional date and status filters."""
    client = get_client(folder_id)
    params: dict = {
        "pageInfo.page": page,
        "pageInfo.pageSize": page_size,
    }
    if date_from:
        params["beginReferenceDate"] = date_from
    if date_to:
        params["endReferenceDate"] = date_to
    if status:
        params["status"] = status
    if include_canceled:
        params["includeCanceled"] = "true"
    try:
        resp = client.get("/api/Import", params=params)
        data = resp.get("data", resp) if isinstance(resp, dict) else resp
        if raw or not is_tty():
            print_json(data)
        else:
            print_table(data, IMPORTS_COLUMNS, label="imports")
    except ApiError as e:
        handle_api_error(e)


@app.command("get")
def get_import(
    import_id: int = typer.Argument(help="Import 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 import details by ID."""
    client = get_client(folder_id)
    try:
        result = client.get(f"/api/Import/{import_id}")
        if raw or not is_tty():
            print_json(result)
        else:
            print_record(result)
    except ApiError as e:
        handle_api_error(e)


@app.command("results")
def import_results(
    import_id: int = typer.Argument(help="Import ID"),
    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"),
):
    """Get rejection results for an import."""
    client = get_client(folder_id)
    params = {
        "pageInfo.page": page,
        "pageInfo.pageSize": page_size,
    }
    try:
        result = client.get(f"/api/Import/{import_id}/Results", params=params)
        print_json(result)
    except ApiError as e:
        handle_api_error(e)


@app.command("logs")
def import_logs(
    import_id: int = typer.Argument(help="Import ID"),
    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"),
):
    """Get execution logs for an import."""
    client = get_client(folder_id)
    params = {
        "pageInfo.page": page,
        "pageInfo.pageSize": page_size,
    }
    try:
        result = client.get(f"/api/Import/{import_id}/Logs", params=params)
        print_json(result)
    except ApiError as e:
        handle_api_error(e)


@app.command("cancel")
def cancel_import(
    import_id: int = typer.Argument(help="Import ID to cancel"),
    folder_id: Optional[str] = typer.Option(None, "--folder-id", help="Folder ID to scope the query"),
):
    """Cancel an import."""
    client = get_client(folder_id)
    try:
        result = client.post("/api/Import/Cancel", json={"ImportIds": [import_id]})
        if not result:
            result = {"status": "canceled", "importId": import_id}
        print_json(result)
    except ApiError as e:
        handle_api_error(e)
