import { readFile } from 'node:fs/promises';
import path from 'node:path';
import puppeteer from 'puppeteer';

export interface CertificateMilestone {
  label: string;
  occurredAt: Date;
  note?: string;
}

export interface CertificateDesignData {
  groomName: string;
  brideName: string;
  completedAt: Date;
  milestones: CertificateMilestone[];
}

const escapeHtml = (value: string) => value.replace(/[&<>"']/g, (character) => ({
  '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;',
}[character]!));

const formatDate = (value: Date) => {
  const parts = new Intl.DateTimeFormat('en-GB', {
    year: 'numeric', month: '2-digit', day: '2-digit', hour: '2-digit', minute: '2-digit',
    hourCycle: 'h23', timeZone: 'Europe/Berlin',
  }).formatToParts(value);
  const part = (type: Intl.DateTimeFormatPartTypes) => parts.find((item) => item.type === type)?.value ?? '';
  return `${part('day')}/${part('month')}/${part('year')} · ${part('hour')}:${part('minute')}`;
};

const certificateHtml = (data: CertificateDesignData, regularFont: string,
  boldFont: string, logo: string) => {
  const milestones = data.milestones.map((milestone, index) => `
    <div class="milestone ${index === data.milestones.length - 1 ? 'last' : ''}">
      <time>${escapeHtml(formatDate(milestone.occurredAt))}</time>
      <span class="track"><i></i></span>
      <div class="milestone-copy"><strong>${escapeHtml(milestone.label)}</strong>
        ${milestone.note ? `<small>${escapeHtml(milestone.note)}</small>` : ''}
      </div>
    </div>`).join('');
  return `<!doctype html><html lang="ar" dir="rtl"><head><meta charset="utf-8">
  <title>شهادة رحلة تعارف - عـلــى طــلــبــك</title><style>
  @font-face{font-family:Amiri;src:url(data:font/ttf;base64,${regularFont}) format('truetype');font-weight:400}
  @font-face{font-family:Amiri;src:url(data:font/ttf;base64,${boldFont}) format('truetype');font-weight:700}
  @page{size:A4;margin:0}*{box-sizing:border-box}html,body{margin:0;width:210mm;height:297mm}
  body{background:#fffdf8;color:#173c39;font-family:Amiri,serif;-webkit-print-color-adjust:exact;print-color-adjust:exact}
  .page{position:relative;width:100%;height:100%;padding:12mm 16mm;overflow:hidden}
  .frame{position:absolute;inset:8mm;border:1.2mm solid #b48632;border-radius:9mm}
  .frame:after{content:"";position:absolute;inset:2.5mm;border:.3mm solid #d9c28e;border-radius:7mm}
  .security-pattern{position:absolute;inset:11mm;z-index:0;width:188mm;height:275mm;opacity:.24}
  .watermark{position:absolute;z-index:0;left:50%;top:55%;width:92mm;height:136mm;object-fit:contain;opacity:.022;transform:translate(-50%,-50%)}
  .corner-ornament{position:absolute;z-index:0;right:8mm;bottom:8mm;width:35mm;height:35mm;border-right:1mm solid #e5d4ac;border-bottom:1mm solid #e5d4ac;border-radius:0 0 9mm 0}
  .corner-ornament:before,.corner-ornament:after{content:"";position:absolute;right:4mm;bottom:4mm;border-right:.35mm solid #c5dcd7;border-bottom:.35mm solid #c5dcd7;border-radius:0 0 6mm 0}
  .corner-ornament:before{width:22mm;height:22mm}.corner-ornament:after{width:12mm;height:12mm;right:8mm;bottom:8mm}
  main{position:relative;z-index:1;text-align:center}.logo{width:33mm;height:33mm;object-fit:contain;margin:1mm auto 0}
  .brand{margin:1mm 0 0;color:#b48632;font-size:24pt;font-weight:700;line-height:1}
  h1{margin:4mm 0 1mm;color:#064f49;font-size:31pt;line-height:1.15}.subtitle{margin:0;color:#657873;font-size:13pt}
  .divider{width:92mm;height:.35mm;margin:4mm auto;background:#d9c28e}
  .names{display:grid;grid-template-columns:1fr 1fr;gap:7mm;margin:7mm 5mm 4mm}
  .name-card{background:#eaf4f1;border:.4mm solid #c9ded9;border-radius:6mm;padding:4mm 6mm;text-align:right;min-height:27mm}
  .name-card span{display:block;color:#657873;font-size:12pt}.name-card strong{display:block;color:#064f49;font-size:20pt;line-height:1.35;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .intro{margin:0 9mm 4mm;font-size:12.5pt;line-height:1.65}.timeline-title{text-align:right;margin:0 5mm 2mm;color:#064f49;font-size:18pt}
  .timeline{margin:0 5mm}.milestone{display:grid;grid-template-columns:48mm 8mm 1fr;direction:ltr;min-height:14mm;align-items:start}
  .milestone time{direction:ltr;text-align:left;color:#657873;font-size:11.5pt;padding-top:1mm;font-family:Amiri,serif}
  .track{position:relative;height:100%}.track:before{content:"";position:absolute;left:50%;top:5mm;bottom:-1mm;width:.4mm;background:#c9d9d5;transform:translateX(-50%)}
  .track i{position:absolute;left:50%;top:2.2mm;width:4mm;height:4mm;border-radius:50%;background:#064f49;transform:translateX(-50%)}
  .last .track:before{display:none}.last .track i{background:#b48632}.milestone-copy{direction:rtl;text-align:right;padding-top:.2mm}
  .milestone-copy strong{display:block;font-size:13pt;line-height:1.35}.milestone-copy small{display:block;color:#b48632;font-size:9.5pt;line-height:1.25}
  .closing{position:absolute;z-index:1;left:22mm;right:22mm;bottom:31mm;background:#f6ead0;border-radius:5mm;padding:4mm 7mm;text-align:center;font-weight:700;font-size:13pt}
  footer{position:absolute;z-index:1;left:20mm;right:20mm;bottom:14mm;text-align:center;color:#657873;font-size:11.5pt;line-height:1.35}
  footer strong{display:block;color:#b48632;font-size:16pt} </style></head><body><div class="page">
  <div class="frame"></div>
  <svg class="security-pattern" viewBox="0 0 188 275" aria-hidden="true">
    <defs><pattern id="certificate-security" width="14" height="14" patternUnits="userSpaceOnUse">
      <path d="M7 2c.5 2.8 1.6 3.9 4.4 4.4-.1.4-.1.8 0 1.2-2.8.5-3.9 1.6-4.4 4.4-.4-.1-.8-.1-1.2 0-.5-2.8-1.6-3.9-4.4-4.4.1-.4.1-.8 0-1.2C4.2 5.9 5.3 4.8 5.8 2c.4.1.8.1 1.2 0Z" fill="#b48632" fill-opacity=".17"/>
      <circle cx="13" cy="1" r=".5" fill="#064f49" fill-opacity=".12"/>
      <circle cx="1" cy="13" r=".5" fill="#064f49" fill-opacity=".12"/>
    </pattern></defs><rect width="188" height="275" rx="8" fill="url(#certificate-security)"/>
  </svg>
  <img class="watermark" src="data:image/svg+xml;base64,${logo}" alt="">
  <div class="corner-ornament"></div><main>
    <img class="logo" src="data:image/svg+xml;base64,${logo}" alt="شعار عـلــى طــلــبــك">
    <div class="brand">عـلــى طــلــبــك</div><h1>شهادة رحلة تعارف</h1>
    <p class="subtitle">احتفاءً بخطوة جادة بُنيت على الوضوح والاحترام والمشاركة العائلية</p><div class="divider"></div>
    <section class="names"><div class="name-card"><span>العريس</span><strong>${escapeHtml(data.groomName)}</strong></div>
      <div class="name-card"><span>العروس</span><strong>${escapeHtml(data.brideName)}</strong></div></section>
    <p class="intro">توثق هذه الشهادة رحلة تعارف اختار طرفاها أن يختماها باتفاق وأمل بخطوة قادمة موفقة.</p>
    <h2 class="timeline-title">محطات الرحلة</h2><section class="timeline">${milestones}</section>
  </main><div class="closing">نسأل الله أن يكتب لكما الخير، وأن يجعل ما هو قادم أجمل وأكثر طمأنينة.</div>
  <footer>مع خالص الأمنيات بالتوفيق<strong>أسرة عـلــى طــلــبــك</strong></footer></div></body></html>`;
};

