/**
 * O custo do produto por unidade de venda, a partir do que está gravado.
 *
 * O modelo do produto é aditivo desde sempre: `cost_total` = custo base
 * estimado + soma da ficha técnica. O que faltava era a conta ser ciente da
 * unidade: as linhas da ficha são gravadas POR PEÇA DE REFERÊNCIA, e num
 * produto medido a unidade de venda é o m². Somar os dois sem dividir pela
 * área de referência dobrava o custo do banner — e o número dobrado ia parar
 * no `cost_total`, que é o que orçamento, pedido e congelamento usam.
 *
 * Esta função é A conta, usada pela tela do produto e pelos três pontos do
 * servidor que recalculam custo. Conta repetida é conta que diverge.
 */

const duasCasas = (n: number) => Math.round(n * 100) / 100;
const positivo = (v: unknown) => {
  const n = Number(v);
  return Number.isFinite(n) && n > 0 ? n : 0;
};

export type EntradaDoCusto = {
  /* Custos fora da ficha, na unidade de venda. Produto nascido no assistente
     de precificação grava 0 aqui: a ficha já é o custo inteiro. */
  estimatedBaseCost?: number | null;
  /* Soma das linhas da ficha, por peça de referência. */
  somaDaFicha: number;
  unitType?: string | null;
  referenceWidthM?: number | null;
  referenceHeightM?: number | null;
};

/** A ficha convertida para a unidade de venda: ÷ área quando o produto é
 * medido e a referência existe. Medido SEM referência não tem conversão
 * honesta — fica como está, que é o comportamento que os produtos antigos
 * sempre tiveram. */
export function fichaPorUnidadeDeVenda(e: EntradaDoCusto): number {
  const area = positivo(e.referenceWidthM) * positivo(e.referenceHeightM);
  if (e.unitType === "square_meter" && area > 0) {
    return duasCasas(positivo(e.somaDaFicha) / area);
  }
  return duasCasas(positivo(e.somaDaFicha));
}

export function custoDoProduto(e: EntradaDoCusto): number {
  return duasCasas(positivo(e.estimatedBaseCost) + fichaPorUnidadeDeVenda(e));
}
