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

companies_app = typer.Typer(help="Empresas e fornecedores.")


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

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


@companies_app.command("list")
def list_companies(
    search_text: Optional[str] = typer.Option(None, "--search-text", help="Texto de busca."),
    fiscal_number_type: Optional[str] = typer.Option(
        None, "--fiscal-number-type", help="Tipo do documento fiscal (CPF, CNPJ)."
    ),
    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 empresas com filtros opcionais.

    EXAMPLES:
      aegro companies list
      aegro companies list --search-text "Agro" --fiscal-number-type CNPJ
      aegro companies 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 fiscal_number_type is not None:
            body["fiscalNumberType"] = fiscal_number_type
        result = client.post("/pub/v1/companies/filter", api_key=api_key, json_body=body)
        if result is None:
            typer.echo("Nenhuma empresa encontrada.")
            return
        typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)


@companies_app.command("create")
def create_company(
    name: str = typer.Option(..., "--name", help="Nome da empresa."),
    type_: Optional[list[str]] = typer.Option(
        None, "--type", help="Tipo da empresa (repetivel para multiplos)."
    ),
    fiscal_code: Optional[str] = typer.Option(
        None, "--fiscal-code", help="Numero do documento fiscal."
    ),
    fiscal_type: Optional[str] = typer.Option(
        None, "--fiscal-type", help="Tipo do documento fiscal (CPF, CNPJ)."
    ),
    fiscal_country: Optional[str] = typer.Option(
        "BR", "--fiscal-country", help="Codigo do pais (default: BR)."
    ),
    trade_name: Optional[str] = typer.Option(None, "--trade-name", help="Nome fantasia."),
    legal_name: Optional[str] = typer.Option(None, "--legal-name", help="Razao social."),
    observations: Optional[str] = typer.Option(None, "--observations", help="Observacoes."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Cria uma nova empresa.

    EXAMPLES:
      aegro companies create --name "AgroSul Ltda" --type SUPPLIER --fiscal-code 12345678000199 --fiscal-type CNPJ
      aegro companies create --name "Joao Silva" --type CLIENT --type SUPPLIER --trade-name "JS Agro"
    """
    try:
        farm_name, api_key = require_farm()
        client = get_client()
        body: dict = {"name": name}
        if type_:
            body["types"] = type_
        if fiscal_code is not None:
            body["fiscalNumber"] = {
                "code": fiscal_code,
                "fiscalNumberType": fiscal_type,
                "countryCode": fiscal_country,
            }
        if trade_name is not None:
            body["tradeName"] = trade_name
        if legal_name is not None:
            body["legalName"] = legal_name
        if observations is not None:
            body["observations"] = observations
        result = client.post("/pub/v1/companies", api_key=api_key, json_body=body)
        if result is None:
            typer.echo(f"Empresa criada na {farm_name}.")
        else:
            typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)


@companies_app.command("update")
def update_company(
    key: str = typer.Argument(help="Chave unica da empresa."),
    name: str = typer.Option(..., "--name", help="Nome da empresa."),
    type_: Optional[list[str]] = typer.Option(
        None, "--type", help="Tipo da empresa (repetivel para multiplos)."
    ),
    fiscal_code: Optional[str] = typer.Option(
        None, "--fiscal-code", help="Numero do documento fiscal."
    ),
    fiscal_type: Optional[str] = typer.Option(
        None, "--fiscal-type", help="Tipo do documento fiscal (CPF, CNPJ)."
    ),
    fiscal_country: Optional[str] = typer.Option(
        "BR", "--fiscal-country", help="Codigo do pais (default: BR)."
    ),
    trade_name: Optional[str] = typer.Option(None, "--trade-name", help="Nome fantasia."),
    legal_name: Optional[str] = typer.Option(None, "--legal-name", help="Razao social."),
    observations: Optional[str] = typer.Option(None, "--observations", help="Observacoes."),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Atualiza uma empresa/fornecedor existente.

    EXAMPLES:
      aegro companies update company::abc --name "Novo nome" --fiscal-code 12345678000199 --fiscal-type CNPJ
    """
    try:
        farm_name, api_key = require_farm()
        client = get_client()
        body: dict = {"name": name}
        if type_:
            body["types"] = type_
        if fiscal_code is not None:
            body["fiscalNumber"] = {
                "code": fiscal_code,
                "fiscalNumberType": fiscal_type,
                "countryCode": fiscal_country,
            }
        if trade_name is not None:
            body["tradeName"] = trade_name
        if legal_name is not None:
            body["legalName"] = legal_name
        if observations is not None:
            body["observations"] = observations
        result = client.put(
            f"/pub/v1/companies/{validate_key(key)}", api_key=api_key, json_body=body
        )
        if result is None:
            typer.echo(f"Empresa atualizada na {farm_name}.")
        else:
            typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)
