import { formatDateBr } from "../../utils/formatters.ts";
import { quantidadeDoItem } from "./quantidade-do-item.ts";
import {
  explicarConsumo,
  formatarDuracao,
  notasDaQuantidade,
  quantidadeLegivel,
  unidadeLegivel,
  type ConsumoDoInsumo,
  type LinhaDeSeparacao,
  type TempoDoProcesso,
} from "./ficha-de-producao.ts";

/**
 * A ordem de produção impressa.
 *
 * É o papel que vai para a bancada. Diz o que separar, o que fazer, em que
 * ordem e em quanto tempo — e deixa espaço para quem fez anotar quando
 * começou, quando terminou, e o que se perdeu ou teve de ser refeito. Não tem
 * preço, desconto nem telefone do cliente: nada disso ajuda a produzir, e
 * ficha que circula na oficina não é lugar para valor comercial.
 *
 * Tipografia de papel: a mesma família do sistema (Plus Jakarta Sans, com
 * fallback do sistema), só três pesos (400, 600, 700) e todo texto preto —
 * hierarquia vem do tamanho e do peso, não de cinza. Cor só em fundo e
 * borda, para guiar o olho sem clarear a leitura.
 */

export type ProductionSheetVariacao = { atributo: string; valor: string };
export type ProductionSheetGabarito = { nome: string; url: string; formato: string };

export type ProductionSheetItem = {
  id?: string | null;
  title?: string | null;
  description?: string | null;
  quantity?: number | string | null;
  unit_type?: string | null;
  width_m?: number | string | null;
  height_m?: number | string | null;
  length_m?: number | string | null;
  sku?: string | null;
  barcode?: string | null;
  /* Falso no item avulso: sem produto não há ficha técnica, só a descrição. */
  tem_produto?: boolean | null;
  variacoes?: ProductionSheetVariacao[] | null;
  insumos?: ConsumoDoInsumo[] | null;
  processos?: TempoDoProcesso[] | null;
  minutos_totais?: number | null;
  /* O que a bancada precisa saber antes de confiar na ficha deste item. */
  avisos?: string[] | null;
  /* De onde veio a receita: congelada na venda, do cadastro atual, ou nenhuma. */
  receita_de?: "venda" | "cadastro" | "nenhuma" | null;
  receita_em?: string | null;
  gabaritos?: ProductionSheetGabarito[] | null;
  art_images?: string[] | null;
};

export type ProductionSheetPayload = {
  order?: {
    id?: string | null;
    number?: number | string | null;
    created_at?: string | null;
    status?: string | null;
    notes?: string | null;
    internal_notes?: string | null;
    quote_title?: string | null;
    delivery_date?: string | null;
    production_started_at?: string | null;
    production_accumulated_seconds?: number | null;
    production_last_stopped_at?: string | null;
    /* A soma dos processos da ficha, no tamanho e quantidade deste pedido. */
    minutos_previstos?: number | null;
  } | null;
  company?: {
    catalog_name?: string | null;
    store_name?: string | null;
    logo_url?: string | null;
    catalog_logo_url?: string | null;
  } | null;
  client?: {
    name?: string | null;
    company_name?: string | null;
  } | null;
  items?: ProductionSheetItem[] | null;
  /* Cada insumo uma vez, somado entre os itens: a lista do almoxarifado. */
  separacao?: LinhaDeSeparacao[] | null;
};

type ProductionSheetHtmlOptions = {
  autoPrint?: boolean;
  autoClose?: boolean;
};

function toNumber(value: number | string | null | undefined) {
  const parsed = Number(value);
  return Number.isFinite(parsed) ? parsed : 0;
}

function formatNumber(value: number | string | null | undefined, digits = 3) {
  return new Intl.NumberFormat("pt-BR", {
    minimumFractionDigits: 0,
    maximumFractionDigits: digits,
  }).format(toNumber(value));
}

function formatDate(value?: string | null) {
  if (!value) return "-";
  return formatDateBr(value) || "-";
}

