export type PdvReceiptItem = {
  title: string;
  quantity: number;
  unit_price: number;
  line_total: number;
  sku?: string | null;
  barcode?: string | null;
  note?: string | null;
};

export type PdvReceiptPayment = {
  method: string;
  amount: number;
};

export type PdvReceiptPayload = {
  company: {
    name: string;
    logo_url?: string | null;
    cnpj?: string | null;
    phone?: string | null;
    whatsapp?: string | null;
    address?: string | null;
  };
  order: {
    id: string;
    number?: number | null;
    created_at: string;
  };
  client: {
    name: string;
  };
  items: PdvReceiptItem[];
  payments: PdvReceiptPayment[];
  totals: {
    subtotal: number;
    discount: number;
    total: number;
    paid_total: number;
    change: number;
  };
};

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

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

function formatMoney(value: number) {
  return new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(Number(value || 0));
}

function formatDateTime(value: string) {
  const date = new Date(value);
  if (!Number.isFinite(date.getTime())) return "-";
  return date.toLocaleString("pt-BR");
}

function methodLabel(value: string) {
  const normalized = String(value || "").toLowerCase();
  if (normalized === "pix") return "PIX";
  if (normalized === "cash") return "DINHEIRO";
  if (normalized === "credit_card") return "CARTAO CREDITO";
  if (normalized === "debit_card") return "CARTAO DEBITO";
  if (normalized === "transfer") return "TRANSFERENCIA";
  if (normalized === "card") return "CARTAO";
  return normalized.toUpperCase() || "PAGAMENTO";
}

function padRight(value: string, size: number) {
  if (value.length >= size) return value.slice(0, size);
  return value + " ".repeat(size - value.length);
}

function padLeft(value: string, size: number) {
  if (value.length >= size) return value.slice(value.length - size);
  return " ".repeat(size - value.length) + value;
}

function safeFilenamePart(value: string) {
  return value
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .replace(/[^a-zA-Z0-9_-]+/g, "-")
    .replace(/^-+|-+$/g, "")
    .toLowerCase();
}

