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_accounts_app = typer.Typer(help="Contas bancarias.")


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

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


@bank_accounts_app.command("list")
def list_bank_accounts(
    search_text: Optional[str] = typer.Option(None, "--search-text", help="Texto de busca."),
    bank_name: Optional[str] = typer.Option(None, "--bank-name", help="Nome do banco."),
    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 contas bancarias com filtros opcionais.

    EXAMPLES:
      aegro bank-accounts list
      aegro bank-accounts list --search-text "Itau" --bank-name "Itau"
      aegro bank-accounts list --page 2 --output table
    """
    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 bank_name is not None:
            body["bankName"] = bank_name
        result = client.post("/pub/v1/bank-accounts/filter", api_key=api_key, json_body=body)
        if result is None:
            typer.echo("Nenhuma conta bancaria encontrada.")
            return
        typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)


@bank_accounts_app.command("create")
def create_bank_account(
    name: str = typer.Option(..., "--name", help="Nome da conta bancaria."),
    balance: Optional[float] = typer.Option(None, "--balance", help="Saldo atual."),
    balance_currency: Optional[str] = typer.Option(
        None, "--balance-currency", help="Moeda do saldo (ex: BRL)."
    ),
    initial_balance: Optional[float] = typer.Option(
        None, "--initial-balance", help="Saldo inicial."
    ),
    initial_balance_currency: Optional[str] = typer.Option(
        None, "--initial-balance-currency", help="Moeda do saldo inicial."
    ),
    initial_balance_date: Optional[str] = typer.Option(
        None, "--initial-balance-date", help="Data do saldo inicial (YYYY-MM-DD)."
    ),
    is_default: bool = typer.Option(False, "--is-default", help="Definir como conta padrao."),
    code: Optional[str] = typer.Option(None, "--code", help="Codigo da conta."),
    bank: Optional[str] = typer.Option(None, "--bank", help="Banco."),
    bank_code: Optional[str] = typer.Option(None, "--bank-code", help="Codigo do banco."),
    bank_name: Optional[str] = typer.Option(None, "--bank-name", help="Nome do banco."),
    branch_code: Optional[str] = typer.Option(None, "--branch-code", help="Codigo da agencia."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Cria uma nova conta bancaria.

    EXAMPLES:
      aegro bank-accounts create --name "Conta Itau" --balance 10000 --balance-currency BRL
      aegro bank-accounts create --name "Conta BB" --is-default --bank-name "Banco do Brasil"
    """
    try:
        farm_name, api_key = require_farm()
        client = get_client()
        body: dict = {"name": name}
        if balance is not None and balance_currency is not None:
            body["balance"] = {"currencyCode": balance_currency, "amount": balance}
        if initial_balance is not None and initial_balance_currency is not None:
            body["initialBalance"] = {
                "currencyCode": initial_balance_currency,
                "amount": initial_balance,
            }
        if initial_balance_date is not None:
            body["initialBalanceDate"] = initial_balance_date
        if code is not None:
            body["code"] = code
        if bank is not None:
            body["bank"] = bank
        if bank_code is not None:
            body["bankCode"] = bank_code
        if bank_name is not None:
            body["bankName"] = bank_name
        if branch_code is not None:
            body["branchCode"] = branch_code
        result = client.post(
            f"/pub/v1/bank-accounts?isDefault={'true' if is_default else 'false'}",
            api_key=api_key,
            json_body=body,
        )
        if result is None:
            typer.echo(f"Conta bancaria criada na {farm_name}.")
        else:
            typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)
