/*
 * A folha de um pedido ou orçamento em HTML, para virar PDF quando o link
 * público não serve (pedido que não veio de orçamento, link desligado ou
 * vencido). Segue o desenho da "folha limpa" do link público e do PDF do
 * painel: cabeçalho empresa × número, cliente × detalhes, tabela com filetes,
 * totais à direita, observações. Sem banco e sem "@/" (teste no node puro).
 *
 * Todo texto vem de cadastro (cliente, equipe) e passa por `escapar`.
 */

export type ItemDaFolha = {
  titulo: string;
  descricao?: string | null;
  medidas?: string | null;
  quantidade: number;
  unitario: number;
  total: number;
};

export type Folha = {
  rotulo: string;
  numero: string | number;
  emitidoEm?: string | null;
  empresa: { nome: string; cnpj?: string | null; endereco?: string | null; contatos?: string | null; logo?: string | null };
  cliente?: { nome: string; contatos?: string | null } | null;
  detalhes?: Array<[string, string]>;
  titulo?: string | null;
  itens: ItemDaFolha[];
  totais: Array<[string, string, boolean?]>;
  secoes?: Array<[string, string]>;
};

export function escapar(valor: unknown) {
  return String(valor ?? "")
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#39;");
}

export function reaisDaFolha(valor: unknown) {
  const numero = Number(valor);
  return (Number.isFinite(numero) ? numero : 0).toLocaleString("pt-BR", { style: "currency", currency: "BRL" });
}

function quantidade(valor: number) {
  return Number.isInteger(valor) ? String(valor) : valor.toLocaleString("pt-BR", { maximumFractionDigits: 3 });
}