export function buildPdvReceiptHtml(payload: PdvReceiptPayload, options: ReceiptHtmlOptions = {}) {
  const autoPrint = options.autoPrint ?? false;
  const autoClose = options.autoClose ?? false;
  const receiptNumber = payload.order.number ? String(payload.order.number) : payload.order.id.slice(0, 8).toUpperCase();
  const lines = payload.items
    .map((item) => {
      const qty = String(Number(item.quantity || 0));
      const unit = formatMoney(item.unit_price);
      const total = formatMoney(item.line_total);
      const title = escapeHtml(item.title || "Item");
      const skuText = item.sku ? `SKU: ${escapeHtml(item.sku)}` : "";
      const barcodeText = item.barcode ? `CÓD: ${escapeHtml(item.barcode)}` : "";
      const identifiers = [skuText, barcodeText].filter(Boolean).join(" ");
      const identifierHtml = identifiers ? `<div class="line-item-note" style="color:#666;font-size:9px;">${identifiers}</div>` : "";
      const detail = `${padRight(qty, 4)} x ${padRight(unit, 14)} ${padLeft(total, 14)}`;
      const note = item.note?.trim() ? `<div class="line-item-note">${escapeHtml(item.note.trim())}</div>` : "";
      return `<div class="line-item"><div class="line-item-title">${title}</div>${identifierHtml}<div class="line-item-detail">${escapeHtml(detail)}</div>${note}</div>`;
    })
    .join("");

  const paymentLines = payload.payments
    .map((payment) => {
      const method = methodLabel(payment.method);
      return `<div class="row"><span>${escapeHtml(method)}</span><span>${escapeHtml(formatMoney(payment.amount))}</span></div>`;
    })
    .join("");

  const logoHtml = payload.company.logo_url
    ? `<div class="logo-wrap"><img src="${escapeHtml(payload.company.logo_url)}" alt="Logo" class="logo" /></div>`
    : "";

  return `<!doctype html>
<html lang="pt-BR">
<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1" />
  <title>Cupom Não Fiscal #${escapeHtml(receiptNumber)}</title>
  <style>
    :root { color-scheme: light only; }
    * { box-sizing: border-box; }
    body {
      margin: 0;
      background: #fff;
      color: #000;
      font-family: "Courier New", Courier, monospace;
    }
    .receipt {
      width: 80mm;
      margin: 0 auto;
      padding: 3mm;
      color: #000;
    }
    .center { text-align: center; }
    .company { font-weight: 700; font-size: 14px; letter-spacing: 0.2px; margin-top: 2px; }
    .meta { font-size: 11px; line-height: 1.35; margin-top: 3px; }
    .divider { border-top: 1px dashed #000; margin: 6px 0; }
    .line-item { margin-bottom: 5px; }
    .line-item-title { font-size: 12px; font-weight: 700; line-height: 1.3; word-break: break-word; }
    .line-item-detail { font-size: 11px; white-space: pre; margin-top: 1px; }
    .line-item-note { font-size: 10px; margin-top: 1px; line-height: 1.2; }
    .row { display: flex; justify-content: space-between; align-items: flex-start; gap: 8px; font-size: 11px; line-height: 1.3; }
    .row strong { font-size: 12px; }
    .logo-wrap { display: flex; justify-content: center; margin-bottom: 4px; }
    .logo { max-width: 42mm; max-height: 18mm; object-fit: contain; filter: grayscale(1) contrast(1.7); }
    .footer { font-size: 10px; line-height: 1.4; text-align: center; margin-top: 6px; }
    @media print {
      html, body { width: 80mm; background: #fff; }
      .receipt { width: 80mm; margin: 0; padding: 2mm; }
      @page { size: 80mm auto; margin: 0; }
    }
  </style>
</head>
<body>
  <main class="receipt">
    ${logoHtml}
    <div class="center company">${escapeHtml(payload.company.name || "LOJA")}</div>
    <div class="center meta">
      ${payload.company.cnpj ? `CNPJ: ${escapeHtml(payload.company.cnpj)}<br/>` : ""}
      ${payload.company.phone ? `Fone: ${escapeHtml(payload.company.phone)}<br/>` : ""}
      ${payload.company.whatsapp ? `WhatsApp: ${escapeHtml(payload.company.whatsapp)}<br/>` : ""}
      ${payload.company.address ? `${escapeHtml(payload.company.address)}<br/>` : ""}
      CUPOM NAO FISCAL
    </div>
    <div class="divider"></div>
    <div class="row"><span>CUPOM</span><span>#${escapeHtml(receiptNumber)}</span></div>
    <div class="row"><span>DATA</span><span>${escapeHtml(formatDateTime(payload.order.created_at))}</span></div>
    <div class="row"><span>CLIENTE</span><span>${escapeHtml(payload.client.name || "Consumidor")}</span></div>
    <div class="divider"></div>
    ${lines || '<div class="line-item"><div class="line-item-title">SEM ITENS</div></div>'}
    <div class="divider"></div>
    <div class="row"><span>Subtotal</span><span>${escapeHtml(formatMoney(payload.totals.subtotal))}</span></div>
    <div class="row"><span>Desconto</span><span>${escapeHtml(formatMoney(payload.totals.discount))}</span></div>
    <div class="row"><strong>Total</strong><strong>${escapeHtml(formatMoney(payload.totals.total))}</strong></div>
    <div class="divider"></div>
    ${paymentLines || '<div class="row"><span>Pagamento</span><span>-</span></div>'}
    <div class="row"><span>Pago</span><span>${escapeHtml(formatMoney(payload.totals.paid_total))}</span></div>
    <div class="row"><span>Troco</span><span>${escapeHtml(formatMoney(payload.totals.change))}</span></div>
    <div class="divider"></div>
    <div class="footer">
      Obrigado pela preferencia<br/>
      Documento sem valor fiscal
    </div>
  </main>
  ${
    autoPrint
      ? `<script>
          window.addEventListener("load", () => {
            setTimeout(() => {
              window.focus();
              window.print();
              ${autoClose ? "setTimeout(() => window.close(), 180);" : ""}
            }, 120);
          });
        </script>`
      : ""
  }
</body>
</html>`;
}

export function printPdvReceipt(payload: PdvReceiptPayload) {
  const iframe = document.createElement("iframe");
  iframe.setAttribute("aria-hidden", "true");
  iframe.style.position = "fixed";
  iframe.style.right = "0";
  iframe.style.bottom = "0";
  iframe.style.width = "0";
  iframe.style.height = "0";
  iframe.style.border = "0";
  iframe.style.opacity = "0";
  iframe.style.pointerEvents = "none";

  const cleanup = () => {
    iframe.onload = null;
    if (iframe.parentNode) iframe.parentNode.removeChild(iframe);
  };

  iframe.onload = () => {
    const frameWindow = iframe.contentWindow;
    if (!frameWindow) {
      cleanup();
      return;
    }
    const onAfterPrint = () => {
      frameWindow.removeEventListener("afterprint", onAfterPrint);
      cleanup();
    };
    frameWindow.addEventListener("afterprint", onAfterPrint);
    window.setTimeout(() => {
      frameWindow.focus();
      frameWindow.print();
    }, 120);
    window.setTimeout(cleanup, 15000);
  };

  iframe.srcdoc = buildPdvReceiptHtml(payload, { autoPrint: false, autoClose: false });
  document.body.appendChild(iframe);
}

export function downloadPdvReceiptHtml(payload: PdvReceiptPayload) {
  const filenameBase = payload.order.number ? `cupom-nao-fiscal-${payload.order.number}` : `cupom-nao-fiscal-${payload.order.id}`;
  const filename = `${safeFilenamePart(filenameBase)}.html`;
  const html = buildPdvReceiptHtml(payload, { autoPrint: false, autoClose: false });
  const blob = new Blob([html], { type: "text/html;charset=utf-8" });
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement("a");
  anchor.href = url;
  anchor.download = filename;
  document.body.appendChild(anchor);
  anchor.click();
  anchor.remove();
  window.setTimeout(() => URL.revokeObjectURL(url), 1000);
}
