from __future__ import annotations

from typing import Optional

import typer

from aegro.cli._config import get_client, require_farm
from aegro.cli._errors import handle_error
from aegro.cli._output import OutputFormat, format_output
from aegro.validation import validate_key

bank_transfers_app = typer.Typer(help="Transferencias bancarias.")


@bank_transfers_app.command("get")
def get_bank_transfer(
    key: str = typer.Argument(help="Chave unica da transferencia bancaria."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Retorna os dados de uma transferencia bancaria pelo seu identificador.

    EXAMPLES:
      aegro bank-transfers get bankTransfer::abc
    """
    try:
        _, api_key = require_farm()
        client = get_client()
        result = client.get(f"/pub/v1/bank-transfers/{validate_key(key)}", api_key=api_key)
        if result is None:
            typer.echo("Transferencia nao encontrada.")
            return
        typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)


@bank_transfers_app.command("list")
def list_bank_transfers(
    search_text: Optional[str] = typer.Option(None, "--search-text", help="Texto de busca."),
    source_key: Optional[list[str]] = typer.Option(
        None, "--source-key", help="Chave da conta de origem (repetivel)."
    ),
    target_key: Optional[list[str]] = typer.Option(
        None, "--target-key", help="Chave da conta de destino (repetivel)."
    ),
    start_date: Optional[str] = typer.Option(
        None, "--start-date", help="Data inicial (YYYY-MM-DD)."
    ),
    end_date: Optional[str] = typer.Option(None, "--end-date", help="Data final (YYYY-MM-DD)."),
    reconciliation_status: Optional[list[str]] = typer.Option(
        None, "--reconciliation-status", help="Status de conciliacao (repetivel)."
    ),
    tag: Optional[list[str]] = typer.Option(None, "--tag", help="Tag associada (repetivel)."),
    page: int = typer.Option(1, "--page", help="Numero da pagina."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Lista transferencias bancarias com filtros opcionais.

    EXAMPLES:
      aegro bank-transfers list
      aegro bank-transfers list --start-date 2025-01-01 --end-date 2025-12-31
      aegro bank-transfers list --reconciliation-status CONFIRMED
    """
    try:
        _, api_key = require_farm()
        client = get_client()
        body: dict = {
            "requiredPageNumber": page,
            "maximumItemsPerPageCount": 50,
        }
        if search_text is not None:
            body["searchText"] = search_text
        if source_key:
            body["sourceBankAccountKeys"] = source_key
        if target_key:
            body["targetBankAccountKeys"] = target_key
        if start_date is not None:
            body["startDate"] = start_date
        if end_date is not None:
            body["endDate"] = end_date
        if reconciliation_status:
            body["reconciliationStatuses"] = reconciliation_status
        if tag:
            body["tags"] = tag
        result = client.post("/pub/v1/bank-transfers/filter", api_key=api_key, json_body=body)
        if result is None:
            typer.echo("Nenhuma transferencia encontrada.")
            return
        typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)


@bank_transfers_app.command("create")
def create_bank_transfer(
    source_key: str = typer.Option(..., "--source-key", help="Chave da conta bancaria de origem."),
    target_key: str = typer.Option(..., "--target-key", help="Chave da conta bancaria de destino."),
    amount: float = typer.Option(..., "--amount", help="Valor da transferencia."),
    entry_date: str = typer.Option(..., "--entry-date", help="Data de entrada (YYYY-MM-DD)."),
    currency: str = typer.Option("BRL", "--currency", help="Moeda (default: BRL)."),
    description: Optional[str] = typer.Option(None, "--description", help="Descricao opcional."),
    tag: Optional[list[str]] = typer.Option(None, "--tag", help="Tag associada (repetivel)."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Cria uma nova transferencia bancaria.

    EXAMPLES:
      aegro bank-transfers create --source-key ba1 --target-key ba2 --amount 5000.00 --entry-date 2025-06-01
    """
    try:
        farm_name, api_key = require_farm()
        client = get_client()
        body: dict = {
            "sourceBankAccountKey": source_key,
            "targetBankAccountKey": target_key,
            "amount": {"amount": amount, "currency": currency},
            "entryDate": entry_date,
        }
        if description is not None:
            body["description"] = description
        if tag:
            body["tags"] = tag
        result = client.post("/pub/v1/bank-transfers", api_key=api_key, json_body=body)
        if result is None:
            typer.echo(f"Transferencia criada na {farm_name}.")
        else:
            typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)
