/**
 * "Anlage Onboarding-Paket" — a separate A4 PDF that accompanies the LogShip
 * Cloud offer (opt-out checkbox `attachments.onboarding`, default ON, only
 * when `onboarding.enabled`). Rendered from the same software-quote payload as
 * the offer itself (buildSoftwareQuotePayload → payload.onboarding: price,
 * priceIsFrom, travelExcluded, intro, highlights, phases, scope).
 *
 * Content: hero (intro + price badge) → highlights → "Preis & Konditionen"
 * (from-price, what is included, travel + hotel billed on top, not included)
 * → onboarding phases → setup scope (process analysis on site, printers,
 * scanners, devices, channels, carriers, …) → closing.
 */
import { BRAND, buildBrandHeader, buildBrandFooter, getQuoteLogos } from './quotePdf'
import { renderPdfmake } from './agbPdf'

const numberBadge = (n: number) => `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 28 28"><circle cx="14" cy="14" r="13" fill="${BRAND.navy}"/><text x="14" y="19" font-family="Helvetica, Arial, sans-serif" font-size="14" font-weight="bold" fill="#ffffff" text-anchor="middle">${n}</text></svg>`
const CHECK_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="11" fill="#1f7a3d"/><path d="M7 12.5l3 3 7-7" stroke="#ffffff" stroke-width="2.4" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>'
const PLUS_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="11" fill="${BRAND.orange}"/><path d="M12 7v10M7 12h10" stroke="#ffffff" stroke-width="2.4" fill="none" stroke-linecap="round"/></svg>`
const MINUS_SVG = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><circle cx="12" cy="12" r="11" fill="#D5DBE1"/><path d="M7 12h10" stroke="#ffffff" stroke-width="2.6" fill="none" stroke-linecap="round"/></svg>'

export const ONBOARDING_ANNEX_TEXTS: any = {
  de: {
    docTitle: 'Anlage: Onboarding-Paket',
    subtitle: 'zum Angebot LogShip Cloud vom {date}',
    forCompany: 'für {company}',
    page: 'Seite',
    of: 'von',
    hero: 'Lehnen Sie sich zurück. Wir bringen Sie live.',
    badgeLabel: 'Onboarding-Paket',
    priceFrom: 'ab {price}',
    priceOnce: 'einmalig, zzgl. MwSt.',
    included: 'im Angebot enthalten',
    pricingTitle: 'Preis & Konditionen',
    priceRow: 'Onboarding-Paket',
    priceRowNote: 'Festpreis für Analyse, Einrichtung, Datenimport, Schulung und Begleitung bis zum Go-Live.',
    fromNote: 'Der genannte Preis ist ein Ab-Preis: Den endgültigen Festpreis legen wir nach dem Kickoff-Gespräch auf Basis Ihres Setups (Anzahl Standorte, Kanäle, Arbeitsplätze, Geräte) verbindlich fest — vor Beginn der Arbeiten.',
    extraTitle: 'Zusätzlich berechnet werden',
    travelTitle: 'Reise- und Übernachtungskosten',
    extraTravel: 'Reisekosten für Termine vor Ort (An- und Abfahrt mit Pkw nach Kilometerpauschale bzw. Bahn/Flug) nach tatsächlichem Aufwand.',
    extraHotel: 'Übernachtungskosten (Hotel) und Verpflegungspauschale bei mehrtägigen Vor-Ort-Einsätzen, nach tatsächlichem Aufwand gegen Nachweis.',
    extraNote: 'Vor-Ort-Termine stimmen wir vorab mit Ihnen ab; Remote-Termine sind kostenfrei im Paket enthalten.',
    travelIncluded: 'Reise- und Übernachtungskosten für die vereinbarten Vor-Ort-Termine sind im Paketpreis enthalten.',
    notIncludedTitle: 'Nicht enthalten (auf Wunsch gegen Angebot)',
    notIncluded: [
      'Hardware wie Drucker, Scanner, mobile Geräte, Waagen und Netzwerktechnik (wir beraten bei der Auswahl und richten sie ein).',
      'Lizenzen und Gebühren Dritter (Marktplätze, Versanddienstleister, Shopsysteme).',
      'Programmierung individueller Schnittstellen und Sonderentwicklungen.',
      'Bauliche Maßnahmen und Verkabelung (WLAN-Ausbau, Stromversorgung an Packplätzen).'
    ],
    phasesTitle: 'So läuft Ihr Onboarding',
    scopeTitle: 'Was wir für Sie analysieren und einrichten',
    scopeIntro: 'Alle Punkte, die für einen reibungslosen Start konfiguriert und getestet sein müssen — wir übernehmen das für Sie, vor Ort und remote.',
    closingTitle: 'Jedes Onboarding wird individuell auf Ihr Business zugeschnitten.',
    closingText: 'Sagen Sie uns, wo Sie stehen — nach dem Kickoff erhalten Sie den verbindlichen Festpreis und Ihren persönlichen Fahrplan bis zum Go-Live.',
    contact: 'LogYou GmbH · Telefon +49 60 33 / 91 60 57-0 · info@logyou.de'
  },
  en: {
    docTitle: 'Annex: Onboarding package',
    subtitle: 'to the LogShip Cloud offer of {date}',
    forCompany: 'for {company}',
    page: 'Page',
    of: 'of',
    hero: 'Sit back. We take you live.',
    badgeLabel: 'Onboarding package',
    priceFrom: 'from {price}',
    priceOnce: 'one-time, plus VAT',
    included: 'included in this offer',
    pricingTitle: 'Price & conditions',
    priceRow: 'Onboarding package',
    priceRowNote: 'Fixed price for analysis, setup, data import, training and support up to the go-live.',
    fromNote: 'The stated price is a starting price: we fix the final price after the kickoff call based on your setup (number of sites, channels, workstations, devices) — before any work starts.',
    extraTitle: 'Billed in addition',
    travelTitle: 'Travel and accommodation costs',
    extraTravel: 'Travel costs for on-site appointments (car at the mileage rate or train/flight) as incurred.',
    extraHotel: 'Accommodation (hotel) and daily allowance for multi-day on-site assignments, as incurred against receipts.',
    extraNote: 'On-site appointments are agreed with you in advance; remote sessions are included in the package free of charge.',
    travelIncluded: 'Travel and accommodation costs for the agreed on-site appointments are included in the package price.',
    notIncludedTitle: 'Not included (available on request)',
    notIncluded: [
      'Hardware such as printers, scanners, mobile devices, scales and network equipment (we advise on the selection and set it up).',
      'Third-party licences and fees (marketplaces, carriers, shop systems).',
      'Custom interface programming and bespoke development.',
      'Structural work and cabling (Wi-Fi expansion, power supply at packing stations).'
    ],
    phasesTitle: 'How your onboarding works',
    scopeTitle: 'What we analyse and set up for you',
    scopeIntro: 'Everything that has to be configured and tested for a smooth start — we take care of it for you, on site and remotely.',
    closingTitle: 'Every onboarding is tailored to your business.',
    closingText: 'Tell us where you stand — after the kickoff you receive the binding fixed price and your personal roadmap to the go-live.',
    contact: 'LogYou GmbH · Phone +49 60 33 / 91 60 57-0 · info@logyou.de'
  }
}

const fmt = (tpl: string, vars: Record<string, any>) => String(tpl || '').replace(/\{(\w+)\}/g, (_, k) => (vars[k] ?? ''))
const formatDateLocal = (iso: string, language: string): string => {
  const m = /^(\d{4})-(\d{2})-(\d{2})/.exec(String(iso || ''))
  if (!m) return String(iso || '')
  return language === 'en' ? `${m[3]}/${m[2]}/${m[1]}` : `${m[3]}.${m[2]}.${m[1]}`
}
const sanitize = (s: string) => String(s || '').replace(/[^\p{L}\p{N}]+/gu, '-').replace(/^-+|-+$/g, '').slice(0, 40)

export const onboardingAnnexFilename = (company: string, language: string, date?: string): string => {
  const d = /^\d{4}-\d{2}-\d{2}$/.test(String(date || '')) ? String(date) : new Date().toISOString().slice(0, 10)
  const prefix = language === 'en' ? 'Annex_Onboarding-Package' : 'Anlage_Onboarding-Paket'
  return `${prefix}_${sanitize(company) || 'Kunde'}_${d}.pdf`
}

export const buildOnboardingAnnexDocDefinition = (payload: any, logos: { light: string | null; dark: string | null }) => {
  const language = payload?.meta?.language === 'en' ? 'en' : 'de'
  const T = ONBOARDING_ANNEX_TEXTS[language]
  const c = payload?.customer || {}
  const ob = payload?.onboarding || {}
  const dateIso = payload?.meta?.date || new Date().toISOString().slice(0, 10)
  const locale = language === 'en' ? 'en-IE' : 'de-DE'
  const euro = (amount: any) => new Intl.NumberFormat(locale, { style: 'currency', currency: 'EUR' }).format(Number(amount) || 0)
  const price = Number.isFinite(Number(ob.price)) ? Number(ob.price) : 0
  const priceIsFrom = ob.priceIsFrom !== false
  const travelExcluded = ob.travelExcluded !== false
  const priceLabel = price > 0 ? (priceIsFrom ? fmt(T.priceFrom, { price: euro(price) }) : euro(price)) : T.included

  const highlights: any[] = (Array.isArray(ob.highlights) ? ob.highlights : []).filter((h: any) => String(h?.value || '').trim() !== '' || String(h?.label || '').trim() !== '')
  const phases: any[] = (Array.isArray(ob.phases) ? ob.phases : []).filter((p: any) => String(p?.title || '').trim() !== '' || String(p?.text || '').trim() !== '')
  const scope: any[] = (Array.isArray(ob.scope) ? ob.scope : []).filter((p: any) => String(p?.title || '').trim() !== '' || String(p?.text || '').trim() !== '')

  const sectionTitle = (text: string) => ({
    stack: [
      { canvas: [{ type: 'rect', x: 0, y: 0, w: 26, h: 3, color: BRAND.orange }] },
      { text: String(text).toUpperCase(), fontSize: 11, bold: true, color: BRAND.navy, characterSpacing: 0.4, margin: [0, 5, 0, 0] }
    ],
    margin: [0, 16, 0, 8]
  })
  const iconRow = (svg: string, text: any, opts: any = {}) => ({
    columns: [
      { width: 11, svg, margin: [0, 1.5, 0, 0] },
      { width: '*', text, fontSize: 8.5, color: BRAND.text, ...opts }
    ],
    columnGap: 6,
    margin: [0, 0, 0, 4]
  })

  // ---- hero: title line, intro, price badge
  const hero = {
    columns: [
      {
        width: '*',
        stack: [
          { text: T.hero, bold: true, fontSize: 16, color: BRAND.navy, margin: [0, 0, 0, 6] },
          ...(String(c.company || '').trim() ? [{ text: fmt(T.forCompany, { company: c.company }), fontSize: 9, color: BRAND.grayText, margin: [0, 0, 0, 6] }] : []),
          ...(String(ob.intro || '').trim() ? [{ text: String(ob.intro).trim(), fontSize: 9.5, color: BRAND.text }] : [])
        ]
      },
      {
        width: 150,
        margin: [14, 0, 0, 0],
        table: {
          widths: ['*'],
          body: [[{
            fillColor: BRAND.navy,
            margin: [10, 10, 10, 10],
            stack: [
              { text: T.badgeLabel, fontSize: 8, color: BRAND.headerSub, alignment: 'center' },
              { text: priceLabel, bold: true, fontSize: price > 0 ? 17 : 12, color: BRAND.white, alignment: 'center', margin: [0, 3, 0, 2] },
              ...(price > 0 ? [{ text: T.priceOnce, fontSize: 7.5, color: BRAND.headerSub, alignment: 'center' }] : [])
            ]
          }]]
        },
        layout: 'noBorders'
      }
    ],
    margin: [0, 0, 0, 12]
  }

  const highlightsNode = highlights.length
    ? {
        unbreakable: true,
        table: {
          widths: highlights.map(() => '*'),
          body: [highlights.map((h: any) => ({
            fillColor: BRAND.zebra,
            margin: [6, 9, 6, 9],
            stack: [
              { text: String(h.value || ''), bold: true, fontSize: 16, color: BRAND.orange, alignment: 'center' },
              { text: String(h.label || ''), fontSize: 7.5, color: BRAND.grayText, alignment: 'center', margin: [0, 2, 0, 0] }
            ]
          }))]
        },
        layout: { hLineWidth: () => 0, vLineWidth: () => 2, vLineColor: () => BRAND.white, paddingLeft: () => 0, paddingRight: () => 0, paddingTop: () => 0, paddingBottom: () => 0 },
        margin: [0, 0, 0, 4]
      }
    : null

  // ---- price & conditions
  const pricingRows: any[] = [
    [
      { stack: [{ text: T.priceRow, bold: true, fontSize: 9.5, color: BRAND.navy }, { text: T.priceRowNote, fontSize: 7.5, color: BRAND.grayText, margin: [0, 2, 0, 0] }], margin: [8, 6, 8, 6] },
      { text: priceLabel, bold: true, fontSize: 11, color: BRAND.navy, alignment: 'right', margin: [8, 6, 8, 6] }
    ]
  ]
  const pricingNode = {
    stack: [
      sectionTitle(T.pricingTitle),
      {
        table: { widths: ['*', 'auto'], body: pricingRows },
        layout: { hLineWidth: () => 0.75, vLineWidth: () => 0, hLineColor: () => BRAND.grayLine, fillColor: () => BRAND.zebra, paddingLeft: () => 0, paddingRight: () => 0, paddingTop: () => 0, paddingBottom: () => 0 },
        margin: [0, 0, 0, 8]
      },
      ...(price > 0 && priceIsFrom ? [{ text: T.fromNote, fontSize: 8.5, color: BRAND.text, margin: [0, 0, 0, 8] }] : []),
      {
        columns: [
          {
            width: '*',
            stack: [
              { text: travelExcluded ? T.extraTitle : T.travelTitle, bold: true, fontSize: 9.5, color: BRAND.navy, margin: [0, 0, 0, 5] },
              ...(travelExcluded
                ? [iconRow(PLUS_SVG, T.extraTravel), iconRow(PLUS_SVG, T.extraHotel), { text: T.extraNote, fontSize: 7.5, italics: true, color: BRAND.grayText, margin: [0, 2, 0, 0] }]
                : [iconRow(CHECK_SVG, T.travelIncluded)])
            ]
          },
          {
            width: '*',
            stack: [
              { text: T.notIncludedTitle, bold: true, fontSize: 9.5, color: BRAND.navy, margin: [0, 0, 0, 5] },
              ...T.notIncluded.map((t: string) => iconRow(MINUS_SVG, t))
            ]
          }
        ],
        columnGap: 18
      }
    ]
  }

  // ---- phases
  const phasesNode = phases.length
    ? {
        stack: [
          sectionTitle(T.phasesTitle),
          ...phases.map((p: any, i: number) => ({
            unbreakable: true,
            columns: [
              { width: 22, svg: numberBadge(i + 1), margin: [0, 1, 0, 0] },
              {
                width: '*',
                stack: [
                  { text: String(p.title || ''), bold: true, fontSize: 9.5, color: BRAND.navy },
                  ...(String(p.text || '').trim() ? [{ text: String(p.text).trim(), fontSize: 8.5, color: BRAND.text, margin: [0, 1.5, 0, 0] }] : [])
                ]
              }
            ],
            columnGap: 8,
            margin: [0, 0, 0, 7]
          }))
        ]
      }
    : null

  // ---- scope (two-column grid of check items)
  const scopeCell = (p: any) => ({
    columns: [
      { width: 11, svg: CHECK_SVG, margin: [0, 1.5, 0, 0] },
      {
        width: '*',
        stack: [
          { text: String(p.title || ''), bold: true, fontSize: 9, color: BRAND.navy },
          ...(String(p.text || '').trim() ? [{ text: String(p.text).trim(), fontSize: 8, color: BRAND.text, margin: [0, 1.5, 0, 0] }] : [])
        ]
      }
    ],
    columnGap: 6,
    margin: [0, 0, 0, 0]
  })
  const scopeRows: any[][] = []
  for (let i = 0; i < scope.length; i += 2) {
    scopeRows.push([
      { ...scopeCell(scope[i]), margin: [6, 6, 6, 6] },
      scope[i + 1] ? { ...scopeCell(scope[i + 1]), margin: [6, 6, 6, 6] } : { text: '', margin: [6, 6, 6, 6] }
    ])
  }
  const scopeNode = scope.length
    ? {
        stack: [
          sectionTitle(T.scopeTitle),
          { text: T.scopeIntro, fontSize: 8.5, color: BRAND.grayText, margin: [0, 0, 0, 8] },
          {
            table: { widths: ['*', '*'], body: scopeRows, dontBreakRows: true },
            layout: { hLineWidth: () => 0.75, vLineWidth: () => 0, hLineColor: () => BRAND.grayLine, fillColor: (row: number) => (row % 2 === 0 ? BRAND.zebra : null), paddingLeft: () => 0, paddingRight: () => 0, paddingTop: () => 0, paddingBottom: () => 0 }
          }
        ]
      }
    : null

  const closingNode = {
    unbreakable: true,
    columns: [
      { width: 'auto', canvas: [{ type: 'rect', x: 0, y: 2, w: 3, h: 40, color: BRAND.orange }] },
      {
        width: '*',
        stack: [
          { text: T.closingTitle, bold: true, fontSize: 11, color: BRAND.navy },
          { text: T.closingText, fontSize: 9.5, color: BRAND.text, margin: [0, 3, 0, 4] },
          { text: T.contact, fontSize: 8, color: BRAND.grayText }
        ],
        margin: [10, 0, 0, 0]
      }
    ],
    margin: [0, 22, 0, 0]
  }

  return {
    pageSize: 'A4',
    pageMargins: [40, 106, 40, 86],
    info: { title: `${T.docTitle} – ${c.company || ''}`, author: 'LogYou GmbH', subject: T.docTitle },
    header: buildBrandHeader(T.docTitle, `app.logship.de  ·  ${fmt(T.subtitle, { date: formatDateLocal(dateIso, language) })}`, logos.dark),
    footer: buildBrandFooter(T.page, T.of),
    content: [hero, ...(highlightsNode ? [highlightsNode] : []), pricingNode, ...(phasesNode ? [phasesNode] : []), ...(scopeNode ? [scopeNode] : []), closingNode],
    defaultStyle: { font: 'Roboto', fontSize: 9.5, color: BRAND.text, lineHeight: 1.25 }
  }
}

/** The annex as PDF buffer + filename (same payload as the software offer). */
export const generateOnboardingAnnexPdf = async (payload: any): Promise<{ buffer: Buffer; filename: string }> => {
  const logos = await getQuoteLogos()
  const buffer = await renderPdfmake(buildOnboardingAnnexDocDefinition(payload, logos))
  const language = payload?.meta?.language === 'en' ? 'en' : 'de'
  return { buffer, filename: onboardingAnnexFilename(payload?.customer?.company, language, payload?.meta?.date) }
}
