import { mapearStatusXbz } from "./xbz.status.ts";
import type { StatusPedido } from "./xbz.types.ts";

/**
 * Um pedido da XBZ do jeito que a tela mostra.
 *
 * O `PedidosListar` devolve bem mais do que a integração lia: produto,
 * quantidade, preço unitário, pagamento, entrega e transportadora. E o valor
 * vem em `pedidoValorTotal`, que a integração não procurava (lia
 * `valorTotal`), por isso a coluna Valor ficava vazia.
 *
 * Junta o que a XBZ devolveu com o que foi enviado: o pedido recém-criado
 * pode voltar só com o número.
 */

export type PedidoXbzResumo = {
  numero: string;
  ordemDeCompra: string | null;
  statusXbz: string | null;
  statusMapeado: StatusPedido;
  valorTotal: number | null;
  emissao: string | null;
  produto: string | null;
  codigoXbz: string | null;
  codigoComposto: string | null;
  quantidade: number | null;
  precoUnitario: number | null;
  pagamento: string | null;
  entrega: string | null;
  transportadora: string | null;
  pedidoLocalId: string | null;
};

type Registro = Record<string, unknown>;

function texto(registros: Registro[], chaves: string[]): string | null {
  for (const registro of registros) {
    for (const chave of chaves) {
      const valor = registro[chave];
      if (typeof valor === "string" && valor.trim()) return valor.trim();
      if (typeof valor === "number" && Number.isFinite(valor)) return String(valor);
    }
  }
  return null;
}

function numero(registros: Registro[], chaves: string[]): number | null {
  for (const registro of registros) {
    for (const chave of chaves) {
      const valor = registro[chave];
      if (typeof valor === "number" && Number.isFinite(valor)) return valor;
      if (typeof valor === "string" && valor.trim()) {
        const lido = Number(valor.includes(",") ? valor.replace(/\./g, "").replace(",", ".") : valor);
        if (Number.isFinite(lido)) return lido;
      }
    }
  }
  return null;
}

const objeto = (valor: unknown): Registro => (valor && typeof valor === "object" && !Array.isArray(valor) ? (valor as Registro) : {});

export function numeroDoPedidoXbz(registro: unknown): string | null {
  return texto([objeto(registro)], ["numero", "pedidoNumero", "pedido_numero"]);
}

export function valorDoPedidoXbz(registro: unknown): number | null {
  return numero([objeto(registro)], ["pedidoValorTotal", "valorTotal", "valor_total", "total"]);
}

export function statusDoPedidoXbz(registro: unknown): string | null {
  return texto([objeto(registro)], ["statusLogistico", "status"]);
}

/** O retorno da XBZ, o que foi enviado e o que a Ktalogu já sabia do pedido. */
export function resumoDoPedidoXbz(entrada: {
  retorno?: unknown;
  envio?: unknown;
  numero?: string | null;
  statusXbz?: string | null;
  valorTotal?: number | null;
  pedidoLocalId?: string | null;
  criadoEm?: string | null;
}): PedidoXbzResumo | null {
  const retorno = objeto(entrada.retorno);
  const envio = objeto(entrada.envio);
  const ambos = [retorno, envio];
  const numeroDoPedido = entrada.numero || numeroDoPedidoXbz(retorno);
  if (!numeroDoPedido) return null;
  const statusXbz = statusDoPedidoXbz(retorno) || entrada.statusXbz || null;
  const quantidade = numero(ambos, ["quantidade"]);
  const precoUnitario = numero([retorno], ["produtoPrecoUnitario", "precoUnitario"]);

  return {
    numero: numeroDoPedido,
    ordemDeCompra: texto(ambos, ["ordemDeCompra"]),
    statusXbz,
    statusMapeado: mapearStatusXbz(statusXbz),
    valorTotal:
      valorDoPedidoXbz(retorno) ??
      entrada.valorTotal ??
      (quantidade !== null && precoUnitario !== null ? Math.round(quantidade * precoUnitario * 100) / 100 : null),
    emissao: texto([retorno], ["dataEmissao", "emissaoData"]) || entrada.criadoEm || null,
    produto: texto([retorno], ["produtoNome"]),
    codigoXbz: texto(ambos, ["produtoCodigoXbz"]),
    codigoComposto: texto([retorno], ["produtoCodigoComposto"]),
    quantidade,
    precoUnitario,
    pagamento: texto([retorno], ["pagamentoTipoNome"]),
    entrega: texto([retorno], ["entregaTipoNome"]),
    transportadora: texto([retorno], ["entregaTransportadoraGravacaoNome"]),
    pedidoLocalId: entrada.pedidoLocalId ?? null,
  };
}
