from __future__ import annotations

import json as json_mod
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

purchase_orders_app = typer.Typer(help="Ordens de compra.")


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

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


@purchase_orders_app.command("list")
def list_purchase_orders(
    company_key: Optional[str] = typer.Option(None, "--company-key", help="Chave da empresa."),
    search_text: Optional[str] = typer.Option(None, "--search-text", help="Texto de busca."),
    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)."),
    delivery_status: Optional[str] = typer.Option(
        None, "--delivery-status", help="Status de entrega."
    ),
    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 ordens de compra com filtros opcionais.

    EXAMPLES:
      aegro purchase-orders list
      aegro purchase-orders list --company-key c1 --delivery-status PENDING
      aegro purchase-orders list --start-date 2025-01-01 --end-date 2025-12-31 --page 2
    """
    try:
        _, api_key = require_farm()
        client = get_client()
        body: dict = {
            "requiredPageNumber": page,
            "maximumItemsPerPageCount": 50,
        }
        if company_key is not None:
            body["companyKey"] = company_key
        if search_text is not None:
            body["searchText"] = search_text
        if start_date is not None:
            body["startDate"] = start_date
        if end_date is not None:
            body["endDate"] = end_date
        if delivery_status is not None:
            body["deliveryStatus"] = delivery_status
        result = client.post("/pub/v1/purchase-orders/filter", api_key=api_key, json_body=body)
        if result is None:
            typer.echo("Nenhuma ordem de compra encontrada.")
            return
        typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)


@purchase_orders_app.command("create")
def create_purchase_order(
    company_key: str = typer.Option(..., "--company-key", help="Chave da empresa."),
    order_date: str = typer.Option(..., "--order-date", help="Data da ordem (YYYY-MM-DD)."),
    currency: str = typer.Option("BRL", "--currency", help="Moeda (default: BRL)."),
    gross_amount: float = typer.Option(..., "--gross-amount", help="Valor bruto."),
    items: str = typer.Option(..., "--items", help="Itens da ordem em formato JSON string."),
    expected_delivery_date: Optional[str] = typer.Option(
        None, "--expected-delivery-date", help="Data prevista de entrega (YYYY-MM-DD)."
    ),
    description: Optional[str] = typer.Option(None, "--description", help="Descricao da ordem."),
    discount_amount: Optional[float] = typer.Option(
        None, "--discount-amount", help="Valor de desconto."
    ),
    company_order_code: Optional[str] = typer.Option(
        None, "--company-order-code", help="Codigo da ordem na empresa."
    ),
    output: OutputFormat = typer.Option(
        OutputFormat.json, "--output", "-o", help="Formato: json|table|csv"
    ),
) -> None:
    """Cria uma nova ordem de compra.

    EXAMPLES:
      aegro purchase-orders create --company-key c1 --order-date 2025-06-01 --gross-amount 5000 --items '[{"productKey":"p1","quantity":10}]'
      aegro purchase-orders create --company-key c1 --order-date 2025-06-01 --gross-amount 5000 --items '[{"productKey":"p1","quantity":10}]' --description "Compra de sementes" --expected-delivery-date 2025-07-01
    """
    try:
        farm_name, api_key = require_farm()
        client = get_client()
        try:
            parsed_items = json_mod.loads(items)
        except json_mod.JSONDecodeError as exc:
            typer.echo(f"--items contem JSON invalido: {exc}", err=True)
            raise typer.Exit(4)

        body: dict = {
            "companyKey": company_key,
            "orderDate": order_date,
            "currencyCode": currency,
            "grossAmount": gross_amount,
            "items": parsed_items,
        }
        if expected_delivery_date is not None:
            body["expectedDeliveryDate"] = expected_delivery_date
        if description is not None:
            body["description"] = description
        if discount_amount is not None:
            body["discountAmount"] = discount_amount
        if company_order_code is not None:
            body["companyOrderCode"] = company_order_code
        result = client.post("/pub/v1/purchase-orders", api_key=api_key, json_body=body)
        if result is None:
            typer.echo(f"Ordem de compra criada na {farm_name}.")
        else:
            typer.echo(format_output(result, output))
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception as exc:
        handle_error(exc)
