from __future__ import annotations

from pathlib import Path
from typing import Optional

import typer

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

nfes_app = typer.Typer(help="Downloads de XML de NF-e.")


@nfes_app.command("xml")
def download_nfe_xml(
    access_key: str = typer.Argument(help="Chave de acesso da NF-e (44 digitos)."),
    output_path: Path = typer.Option(
        ..., "--output-path", "-o", help="Caminho do arquivo XML de destino."
    ),
) -> None:
    """Baixa o XML de uma NF-e pela chave de acesso.

    EXAMPLES:
      aegro nfes xml 35250512345678000190550010000123451234567890 -o ./nfe.xml
    """
    try:
        _, api_key = require_farm()
        client = get_client()
        data = client.download(f"/pub/v1/nfes/{validate_key(access_key)}/xml", api_key=api_key)
        if not data:
            typer.echo("NF-e nao encontrada.")
            return
        output_path.write_bytes(data)
        typer.echo(f"XML salvo em {output_path} ({len(data)} bytes).")
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)


@nfes_app.command("xml-batch")
def download_nfe_xml_batch(
    output_path: Path = typer.Option(
        ..., "--output-path", "-o", help="Caminho do arquivo ZIP de destino."
    ),
    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)."),
    number: Optional[str] = typer.Option(None, "--number", help="Numero da NF-e."),
    series: Optional[str] = typer.Option(None, "--series", help="Serie da NF-e."),
    cfop_code: Optional[list[str]] = typer.Option(
        None, "--cfop-code", help="Codigo CFOP (repetivel)."
    ),
    buyer_key: Optional[list[str]] = typer.Option(
        None, "--buyer-key", help="Chave de empresa compradora (repetivel)."
    ),
    issuer_key: Optional[list[str]] = typer.Option(
        None, "--issuer-key", help="Chave de empresa emissora (repetivel)."
    ),
    fiscal_product_key: Optional[list[str]] = typer.Option(
        None, "--fiscal-product-key", help="Chave de produto fiscal (repetivel)."
    ),
    status: Optional[list[str]] = typer.Option(None, "--status", help="Status (repetivel)."),
    operation_type: Optional[list[str]] = typer.Option(
        None, "--operation-type", help="INBOUND|OUTBOUND (repetivel)."
    ),
    purpose_type: Optional[list[str]] = typer.Option(
        None, "--purpose-type", help="Finalidade (repetivel)."
    ),
    financial_import_status: Optional[list[str]] = typer.Option(
        None, "--financial-import-status", help="IMPORTED|NOT_IMPORTED (repetivel)."
    ),
    search_text: Optional[str] = typer.Option(None, "--search-text", help="Texto de busca."),
    page: int = typer.Option(1, "--page", help="Numero da pagina."),
) -> None:
    """Baixa um ZIP com XMLs de NF-es filtrados.

    EXAMPLES:
      aegro nfes xml-batch -o ./nfes.zip --start-date 2025-01-01 --end-date 2025-01-31
      aegro nfes xml-batch -o ./saida.zip --operation-type OUTBOUND --status AUTHORIZED
    """
    try:
        _, api_key = require_farm()
        client = get_client()
        body: dict = {
            "requiredPageNumber": page,
            "maximumItemsPerPageCount": 50,
        }
        if start_date is not None:
            body["startDate"] = start_date
        if end_date is not None:
            body["endDate"] = end_date
        if number is not None:
            body["number"] = number
        if series is not None:
            body["series"] = series
        if cfop_code:
            body["cfopCodes"] = cfop_code
        if buyer_key:
            body["buyerKeys"] = buyer_key
        if issuer_key:
            body["issuerKeys"] = issuer_key
        if fiscal_product_key:
            body["fiscalProductKeys"] = fiscal_product_key
        if status:
            body["statuses"] = status
        if operation_type:
            body["operationTypes"] = operation_type
        if purpose_type:
            body["purposeTypes"] = purpose_type
        if financial_import_status:
            body["financialImportStatuses"] = financial_import_status
        if search_text is not None:
            body["searchText"] = search_text
        data = client.download(
            "/pub/v1/nfes/xmls/filter",
            api_key=api_key,
            method="POST",
            json_body=body,
        )
        if not data:
            typer.echo("Nenhuma NF-e encontrada para o filtro informado.")
            return
        output_path.write_bytes(data)
        typer.echo(f"ZIP salvo em {output_path} ({len(data)} bytes).")
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)