/* Só imagem https vira <img>: o resto (data:, javascript:, endereço interno) fica de fora. */
function logoSegura(url: string | null | undefined) {
  const limpa = String(url || "").trim();
  return /^https:\/\/[^\s"'<>]+$/i.test(limpa) ? limpa : null;
}

function comQuebras(texto: string) {
  return escapar(texto).replace(/\n/g, "<br>");
}

export function htmlDaFolha(folha: Folha) {
  const logo = logoSegura(folha.empresa.logo);
  const linhas = folha.itens
    .map(
      (item, i) => `<tr>
        <td class="n">${i + 1}</td>
        <td><div class="t">${escapar(item.titulo)}</div>${item.descricao ? `<div class="d">${comQuebras(item.descricao)}</div>` : ""}</td>
        <td>${escapar(item.medidas || "")}</td>
        <td class="r">${escapar(quantidade(item.quantidade))}</td>
        <td class="r">${reaisDaFolha(item.unitario)}</td>
        <td class="r b">${reaisDaFolha(item.total)}</td>
      </tr>`
    )
    .join("");
  const detalhes = (folha.detalhes || []).filter(([, valor]) => valor);
  return `<!doctype html><html lang="pt-BR"><head><meta charset="utf-8"><title>${escapar(folha.rotulo)} ${escapar(folha.numero)}</title>
<style>
@page { size: A4; margin: 14mm; }
* { box-sizing: border-box; }
body { margin: 0; font-family: Arial, Helvetica, sans-serif; font-size: 12px; line-height: 1.45; color: #18181b; }
.topo { display: flex; justify-content: space-between; gap: 24px; border-bottom: 2px solid #18181b; padding-bottom: 14px; }
.empresa { display: flex; gap: 14px; align-items: flex-start; min-width: 0; }
.empresa img { height: 56px; max-width: 150px; object-fit: contain; }
.nome { font-size: 17px; font-weight: 700; }
.mini { font-size: 11px; color: #52525b; }
.numero { text-align: right; flex-shrink: 0; }
.rotulo { font-size: 10px; font-weight: 600; letter-spacing: .2em; text-transform: uppercase; color: #71717a; }
.grande { font-size: 26px; font-weight: 900; line-height: 1; margin-top: 2px; }
.faixa { display: grid; grid-template-columns: 1.35fr 1fr; gap: 32px; border-bottom: 1px solid #e4e4e7; padding: 14px 0; }
.titulinho { font-size: 9.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: #71717a; margin-bottom: 4px; }
dl { display: grid; grid-template-columns: auto 1fr; gap: 2px 12px; margin: 0; font-size: 11px; }
dt { color: #71717a; } dd { margin: 0; font-weight: 500; }
h2 { font-size: 14px; margin: 14px 0 0; }
table { width: 100%; border-collapse: collapse; margin-top: 12px; }
thead { display: table-header-group; }
th { text-align: left; font-size: 9.5px; letter-spacing: .12em; text-transform: uppercase; color: #71717a; border-bottom: 1.5px solid #18181b; padding: 6px 6px 6px 0; }
td { border-bottom: 1px solid #e4e4e7; padding: 7px 6px 7px 0; vertical-align: top; }
tr, .secao, img { break-inside: avoid; }
.n { width: 22px; color: #71717a; } .r { text-align: right; white-space: nowrap; } .b { font-weight: 700; }
.t { font-weight: 600; } .d { font-size: 11px; color: #52525b; }
.totais { display: flex; justify-content: flex-end; margin-top: 12px; }
.totais table { width: auto; min-width: 240px; margin: 0; }
.totais td { border: 0; padding: 2px 0 2px 24px; }
.totais .forte td { font-size: 14px; font-weight: 800; border-top: 1.5px solid #18181b; padding-top: 6px; }
.secao { margin-top: 18px; }
.secao .titulo { font-size: 10px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: #52525b; border-bottom: 1px solid #d4d4d8; padding-bottom: 4px; margin-bottom: 6px; }
</style></head><body>
<div class="topo secao" style="margin-top:0">
  <div class="empresa">
    ${logo ? `<img src="${escapar(logo)}" alt="">` : ""}
    <div>
      <div class="nome">${escapar(folha.empresa.nome)}</div>
      <div class="mini">
        ${folha.empresa.cnpj ? `<div>CNPJ ${escapar(folha.empresa.cnpj)}</div>` : ""}
        ${folha.empresa.endereco ? `<div>${escapar(folha.empresa.endereco)}</div>` : ""}
        ${folha.empresa.contatos ? `<div>${escapar(folha.empresa.contatos)}</div>` : ""}
      </div>
    </div>
  </div>
  <div class="numero">
    <div class="rotulo">${escapar(folha.rotulo)}</div>
    <div class="grande">#${escapar(folha.numero)}</div>
    ${folha.emitidoEm ? `<div class="mini" style="margin-top:8px">Emitido em ${escapar(folha.emitidoEm)}</div>` : ""}
  </div>
</div>
<div class="faixa">
  <div>
    <div class="titulinho">Cliente</div>
    <div style="font-size:13px;font-weight:600">${escapar(folha.cliente?.nome || "Cliente não informado")}</div>
    ${folha.cliente?.contatos ? `<div class="mini">${escapar(folha.cliente.contatos)}</div>` : ""}
  </div>
  ${
    detalhes.length
      ? `<div><div class="titulinho">Detalhes</div><dl>${detalhes.map(([rotulo, valor]) => `<dt>${escapar(rotulo)}</dt><dd>${escapar(valor)}</dd>`).join("")}</dl></div>`
      : "<div></div>"
  }
</div>
${folha.titulo ? `<h2>${escapar(folha.titulo)}</h2>` : ""}
<table>
  <thead><tr><th>#</th><th>Descrição</th><th>Tamanho</th><th class="r">Qtd</th><th class="r">Unitário</th><th class="r">Total</th></tr></thead>
  <tbody>${linhas || `<tr><td></td><td colspan="5" class="mini">Sem itens.</td></tr>`}</tbody>
</table>
<div class="totais secao" style="margin-top:12px"><table>${folha.totais
    .map(([rotulo, valor, forte]) => `<tr${forte ? ' class="forte"' : ""}><td>${escapar(rotulo)}</td><td class="r">${escapar(valor)}</td></tr>`)
    .join("")}</table></div>
${(folha.secoes || [])
  .filter(([, texto]) => texto && texto.trim())
  .map(([titulo, texto]) => `<div class="secao"><div class="titulo">${escapar(titulo)}</div><div>${comQuebras(texto)}</div></div>`)
  .join("")}
</body></html>`;
}

/* ------------------------------------------------ o que o Chrome pode buscar */

const NOME_DE_DENTRO = /(^|\.)(localhost|local|internal|intranet|lan|home|corp|localdomain)$/i;

/**
 * Ao imprimir uma página da loja, o Chrome do servidor só busca: a própria
 * página (o endereço da loja, que pode ser interno), e de fora só por https,
 * pelo nome (nunca por IP escrito) e nunca um nome de rede interna. Só GET:
 * nada que a página tente enviar (contador de leitura, formulários) sai.
 */
export function pedidoDoDocumentoPermitido(url: string, metodo: string, origemDaPagina: string | null) {
  if (url.startsWith("data:") || url.startsWith("about:") || url.startsWith("blob:")) return true;
  if (metodo.toUpperCase() !== "GET") return false;
  let endereco: URL;
  try {
    endereco = new URL(url);
  } catch {
    return false;
  }
  if (origemDaPagina && endereco.origin === origemDaPagina) return true;
  if (endereco.protocol !== "https:" || endereco.username || endereco.password) return false;
  const host = endereco.hostname.replace(/^\[|\]$/g, "");
  if (!host.includes(".") || NOME_DE_DENTRO.test(host)) return false;
  if (/^[\d.]+$/.test(host) || host.includes(":")) return false;
  if (endereco.port && endereco.port !== "443") return false;
  return true;
}