export async function createCertificatePdf(data: CertificateDesignData): Promise<Buffer> {
  const applicationRoot = process.cwd();
  const [regularFont, boldFont, logo] = await Promise.all([
    readFile(path.join(applicationRoot, 'node_modules', '@expo-google-fonts', 'amiri',
      '400Regular', 'Amiri_400Regular.ttf')),
    readFile(path.join(applicationRoot, 'node_modules', '@expo-google-fonts', 'amiri',
      '700Bold', 'Amiri_700Bold.ttf')),
    readFile(path.join(applicationRoot, 'Logo', 'AlaTalabak_Symbol_Only_CMYK_Package',
      'AlaTalabak_Symbol_Only.svg')),
  ]);
  const executablePath = process.env.PUPPETEER_EXECUTABLE_PATH?.trim();
  const browser = await puppeteer.launch({
    headless: true,
    ...(executablePath ? { executablePath } : {}),
  });
  try {
    const page = await browser.newPage();
    await page.setContent(certificateHtml(data, regularFont.toString('base64'),
      boldFont.toString('base64'), logo.toString('base64')), { waitUntil: 'load' });
    await page.evaluate(() => document.fonts.ready);
    const pdf = await page.pdf({ format: 'A4', printBackground: true, preferCSSPageSize: true });
    return Buffer.from(pdf);
  } finally {
    await browser.close();
  }
}

export const certificateDateText = formatDate;