function escapeHtml(value: string) {
  return value
    .replace(/&/g, "&amp;")
    .replace(/</g, "&lt;")
    .replace(/>/g, "&gt;")
    .replace(/"/g, "&quot;")
    .replace(/'/g, "&#39;");
}


function humanizeStatus(status?: string | null) {
  switch (status) {
    case "pending_production":
      return "Aguardando produção";
    case "in_production":
      return "Em produção";
    case "finished":
      return "Finalizado";
    case "delivered":
      return "Entregue";
    case "canceled":
      return "Cancelado";
    default:
      return status || "-";
  }
}

/* Na bancada, o que cobre a peça vem antes do que a contorna, e o que é por
   peça fecha a lista. É a ordem em que se separa. */
const ORDEM_DA_BASE: Record<ConsumoDoInsumo["base"], number> = {
  por_m2: 0,
  por_m_largura: 1,
  por_m_altura: 2,
  por_perimetro: 3,
  por_peca: 4,
};

function ordenarInsumos(insumos: ConsumoDoInsumo[]) {
  return [...insumos].sort((a, b) => {
    const base = ORDEM_DA_BASE[a.base] - ORDEM_DA_BASE[b.base];
    if (base !== 0) return base;
    if (a.origem.tipo !== b.origem.tipo) return a.origem.tipo === "ficha" ? -1 : 1;
    return a.nome.localeCompare(b.nome, "pt-BR");
  });
}

function companyName(payload: ProductionSheetPayload) {
  return payload.company?.catalog_name || payload.company?.store_name || "Empresa";
}

function clientDisplayName(payload: ProductionSheetPayload) {
  return payload.client?.company_name || payload.client?.name || "Cliente";
}

function renderInsumos(insumos: ConsumoDoInsumo[], temProduto: boolean) {
  if (!insumos.length) {
    return `<div class="empty-state">${
      temProduto ? "Produto sem insumos na ficha técnica." : "Item sem produto vinculado: sem ficha técnica."
    }</div>`;
  }

  const rows = ordenarInsumos(insumos)
    .map((insumo) => {
      const nome = escapeHtml(insumo.nome || "Material");
      /* A quantidade na unidade em que se lê (17 ml, não 0,017 l), e as
         notas de onde o número veio — as mesmas do painel. */
      const legivel = quantidadeLegivel(insumo.quantidade, insumo.unidade);
      const notas = notasDaQuantidade(insumo)
        .map((nota) => `<div class="sub">${escapeHtml(nota)}</div>`)
        .join("");
      const origem =
        insumo.origem.tipo === "opcao"
          ? `<span class="tag tag-opcao">opção: ${escapeHtml(insumo.origem.opcao)}</span>`
          : "";
      const receita = explicarConsumo(insumo);
      const quantidade = insumo.semMedida
        ? '<span class="warn">sem medida no item</span>'
        : `<span class="qtd">${formatNumber(legivel.valor)} <small>${escapeHtml(legivel.unidade)}</small></span>${notas}`;
      /* Serviço não se separa: sem caixa para marcar. */
      const marca = insumo.natureza === "servico" ? "" : '<span class="check"></span>';
      return `<tr><td class="nome">${nome}${origem}</td><td class="calc">${escapeHtml(receita)}</td><td class="align-right">${quantidade}</td><td class="marca">${marca}</td></tr>`;
    })
    .join("");

  return `
    <table class="tabela">
      <thead><tr><th>Insumo</th><th>Como se calcula</th><th class="align-right">Separar</th><th class="marca">OK</th></tr></thead>
      <tbody>${rows}</tbody>
    </table>
  `;
}

function renderProcessos(processos: TempoDoProcesso[], minutosTotais: number, temProduto: boolean) {
  if (!processos.length) {
    return `<div class="empty-state">${
      temProduto ? "Produto sem processos na ficha técnica." : "Item sem produto vinculado: sem ficha técnica."
    }</div>`;
  }

  const rows = processos
    .map((processo, index) => {
      const nome = escapeHtml(processo.nome || "Processo");
      const recurso = escapeHtml(processo.recurso || "-");
      const tipo = processo.tipo === "maquina" ? "máquina" : processo.tipo === "pessoa" ? "pessoa" : "";
      const tempo = processo.semMedida
        ? '<span class="warn">sem medida no item</span>'
        : `<span class="qtd">${escapeHtml(formatarDuracao(processo.minutosTotais))}</span>${
            processo.minutosDeSetup > 0
              ? `<div class="sub">${formatNumber(processo.minutosDeProducao, 1)} + ${formatNumber(processo.minutosDeSetup, 1)} min preparo</div>`
              : ""
          }`;
      return `<tr><td class="num"><span class="passo">${index + 1}</span></td><td class="nome">${nome}</td><td class="calc">${recurso}${
        tipo ? ` <span class="sub-inline">${tipo}</span>` : ""
      }</td><td class="align-right">${tempo}</td><td class="marca"><span class="check"></span></td></tr>`;
    })
    .join("");

  return `
    <table class="tabela">
      <thead><tr><th class="num">#</th><th>Processo</th><th>Recurso</th><th class="align-right">Tempo</th><th class="marca">Feito</th></tr></thead>
      <tbody>${rows}</tbody>
      <tfoot><tr><td colspan="3">Tempo previsto do item</td><td class="align-right"><span class="qtd">${escapeHtml(formatarDuracao(minutosTotais))}</span></td><td></td></tr></tfoot>
    </table>
  `;
}

function renderGabaritos(gabaritos: ProductionSheetGabarito[]) {
  if (!gabaritos.length) return "";
  const rows = gabaritos
    .map(
      (g) =>
        `<li><span class="tag">${escapeHtml(g.formato.toUpperCase())}</span><a href="${escapeHtml(g.url)}" target="_blank" rel="noreferrer">${escapeHtml(g.nome)}</a></li>`
    )
    .join("");
  return `<div class="linha-bloco"><span class="block-title">Gabaritos</span><ul class="gabaritos">${rows}</ul></div>`;
}

function renderVariacoes(variacoes: ProductionSheetVariacao[]) {
  if (!variacoes.length) return "";
  return `<span class="chips">${variacoes
    .map((v) => `<span class="chip"><span class="chip-key">${escapeHtml(v.atributo)}</span>${escapeHtml(v.valor)}</span>`)
    .join("")}</span>`;
}

function renderArtes(artImages: string[]) {
  if (!artImages.length) return "";
  return `
    <div class="artes">
      <span class="block-title">Artes aprovadas</span>
      <div class="art-list">${artImages
        .map(
          (url) =>
            `<div class="art-thumb-wrap"><img class="art-thumb" src="${escapeHtml(url)}" alt="Arte do item" /></div>`
        )
        .join("")}</div>
    </div>
  `;
}

/* Quem fez, de quando a quando, e se conferiu: enquanto o apontamento não
   está em tela, o papel é o registro. */
function renderExecucao() {
  return `
    <div class="execucao">
      <span class="campo campo-largo"><span class="campo-label">Responsável</span><span class="linha"></span></span>
      <span class="campo"><span class="campo-label">Início</span><span class="linha linha-curta"></span></span>
      <span class="campo"><span class="campo-label">Fim</span><span class="linha linha-curta"></span></span>
      <span class="campo campo-check"><span class="check"></span><span class="campo-label">Conferido</span></span>
    </div>
  `;
}

/* Perdas e retrabalho: o que se estragou, quanto, por quê. É o que depois vira
   baixa de estoque e histórico do produto — e é justamente o que hoje se
   perde na conversa de corredor. */
function renderPerdas() {
  const linhas = [1, 2, 3]
    .map(
      () =>
        `<tr><td></td><td class="col-qtd"></td><td></td><td class="col-refeito"><span class="check"></span></td></tr>`
    )
    .join("");
  return `
    <div class="perdas">
      <div class="perdas-head">
        <span class="block-title">Perdas e retrabalho</span>
        <span class="campo campo-check"><span class="check"></span><span class="campo-label">Sem perdas nem retrabalho</span></span>
      </div>
      <table class="tabela tabela-vazia">
        <thead><tr><th>Insumo ou peça</th><th class="col-qtd">Qtd</th><th>Motivo (impressão, corte, defeito do insumo, cliente…)</th><th class="col-refeito">Refeito</th></tr></thead>
        <tbody>${linhas}</tbody>
      </table>
    </div>
  `;
}

function renderItems(items: ProductionSheetItem[]) {
  if (!items.length) {
    return '<section class="item-card"><div class="empty-state">Não há itens neste pedido.</div></section>';
  }

  return items
    .map((item, index) => {
      const title = escapeHtml(item.title || "Item sem título");
      const description = (item.description || "").trim();
      const quantidade = quantidadeDoItem(item);
      const temProduto = item.tem_produto !== false;
      const insumos = Array.isArray(item.insumos) ? item.insumos : [];
      const processos = Array.isArray(item.processos) ? item.processos : [];
      const variacoes = Array.isArray(item.variacoes) ? item.variacoes : [];
      const gabaritos = Array.isArray(item.gabaritos) ? item.gabaritos : [];
      const avisos = Array.isArray(item.avisos) ? item.avisos.filter(Boolean) : [];
      const artImages = Array.isArray(item.art_images) ? item.art_images.filter(Boolean) : [];

      const barcodeText = item.barcode ? `Cód. ${escapeHtml(item.barcode)}` : "";
      const skuText = item.sku ? `SKU ${escapeHtml(item.sku)}` : "";
      const identifierText = [skuText, barcodeText].filter(Boolean).join(" · ");
      const receita =
        item.receita_de === "venda"
          ? `Receita congelada na venda${item.receita_em ? ` em ${escapeHtml(formatDate(item.receita_em))}` : ""}`
          : item.receita_de === "cadastro"
            ? "Receita do cadastro atual do produto"
            : "";

      return `
        <section class="item-card">
          <div class="item-head">
            <div class="item-title">
              <span class="item-num">${index + 1}</span>
              <h2>${title}</h2>
              ${identifierText ? `<span class="ids">${identifierText}</span>` : ""}
              ${renderVariacoes(variacoes)}
            </div>
            <div class="badges">
              <span class="badge badge-qty">${escapeHtml(quantidade.pecasTexto)}</span>
              ${quantidade.medida ? `<span class="badge">${escapeHtml(quantidade.medida)}</span>` : ""}
              ${quantidade.total ? `<span class="badge">${escapeHtml(quantidade.total)}</span>` : ""}
              ${
                processos.length
                  ? `<span class="badge badge-time">${escapeHtml(formatarDuracao(toNumber(item.minutos_totais)))}</span>`
                  : ""
              }
            </div>
          </div>
          ${description ? `<div class="description-box">${escapeHtml(description)}</div>` : ""}
          ${
            temProduto
              ? ""
              : '<div class="aviso">Item sem produto vinculado: não há ficha técnica. Produzir pela descrição e pela arte.</div>'
          }
          ${avisos.map((aviso) => `<div class="aviso">${escapeHtml(aviso)}</div>`).join("")}
          <div class="panels">
            <div class="panel">
              <h3>Insumos</h3>
              ${renderInsumos(insumos, temProduto)}
            </div>
            <div class="panel panel-processos">
              <h3>Processos, na ordem</h3>
              ${renderProcessos(processos, toNumber(item.minutos_totais), temProduto)}
            </div>
          </div>
          ${receita ? `<div class="receita-de">${receita}</div>` : ""}
          ${renderGabaritos(gabaritos)}
          ${renderArtes(artImages)}
          ${renderExecucao()}
          ${renderPerdas()}
        </section>
      `;
    })
    .join("");
}

/* O checklist de separação vai numa folha própria: quem separa insumo é o
   almoxarifado, e a folha dele circula sozinha, antes da produção começar.
   Linhas altas para marcar e anotar à mão. */
function renderChecklistDeSeparacao(
  separacao: LinhaDeSeparacao[],
  cabecalho: { logoUrl: string; empresa: string; numero: string; cliente: string; entrega: string; itens: number }
) {
  if (!separacao.length) return "";
  const rows = separacao
    .map((linha, index) => {
      const legivel = quantidadeLegivel(linha.quantidade, linha.unidade);
      /* Com rendimento, a folha inteira veio da soma das frações dos itens. */
      const soma =
        linha.natureza === "rendimento" && linha.fracaoSomada > 0 && linha.fracaoSomada !== linha.quantidade
          ? `<div class="sub">${formatNumber(linha.fracaoSomada)} pela soma dos itens</div>`
          : "";
      return `<tr>
          <td class="cl-check"><span class="check check-grande"></span></td>
          <td class="cl-num">${index + 1}</td>
          <td class="cl-nome">${escapeHtml(linha.nome)}</td>
          <td class="cl-qtd"><span class="qtd qtd-grande">${formatNumber(legivel.valor)} <small>${escapeHtml(legivel.unidade)}</small></span>${soma}</td>
          <td class="cl-itens">${linha.itens} ${linha.itens === 1 ? "item" : "itens"}</td>
          <td class="cl-obs"></td>
        </tr>`;
    })
    .join("");
  return `
    <section class="separacao-pagina">
      <div class="quebra-de-pagina"><span>folha seguinte</span></div>
      <header class="header">
        <div class="brand">
          ${cabecalho.logoUrl ? `<img class="brand-logo" src="${escapeHtml(cabecalho.logoUrl)}" alt="Logo da empresa" />` : ""}
          <div>
            <div class="title">Checklist de separação de insumos</div>
            <div class="company-name">${cabecalho.empresa}</div>
          </div>
        </div>
        <div class="header-right">
          <div class="order-number"><small>PEDIDO</small>#${cabecalho.numero}</div>
          <div class="order-sub">Entrega ${cabecalho.entrega}</div>
        </div>
      </header>
      <div class="meta-row">
        <span class="meta"><span class="meta-label">Cliente</span><span class="meta-value">${cabecalho.cliente}</span></span>
        <span class="meta"><span class="meta-label">Insumos</span><span class="meta-value">${separacao.length}</span></span>
        <span class="meta"><span class="meta-label">Itens do pedido</span><span class="meta-value">${cabecalho.itens}</span></span>
      </div>
      <p class="checklist-instrucao">Separe tudo antes de liberar o pedido para a bancada. Marque cada linha ao separar e anote o que faltou ou foi trocado.</p>
      <table class="checklist">
        <thead><tr><th class="cl-check"></th><th class="cl-num">#</th><th>Insumo</th><th class="cl-qtd">Quantidade</th><th class="cl-itens">Usado em</th><th class="cl-obs">Faltou / trocado por / observação</th></tr></thead>
        <tbody>${rows}</tbody>
      </table>
      <div class="checklist-foot">
        <span class="campo campo-largo"><span class="campo-label">Separado por</span><span class="linha"></span></span>
        <span class="campo"><span class="campo-label">Data</span><span class="linha linha-curta"></span></span>
        <span class="campo campo-check"><span class="check"></span><span class="campo-label">Tudo separado</span></span>
        <span class="campo campo-check"><span class="check"></span><span class="campo-label">Faltou algo</span></span>
      </div>
    </section>
  `;
}

export function buildProductionSheetHtml(
  payload: ProductionSheetPayload,
  options: ProductionSheetHtmlOptions = {}
) {
  const autoPrint = options.autoPrint === true;
  const autoClose = options.autoClose === true;
  const safeCompany = escapeHtml(companyName(payload));
  const safeClient = escapeHtml(clientDisplayName(payload));
  const orderNumber = escapeHtml(String(payload.order?.number ?? "-"));
  const status = escapeHtml(humanizeStatus(payload.order?.status));
  const createdAt = escapeHtml(formatDate(payload.order?.created_at));
  const quoteTitle = (payload.order?.quote_title || "").trim();
  const deliveryDate = escapeHtml(formatDate(payload.order?.delivery_date));
  const minutosPrevistos = toNumber(payload.order?.minutos_previstos);
  const tempoPrevisto = minutosPrevistos > 0 ? escapeHtml(formatarDuracao(minutosPrevistos)) : "sem ficha";
  const notes = (payload.order?.notes || "").trim();
  const internalNotes = (payload.order?.internal_notes || "").trim();
  const logoUrl = (payload.company?.logo_url || payload.company?.catalog_logo_url || "").trim();
  const items = Array.isArray(payload.items) ? payload.items : [];
  const separacao = Array.isArray(payload.separacao) ? payload.separacao : [];

  return `<!doctype html>
<html lang="pt-BR">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>Ordem de produção #${orderNumber}</title>
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link href="https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;600;700&display=swap" rel="stylesheet" />
    <style>
      @page { size: A4; margin: 10mm 11mm; }
      :root {
        --tinta: #111111;
        --roxo: #4425a7;
        --roxo-claro: #efeaff;
        --rosa-claro: #fdf2f8;
        --alerta: #b45309;
        --alerta-claro: #fff7ed;
        --papel: #ffffff;
        --fundo: #f4f3f8;
        --borda: #d9dbe3;
        --borda-forte: #b8bcc8;
      }
      * { box-sizing: border-box; }
      html { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
      body {
        margin: 0;
        font-family: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
        color: var(--tinta);
        background: #e9e8ef;
        font-size: 12px;
        line-height: 1.4;
        font-weight: 400;
        -webkit-font-smoothing: antialiased;
      }
      .sheet { width: 100%; max-width: 940px; margin: 0 auto; background: var(--papel); padding: 16px 20px 14px; }
      strong, b { font-weight: 700; }

      /* Cabeçalho ------------------------------------------------------ */
      .header {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 14px;
        padding-bottom: 8px;
        border-bottom: 2px solid var(--roxo);
      }
      .brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
      .brand-logo { height: 40px; width: auto; max-width: 120px; object-fit: contain; flex-shrink: 0; }
      .title { font-size: 10px; letter-spacing: 0.12em; font-weight: 600; text-transform: uppercase; }
      .company-name { font-size: 18px; font-weight: 700; line-height: 1.15; }
      .header-right { text-align: right; flex-shrink: 0; }
      .order-number { font-size: 26px; font-weight: 700; line-height: 1; letter-spacing: -0.01em; font-variant-numeric: tabular-nums; }
      .order-number small { font-size: 11px; font-weight: 600; letter-spacing: 0.1em; margin-right: 5px; }
      .order-sub { font-size: 11px; margin-top: 4px; }
      .status-pill {
        display: inline-block;
        margin-left: 6px;
        padding: 1px 7px;
        border-radius: 999px;
        border: 1px solid var(--tinta);
        font-size: 9.5px;
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: 0.05em;
      }

      /* Resumo do pedido: uma linha, sem caixas ------------------------ */
      .meta-row {
        display: flex;
        flex-wrap: wrap;
        align-items: baseline;
        gap: 4px 0;
        margin-top: 8px;
        padding-bottom: 8px;
        border-bottom: 1px solid var(--borda);
      }
      .meta { display: flex; align-items: baseline; gap: 6px; padding: 0 14px; border-left: 1px solid var(--borda); }
      .meta:first-child { padding-left: 0; border-left: none; }
      .meta-label { font-size: 9.5px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; }
      .meta-value { font-size: 13px; font-weight: 700; font-variant-numeric: tabular-nums; }
      .meta-title { margin-top: 6px; font-size: 12px; }

      /* Item ----------------------------------------------------------- */
      .item-card { margin-top: 14px; padding-top: 8px; border-top: 2px solid var(--tinta); break-inside: avoid; page-break-inside: avoid; }
      .item-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
      .item-title { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; min-width: 0; }
      .item-head h2 { margin: 0; font-size: 15px; line-height: 1.2; font-weight: 700; }
      .item-num {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 22px;
        height: 22px;
        border-radius: 6px;
        border: 1.5px solid var(--tinta);
        font-size: 12px;
        font-weight: 700;
        flex-shrink: 0;
      }
      .ids { font-size: 10.5px; }
      .badges { display: flex; flex-wrap: wrap; gap: 5px; justify-content: flex-end; flex-shrink: 0; }
      .badge {
        display: inline-flex;
        align-items: center;
        border-radius: 999px;
        padding: 3px 9px;
        font-weight: 600;
        font-size: 11px;
        white-space: nowrap;
        font-variant-numeric: tabular-nums;
        border: 1px solid var(--tinta);
        background: var(--papel);
      }
      .badge-qty { font-weight: 700; background: var(--fundo); }
      .badge-time { border-color: var(--roxo); background: var(--roxo-claro); font-weight: 700; }
      .chips { display: inline-flex; flex-wrap: wrap; gap: 5px; }
      .chip { display: inline-flex; align-items: baseline; gap: 4px; border: 1px solid var(--roxo); border-radius: 6px; padding: 1px 7px; font-size: 11px; font-weight: 600; background: var(--roxo-claro); }
      .chip-key { font-size: 9px; text-transform: uppercase; letter-spacing: 0.06em; }
      .description-box { margin-top: 6px; padding: 3px 0 3px 9px; border-left: 3px solid var(--roxo); font-size: 12px; white-space: pre-wrap; }
      .aviso { margin-top: 6px; padding: 4px 9px; border-left: 3px solid var(--alerta); background: var(--alerta-claro); font-size: 11.5px; font-weight: 600; }

      /* Painéis -------------------------------------------------------- */
      .panels { margin-top: 8px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; break-inside: avoid-page; page-break-inside: avoid; }
      .panel { border: 1px solid var(--borda); border-radius: 6px; overflow: hidden; background: var(--papel); break-inside: avoid-page; page-break-inside: avoid; }
      .panel h3 {
        margin: 0;
        padding: 5px 8px;
        font-size: 10px;
        font-weight: 700;
        text-transform: uppercase;
        letter-spacing: 0.08em;
        background: var(--fundo);
        border-left: 3px solid var(--tinta);
        border-bottom: 1px solid var(--borda);
      }
      .panel-processos h3 { border-left-color: var(--roxo); }
      .tabela { width: 100%; border-collapse: collapse; font-size: 11.5px; font-variant-numeric: tabular-nums; }
      .tabela th, .tabela td { padding: 4px 7px; border-bottom: 1px solid var(--borda); vertical-align: top; }
      .tabela tbody tr:last-child td { border-bottom: none; }
      .tabela th { font-size: 9.5px; text-align: left; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; background: var(--fundo); }
      .tabela tfoot td { border-top: 1.5px solid var(--tinta); border-bottom: none; font-weight: 700; background: var(--fundo); }
      .tabela td.nome { font-weight: 600; }
      .tabela td.calc { font-size: 11px; }
      .align-right { text-align: right; }
      .num { width: 26px; text-align: center; }
      .passo { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 999px; background: var(--roxo-claro); font-size: 10px; font-weight: 700; }
      .marca { width: 30px; text-align: center; }
      .sub { font-size: 10px; margin-top: 1px; white-space: nowrap; }
      .sub-inline { font-size: 10px; }
      .qtd { font-weight: 700; font-size: 12px; white-space: nowrap; }
      .qtd small { font-size: 10px; font-weight: 600; }
      .warn { font-weight: 700; font-size: 11px; background: var(--alerta-claro); padding: 0 4px; }
      .tag { display: inline-block; margin-left: 5px; padding: 0 5px; border-radius: 3px; background: var(--roxo-claro); font-size: 9.5px; font-weight: 600; vertical-align: middle; white-space: nowrap; }
      .tag-opcao { background: var(--rosa-claro); }
      .empty-state { padding: 8px; font-size: 11.5px; }
      .receita-de { margin-top: 3px; font-size: 10px; text-align: right; }

      /* Gabaritos e artes ---------------------------------------------- */
      .block-title { font-size: 9.5px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; white-space: nowrap; }
      .linha-bloco { display: flex; align-items: baseline; gap: 10px; margin-top: 6px; font-size: 11.5px; }
      .gabaritos { margin: 0; padding: 0; list-style: none; display: flex; flex-wrap: wrap; gap: 4px 14px; }
      .gabaritos a { color: var(--tinta); font-weight: 600; word-break: break-all; }
      .gabaritos .tag { margin-left: 0; margin-right: 4px; }
      .artes { margin-top: 6px; break-inside: avoid-page; page-break-inside: avoid; }
      .art-list { margin-top: 4px; display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 6px; }
      .art-thumb-wrap { position: relative; border: 1px solid var(--borda); border-radius: 4px; overflow: hidden; background: var(--papel); width: 100%; padding-top: 100%; }
      .art-thumb { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: contain; display: block; }

      /* Execução e perdas ---------------------------------------------- */
      .execucao { margin-top: 8px; display: flex; flex-wrap: wrap; align-items: flex-end; gap: 12px; padding-top: 6px; border-top: 1px dashed var(--borda-forte); font-size: 11px; break-inside: avoid-page; page-break-inside: avoid; }
      .campo { display: inline-flex; align-items: flex-end; gap: 5px; }
      .campo-largo { flex: 1 1 200px; }
      .campo-label { font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; font-size: 9.5px; white-space: nowrap; }
      .linha { display: inline-block; flex: 1; min-width: 110px; border-bottom: 1px solid var(--tinta); height: 14px; }
      .linha-curta { flex: 0 0 auto; width: 100px; min-width: 0; }
      .check { display: inline-block; width: 12px; height: 12px; border: 1px solid var(--tinta); border-radius: 3px; vertical-align: middle; background: var(--papel); }
      .campo-check { align-items: center; }
      .perdas { margin-top: 6px; break-inside: avoid-page; page-break-inside: avoid; }
      .perdas-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; padding: 3px 0; }
      .tabela-vazia th { background: var(--rosa-claro); }
      .tabela-vazia td { border-bottom: 1px solid var(--borda-forte); height: 20px; }
      .tabela-vazia tbody tr:last-child td { border-bottom: 1px solid var(--borda-forte); }
      .col-qtd { width: 60px; }
      .col-refeito { width: 54px; text-align: center; }

      /* Checklist de separação: folha própria ------------------------- */
      .separacao-pagina { break-before: page; page-break-before: always; margin-top: 36px; }
      .quebra-de-pagina { display: flex; align-items: center; gap: 10px; margin-bottom: 16px; font-size: 9.5px; text-transform: uppercase; letter-spacing: 0.1em; font-weight: 600; }
      .quebra-de-pagina::before, .quebra-de-pagina::after { content: ""; flex: 1; border-top: 2px dashed var(--borda-forte); }
      .checklist-instrucao { margin: 10px 0 8px; font-size: 11.5px; }
      .checklist { width: 100%; border-collapse: collapse; font-size: 12.5px; font-variant-numeric: tabular-nums; }
      .checklist th { font-size: 9.5px; text-align: left; text-transform: uppercase; letter-spacing: 0.06em; font-weight: 600; padding: 5px 8px; border-bottom: 1.5px solid var(--tinta); }
      .checklist td { padding: 7px 8px; border-bottom: 1px solid var(--borda); vertical-align: middle; height: 30px; }
      .checklist tbody tr:nth-child(even) td { background: var(--fundo); }
      .checklist .cl-check { width: 30px; text-align: center; }
      .checklist .cl-num { width: 28px; font-size: 10.5px; }
      .checklist .cl-nome { font-weight: 600; }
      .checklist .cl-qtd { width: 120px; text-align: right; white-space: nowrap; }
      .checklist .cl-itens { width: 80px; font-size: 10.5px; white-space: nowrap; }
      .checklist .cl-obs { width: 34%; }
      .check-grande { width: 16px; height: 16px; border-width: 1.5px; }
      .qtd-grande { font-size: 13.5px; }
      .checklist-foot { margin-top: 14px; display: flex; flex-wrap: wrap; align-items: flex-end; gap: 14px; padding-top: 8px; border-top: 1px dashed var(--borda-forte); font-size: 11px; }

      /* Rodapé do pedido ----------------------------------------------- */
      .notes-block { margin-top: 8px; border-left: 3px solid var(--tinta); padding: 2px 0 2px 9px; font-size: 11.5px; white-space: pre-wrap; break-inside: avoid-page; page-break-inside: avoid; }
      .notes-title { font-size: 9.5px; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 1px; }
      .conferencia { margin-top: 16px; display: grid; grid-template-columns: 2fr 1fr 2fr; gap: 16px; break-inside: avoid-page; page-break-inside: avoid; }
      .conferencia .campo { display: flex; flex-direction: column; align-items: stretch; gap: 18px; }
      .conferencia .linha { min-width: 0; }
      .footer-note { margin-top: 10px; padding-top: 6px; border-top: 1px solid var(--borda); font-size: 10px; display: flex; justify-content: space-between; gap: 10px; }
      @media print {
        body { background: var(--papel); }
        .sheet { padding: 0; max-width: none; }
        /* Na impressão a quebra é real; o aviso de "folha seguinte" é só da tela. */
        .separacao-pagina { margin-top: 0; }
        .quebra-de-pagina { display: none; }
      }
    </style>
  </head>
  <body>
    <main class="sheet">
      <header class="header">
        <div class="brand">
          ${logoUrl ? `<img class="brand-logo" src="${escapeHtml(logoUrl)}" alt="Logo da empresa" />` : ""}
          <div>
            <div class="title">Ordem de produção</div>
            <div class="company-name">${safeCompany}</div>
          </div>
        </div>
        <div class="header-right">
          <div class="order-number"><small>PEDIDO</small>#${orderNumber}</div>
          <div class="order-sub">Emitida em ${createdAt}<span class="status-pill">${status}</span></div>
        </div>
      </header>

      <div class="meta-row">
        <span class="meta"><span class="meta-label">Cliente</span><span class="meta-value">${safeClient}</span></span>
        <span class="meta"><span class="meta-label">Entrega</span><span class="meta-value">${deliveryDate}</span></span>
        <span class="meta"><span class="meta-label">Tempo previsto</span><span class="meta-value">${tempoPrevisto}</span></span>
        <span class="meta"><span class="meta-label">Itens</span><span class="meta-value">${items.length}</span></span>
      </div>
      ${quoteTitle ? `<div class="meta-title">${escapeHtml(quoteTitle)}</div>` : ""}

      ${renderItems(items)}

      ${
        notes
          ? `<section class="notes-block"><div class="notes-title">Observações do pedido</div>${escapeHtml(notes)}</section>`
          : ""
      }
      ${
        internalNotes
          ? `<section class="notes-block"><div class="notes-title">Observações internas</div>${escapeHtml(internalNotes)}</section>`
          : ""
      }

      <section class="conferencia">
        <div class="campo"><span class="campo-label">Conferido por</span><span class="linha"></span></div>
        <div class="campo"><span class="campo-label">Data</span><span class="linha"></span></div>
        <div class="campo"><span class="campo-label">Assinatura</span><span class="linha"></span></div>
      </section>

      <footer class="footer-note">
        <span>Documento interno de produção. Não contém valores comerciais.</span>
        <span>Pedido #${orderNumber} · ${safeCompany}</span>
      </footer>

      ${renderChecklistDeSeparacao(separacao, {
        logoUrl,
        empresa: safeCompany,
        numero: orderNumber,
        cliente: safeClient,
        entrega: deliveryDate,
        itens: items.length,
      })}
    </main>
    ${
      autoPrint
        ? `<script>
      window.addEventListener("load", function() {
        window.setTimeout(function() { window.print(); }, 250);
      });
      ${autoClose ? 'window.addEventListener("afterprint", function() { window.close(); });' : ""}
    </script>`
        : ""
    }
  </body>
</html>`;
}

export function renderProductionSheetPrint(
  payload: ProductionSheetPayload,
  printWindow: Window
) {
  const html = buildProductionSheetHtml(payload, { autoPrint: true, autoClose: true });
  printWindow.document.open();
  printWindow.document.write(html);
  printWindow.document.close();
}
