/*
 * As colunas novas da linha de composição (product_materials) no estoque v2:
 * quando sai, a condição da opção, a quantidade por variação e a troca manual
 * da célula. Uma função pura só, usada pela rota da composição e pelo
 * cadastro do produto (gravar-produto.ts) — os dois caminhos que gravam linha.
 *
 * Empresa fora do v2: devolve {} e a linha é gravada exatamente como antes
 * (o banco põe `quando_sai = 'sempre'`, o padrão de sempre).
 */

import type { QuandoSai } from "./tipos.ts";

export const aparecemNoV2 = ["quando_sai", "condicao_opcao_id", "condicao_atributo", "condicao_valor", "qtd_por_variacao", "celulas"] as const;

const QUANDO: QuandoSai[] = ["sempre", "pela_variacao", "se_opcao", "so_custo"];
const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;

function texto(v: unknown): string | null {
  const t = typeof v === "string" ? v.trim() : "";
  return t ? t.slice(0, 200) : null;
}

function numero(v: unknown): number | null {
  if (typeof v === "number") return Number.isFinite(v) ? v : null;
  if (typeof v === "string" && v.trim()) {
    const n = Number(v.trim().replace(",", "."));
    return Number.isFinite(n) ? n : null;
  }
  return null;
}

function combinacao(v: unknown): Record<string, string> | null {
  if (!v || typeof v !== "object" || Array.isArray(v)) return null;
  const saida: Record<string, string> = {};
  for (const [k, val] of Object.entries(v as Record<string, unknown>)) {
    const chave = texto(k);
    const valor = texto(val);
    if (chave && valor) saida[chave] = valor;
  }
  return Object.keys(saida).length ? saida : null;
}

export type ColunasDoV2 = {
  quando_sai?: QuandoSai;
  condicao_opcao_id?: string | null;
  condicao_atributo?: string | null;
  condicao_valor?: string | null;
  qtd_por_variacao?: Array<{ combinacao: Record<string, string>; quantidade: number }>;
  celulas?: Array<{ combinacao: Record<string, string>; celula_id: string }>;
};

/** Limpa as colunas novas que vieram da tela. `v2 = false` → nada. */
export function linhaDaComposicaoParaGravar(entrada: Record<string, unknown> | null | undefined, v2: boolean): ColunasDoV2 {
  if (!v2 || !entrada) return {};
  const quando = QUANDO.includes(entrada.quando_sai as QuandoSai) ? (entrada.quando_sai as QuandoSai) : "sempre";
  const saida: ColunasDoV2 = { quando_sai: quando };

  if (quando === "se_opcao") {
    const opcao = texto(entrada.condicao_opcao_id);
    saida.condicao_opcao_id = opcao && UUID.test(opcao) ? opcao : null;
    saida.condicao_atributo = texto(entrada.condicao_atributo);
    saida.condicao_valor = texto(entrada.condicao_valor);
  } else {
    saida.condicao_opcao_id = null;
    saida.condicao_atributo = null;
    saida.condicao_valor = null;
  }

  const qtds = Array.isArray(entrada.qtd_por_variacao) ? entrada.qtd_por_variacao : [];
  saida.qtd_por_variacao = qtds
    .map((l) => {
      const linha = (l ?? {}) as Record<string, unknown>;
      const comb = combinacao(linha.combinacao);
      const q = numero(linha.quantidade);
      return comb && q !== null && q >= 0 ? { combinacao: comb, quantidade: q } : null;
    })
    .filter((l): l is { combinacao: Record<string, string>; quantidade: number } => Boolean(l))
    .slice(0, 300);

  const celulas = Array.isArray(entrada.celulas) ? entrada.celulas : [];
  saida.celulas = celulas
    .map((l) => {
      const linha = (l ?? {}) as Record<string, unknown>;
      const comb = combinacao(linha.combinacao);
      const id = texto(linha.celula_id);
      return comb && id && UUID.test(id) ? { combinacao: comb, celula_id: id } : null;
    })
    .filter((l): l is { combinacao: Record<string, string>; celula_id: string } => Boolean(l))
    .slice(0, 300);

  return saida;
}
