import { PDFDocument, StandardFonts, rgb } from 'pdf-lib'
import fs from 'fs'

async function create() {
  const pdfDoc = await PDFDocument.create()
  const page = pdfDoc.addPage([595.28, 841.89]) // A4
  const helv = await pdfDoc.embedFont(StandardFonts.Helvetica)
  const helvBold = await pdfDoc.embedFont(StandardFonts.HelveticaBold)
  const logoBytes = fs.readFileSync('assets/images/logos/Harheimer TC.png')
  const logoImage = await pdfDoc.embedPng(logoBytes)
  const { width, height } = page.getSize()

  // left column moved further left to align with checkboxes
  const leftX = 48
  const rightX = 320
  // baseY is the vertical anchor for page-1 content. Increase it by ~5.2mm (≈14.739pt)
  const baseY = height - 160 + 14.739
  // shift to apply only to labels and input fields (move those 1cm down)
  const labelsShift = -28.35
  const gap = 36
  const labelWidth = 100
  const fieldXOffset = 100
  // Make fields 10% narrower
  const fieldWidth = Math.round(180 * 0.9)
  // shrink most fields by another 20% on request (applied selectively later)
  const fieldShrinkFactor = 0.8
  const fieldHeight = 14
  // raise date fields by 0.4cm (≈11.34pt) when requested; add extra 1.2mm (≈3.4016pt) per user request
  const dateRaise = 11.34 + 3.4016 // now ≈14.7416pt
  // fixed checkbox positions (do not move with leftX)
  const cbX = 48
  const cbYOffset = 5

  // Header: centered club name and a full-width horizontal bar underneath (~2mm high)
  const headerText = 'Harheimer Tischtennis-Club 1954 e.V.'
  const headerSize = 20
  // draw full-width bar directly under the header; 2mm ≈ 5.67 points
  const barHeight = 5.67
  const drawHeader = (targetPage) => {
    const { width: pageWidth, height: pageHeight } = targetPage.getSize()
    const textWidth = helv.widthOfTextAtSize(headerText, headerSize)
    const headerY = pageHeight - 72
    const logoSize = 52
    const logoY = headerY - 13

    targetPage.drawImage(logoImage, {
      x: leftX,
      y: logoY,
      width: logoSize,
      height: logoSize
    })
    targetPage.drawText(headerText, {
      x: (pageWidth - textWidth) / 2,
      y: headerY,
      size: headerSize,
      font: helv
    })
    targetPage.drawRectangle({
      x: 0,
      y: headerY - 20,
      width: pageWidth,
      height: barHeight,
      color: rgb(0,0,0)
    })

    return headerY
  }
  const headerY = drawHeader(page)

  // Labels and lines
  // Labels left-aligned in their columns
  // Add form title above the fields
  const titleText = 'Beitrittserklärung'
  const titleSize = 14
  const titleWidth = helvBold.widthOfTextAtSize(titleText, titleSize)
  // left-align title above the left labels and move up ~0.7cm (≈20pt)
  const titleX = leftX
  // move title down by 0.5cm (≈14.17pt)
  const titleY = baseY + 24 + 20 - 14.17
  page.drawText(titleText, { x: titleX, y: titleY, size: titleSize, font: helvBold })

  const subtitle = 'Hiermit beantrage ich,'
  const subtitleSize = 12
  const subtitleX = leftX
  const subtitleY = titleY - 18 - 14.17
  page.drawText(subtitle, { x: subtitleX, y: subtitleY, size: subtitleSize, font: helv })
  // apply same vertical shift as fields so labels align
  const fieldsShift = -14.17
  page.drawText('Name:', { x: leftX, y: baseY + fieldsShift + labelsShift, size: 12, font: helv })
  page.drawText('Vorname:', { x: rightX, y: baseY + fieldsShift + labelsShift, size: 12, font: helv })

  page.drawText('Straße:', { x: leftX, y: baseY - gap + fieldsShift + labelsShift, size: 12, font: helv })
  page.drawText('PLZ/Wohnort:', { x: rightX, y: baseY - gap + fieldsShift + labelsShift, size: 12, font: helv })

  page.drawText('Geburtsdatum:', { x: leftX, y: baseY - gap * 2 + fieldsShift + labelsShift, size: 12, font: helv })
  page.drawText('Telefon(privat):', { x: rightX, y: baseY - gap * 2 + fieldsShift + labelsShift, size: 12, font: helv })

  page.drawText('E-Mail:', { x: leftX, y: baseY - gap * 3 + fieldsShift + labelsShift, size: 12, font: helv })
  page.drawText('Telefon(Mobil):', { x: rightX, y: baseY - gap * 3 + fieldsShift + labelsShift, size: 12, font: helv })

  // Create form fields
  const form = pdfDoc.getForm()
  const createUnderlinedTextField = (name, targetPage, options) => {
    const {
      x,
      y,
      width: fieldW,
      height: fieldH,
      font,
      drawUnderline = true,
      lineOffset = 1,
      lineHeight = 0.7
    } = options

    if (drawUnderline) {
      targetPage.drawRectangle({
        x,
        y: y + lineOffset,
        width: fieldW,
        height: lineHeight,
        color: rgb(0, 0, 0)
      })
    }

    return form.createTextField(name).addToPage(targetPage, {
      x,
      y,
      width: fieldW,
      height: fieldH,
      font,
      borderWidth: 0,
      borderColor: undefined,
      backgroundColor: undefined
    })
  }
  // Place fields on the same baseline as their labels
  // We need to move only the input fields on page 1 up by 0.6cm (≈17.01pt) without moving labels.
  const labelToFieldYDelta = 2 // small vertical offset so field baseline matches label visually
  const lift = 0 // original lift value
  // previously raised inputs by 17.01pt (0.6cm); move them down by 5.67pt (0.2cm)
  const inputFieldRaise = 11.34 // net upward offset now ~11.34pt
  createUnderlinedTextField('nachname', page, { x: leftX + fieldXOffset, y: baseY - fieldHeight + labelToFieldYDelta + lift + fieldsShift + labelsShift + inputFieldRaise, width: Math.round(fieldWidth * fieldShrinkFactor), height: fieldHeight, font: helv })
  createUnderlinedTextField('vorname', page, { x: rightX + fieldXOffset, y: baseY - fieldHeight + labelToFieldYDelta + lift + fieldsShift + labelsShift + inputFieldRaise, width: Math.round(fieldWidth * fieldShrinkFactor), height: fieldHeight, font: helv })
  createUnderlinedTextField('strasse', page, { x: leftX + fieldXOffset, y: baseY - gap - fieldHeight + labelToFieldYDelta + lift + fieldsShift + labelsShift + inputFieldRaise, width: Math.round(fieldWidth * fieldShrinkFactor), height: fieldHeight, font: helv })
  createUnderlinedTextField('plz_ort', page, { x: rightX + fieldXOffset, y: baseY - gap - fieldHeight + labelToFieldYDelta + lift + fieldsShift + labelsShift + inputFieldRaise, width: Math.round(fieldWidth * fieldShrinkFactor), height: fieldHeight, font: helv })
  createUnderlinedTextField('geburtsdatum', page, { x: leftX + fieldXOffset, y: baseY - gap * 2 - fieldHeight + labelToFieldYDelta + lift + fieldsShift + labelsShift + inputFieldRaise, width: Math.round(fieldWidth * fieldShrinkFactor), height: fieldHeight, font: helv })
  createUnderlinedTextField('telefon', page, { x: rightX + fieldXOffset, y: baseY - gap * 2 - fieldHeight + labelToFieldYDelta + lift + fieldsShift + labelsShift + inputFieldRaise, width: Math.round(fieldWidth * fieldShrinkFactor), height: fieldHeight, font: helv })
  createUnderlinedTextField('email', page, { x: leftX + fieldXOffset, y: baseY - gap * 3 - fieldHeight + labelToFieldYDelta + lift + fieldsShift + labelsShift + inputFieldRaise, width: Math.round(fieldWidth * fieldShrinkFactor), height: fieldHeight, font: helv })
  createUnderlinedTextField('telefon_mobil', page, { x: rightX + fieldXOffset, y: baseY - gap * 3 - fieldHeight + labelToFieldYDelta + lift + fieldsShift + labelsShift + inputFieldRaise, width: Math.round(fieldWidth * fieldShrinkFactor), height: fieldHeight, font: helv })

  // read membership amounts from config (fall back to defaults)
  let erw = 120, jug = 72, passv = 30
  try {
    const cfg = JSON.parse(fs.readFileSync('server/data/config.json', 'utf8'))
    const ms = cfg.mitgliedschaft || []
    erw = (ms.find(m => /Erwachsene/i.test(m.typ)) || ms.find(m => m.typ === 'Erwachsene') || {}).preis || erw
    jug = (ms.find(m => /Jugend|Kinder/i.test(m.typ)) || ms.find(m => m.typ === 'Kinder/Jugend') || {}).preis || jug
    passv = (ms.find(m => /Passiv/i.test(m.typ)) || {}).preis || passv
  } catch (e) {
    console.error('Could not read config for membership amounts', e)
  }

  const paraLines = [
    'Den derzeitigen jährlichen Mitgliedsbeitrag in Höhe von',
    `€ ${erw},-- (Erwachsene)`,
    `€ ${jug},-- (Jugendliche bis zum vollendeten 18. Lebensjahr)`,
    `€ ${passv},-- (passive Mitglieder)`,
    'bitte ich per Lastschrift jährlich von meinem Konto einzuziehen.',
    'Hierzu erteile ich beigefügtes SEPA-Lastschriftmandat.',
    'Mir ist bekannt, dass die Mitgliedschaft im Harheimer Tischtennis-Club erst nach Bestätigung durch den',
    'Vorstand Wirksamkeit erlangt. Die Beitragspflicht beginnt mit dem darauf folgenden Monat.',
    'Ich erkenne die Vereinssatzung (erhältlich beim Vorstand bzw. auf der Vereinshomepage) an.'
  ]

  // compute intermediate line position and move it down by additional 0.3cm ≈ 8.5pt
  const intermediateY = baseY - gap * 3 + fieldsShift - 6 - 14.17 - 8.5 - 8.5 + labelsShift
  page.drawText('meine Aufnahme in den Harheimer Tischtennis-Club 1954 e.V. als', { x: leftX, y: intermediateY, size: 12, font: helv })

  // membership checkboxes
  // Keep checkbox labels and boxes at fixed left positions, but move them down by 0.8cm ≈ 22.68pt
  const cbLift = -22.68
  page.drawText('aktives Mitglied', { x: cbX + 16, y: baseY - gap * 5 + cbLift + labelsShift, size: 12, font: helv })
  page.drawText('passives Mitglied', { x: cbX + 16, y: baseY - gap * 6 + cbLift + labelsShift, size: 12, font: helv })
  form.createCheckBox('mitglied_aktiv').addToPage(page, { x: cbX, y: baseY - gap * 5 - cbYOffset + cbLift + labelsShift, width: 12, height: 12 })
  form.createCheckBox('mitglied_passiv').addToPage(page, { x: cbX, y: baseY - gap * 6 - cbYOffset + cbLift + labelsShift, width: 12, height: 12 })

  // place the paragraph below the checkboxes with extra spacing before and after the cost lines (~0.3cm)
  try {
  // increase gap around cost lines for better readability (~0.6cm)
  const beforeCostGap = 17
  const afterCostGap = 17
  const paraStartY = baseY - gap * 6 + cbLift - 28 - beforeCostGap
    const lineHeight = 14
    // insert explicit gaps before and after the cost lines (lines 1-3)
    let y = paraStartY
    // first line
    page.drawText(paraLines[0], { x: leftX, y: y, size: 11, font: helv })
    y -= lineHeight
    // gap before costs
    y -= beforeCostGap
    // cost lines (1..3)
    for (let k = 1; k <= 3; k++) {
      page.drawText(paraLines[k], { x: leftX + 6, y: y, size: 11, font: helv })
      y -= lineHeight
    }
    // gap after costs
    y -= afterCostGap
    // remaining lines
    for (let i = 4; i < paraLines.length; i++) {
      page.drawText(paraLines[i], { x: leftX, y: y, size: 11, font: helv })
      y -= lineHeight
    }
    // shift following content down by afterCostGap if needed (none after currently)
  // now add signature/city line 2 cm below the current text
  const twoCm = 56.7
  const signY = y - twoCm
  const sigText = 'Frankfurt/Main-Harheim, den'
  const sigSize = 12
  page.drawText(sigText + ' ', { x: leftX, y: signY, size: sigSize, font: helv })
  const sigStartX = leftX + helv.widthOfTextAtSize(sigText + ' ', sigSize)
  const sigWidth = 220
  // draw thin line for signature
  page.drawRectangle({ x: sigStartX, y: signY - 2, width: sigWidth, height: 1, color: rgb(0,0,0) })
  // draw 'Datum' centered under the signature line
  const datum = 'Datum'
  const datumSize = 11
  const datumX = sigStartX + sigWidth / 2 - helv.widthOfTextAtSize(datum, datumSize) / 2
  page.drawText(datum, { x: datumX, y: signY - 18, size: datumSize, font: helv })
  // create a date form field on page 1 centered under the date line
  const dateFieldWidth = 120
  const dateFieldX = sigStartX + sigWidth / 2 - dateFieldWidth / 2
  // position date field so its bottom edge is exactly on the signature line
  const signatureLineY = signY - 2 // the 1pt-high rectangle was drawn at signY-2
  // raise date fields by 0.4cm (≈11.34pt) upward relative to the line
  const dateRaise = 11.34
  // For page 1 we need to move only the date input up by 5.2mm (≈14.739pt)
  const signDatumExtraRaise = 14.739
  createUnderlinedTextField('sign_datum', page, { x: dateFieldX, y: signatureLineY - fieldHeight + signDatumExtraRaise, width: dateFieldWidth, height: fieldHeight, font: helv, drawUnderline: false })
  // second signature line 3cm below first
  const threeCm = 85.04
  const secondY = signY - threeCm
  const line2Width = 300
  page.drawRectangle({ x: leftX, y: secondY - 2, width: line2Width, height: 1, color: rgb(0,0,0) })
  const label2 = 'Unterschrift (bei Jugendlichen gesetzlicher Vertreter)'
  page.drawText(label2, { x: leftX, y: secondY - 18, size: 11, font: helv })
  } catch (e) {
    // ignore
  }

  // footer: right-aligned 'Seite 1 von 3' 2cm from bottom
  const footerY = 56.7
  const footerText = 'Seite 1 von 3'
  const footerSize = 10
  const footerWidth = helv.widthOfTextAtSize(footerText, footerSize)
  page.drawText(footerText, { x: width - footerWidth - leftX, y: footerY, size: footerSize, font: helv })

  // --- Add a second page with the same header and horizontal bar ---
  const page2 = pdfDoc.addPage([595.28, 841.89])
  const { width: width2, height: height2 } = page2.getSize()
  const headerY2 = drawHeader(page2)

  // --- Page 2: SEPA-Lastschriftmandat text and fields ---
  // move SEPA section slightly up so title sits closer to the header bar
  const sepaYStart = headerY2 - 54
  const sepaLeft = leftX
  // increase line gap for SEPA section (~22pt)
  const lineGap = 22
  let sy = sepaYStart
  const small = 11
  page2.drawText('Erteilung eines SEPA-Lastschriftmandates', { x: sepaLeft, y: sy, size: 12, font: helvBold })
  sy -= lineGap
  // draw these two lines as a tight block (no extra gap)
  page2.drawText('Harheimer Tischtennis-Club 1954 e.V.', { x: sepaLeft, y: sy, size: small, font: helv })
  sy -= 12
  page2.drawText('Unsere Gläubiger-Identifikationsnummer: DE46ZZZ00000745362', { x: sepaLeft, y: sy, size: small, font: helv })
  // add 0.7cm vertical gap (≈19.8pt) before the authorization paragraph
  sy -= 19.8
  // draw the authorization text as wrapped lines within page margins
  const wrapMaxWidth = width2 - sepaLeft - 48
  function drawWrapped(text, x, y, size, font) {
    const words = text.split(' ')
    let line = ''
    let curY = y
    for (const w of words) {
      const test = line ? line + ' ' + w : w
      const testWidth = helv.widthOfTextAtSize(test, size)
      if (testWidth > wrapMaxWidth) {
        page2.drawText(line, { x, y: curY, size, font })
        line = w
        curY -= size + 4
      } else {
        line = test
      }
    }
    if (line) {
      page2.drawText(line, { x, y: curY, size, font })
      curY -= size + 4
    }
    return curY
  }
  sy = drawWrapped('Hiermit ermächtige ich den Harheimer Tischtennis-Club 1954 e.V. die jährlichen Mitgliedsbeiträge von meinem untenstehenden Konto per Lastschrift einzuziehen. Zugleich weise ich mein Kreditinstitut an, die vom Harheimer Tischtennis-Club 1954 e.V. auf mein Konto gezogenen Lastschriften einzulösen.', sepaLeft, sy, small, helv)
  sy -= lineGap * 0.2
  // draw mandate reference and validity with a small gap
  page2.drawText('Mandatsreferenz: HTC0000 _ _ _', { x: sepaLeft, y: sy, size: small, font: helv })
  // add 0.7cm space after Mandatsreferenz as requested
  sy -= 19.8
  page2.drawText('Dieses Mandat gilt für die zugrundeliegende Beitrittserklärung ab sofort.', { x: sepaLeft, y: sy, size: small, font: helv })
  sy -= lineGap * 0.6

  // Draw labeled lines and create text fields for mandate details
  const fieldHeight2 = 14
  const fieldWidth2 = 380
  const labelOffset = 0
  // place SEPA inputs 1cm left (≈28.35pt) from previous and slightly up; adjust to align with labels
    const inputX = sepaLeft + 220 - 28.35
    // reduce vertical raise so inputs sit on same baseline as labels (previously too high)
    const inputYAdjust = 6 + 5.67 // Move SEPA inputs (except date) up by additional 2mm (≈5.67pt)
  // adjust page2DownShift so inputs move up by 0.75mm (net)
  // 0.75mm = 0.075cm -> ~2.12625 pt
  const page2DownShift = 0.075 * 28.35 // 0.075 cm -> ~2.12625 pt

  // apply labelsShift only to the SEPA form labels/inputs so paragraphs remain unaffected
  let syFields = sy + labelsShift
  page2.drawText('Mitglied (Vorname und Name)', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
  createUnderlinedTextField('sepa_mitglied', page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
  syFields -= lineGap * 1.1

  page2.drawText('Kontoinhaber (Vorname und Name):', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
  createUnderlinedTextField('sepa_kontoinhaber', page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
  syFields -= lineGap * 1.1

  page2.drawText('Straße und Hausnummer:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
  createUnderlinedTextField('sepa_strasse', page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
  syFields -= lineGap * 1.1

  page2.drawText('PLZ und Ort:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
  createUnderlinedTextField('sepa_plz_ort', page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
  syFields -= lineGap * 1.1

  page2.drawText('Kreditinstitut:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
  createUnderlinedTextField('sepa_bank', page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
  syFields -= lineGap * 1.1

  page2.drawText('IBAN:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
  createUnderlinedTextField('sepa_iban', page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: Math.round(fieldWidth2 * fieldShrinkFactor), height: fieldHeight2, font: helv })
  syFields -= lineGap * 1.1

  page2.drawText('BIC:', { x: sepaLeft + labelOffset, y: syFields, size: small, font: helv })
  // BIC remains full width as requested
  createUnderlinedTextField('sepa_bic', page2, { x: inputX, y: syFields - fieldHeight2 + 2 + inputYAdjust - page2DownShift, width: 220, height: fieldHeight2, font: helv })
  syFields -= lineGap * 1.1

  // add signature and date lines 2cm below last field
  const twoCm = 56.7
  const signY2 = syFields - twoCm
  // date text and line
  const sigDateText = 'Frankfurt/Main-Harheim, den'
  page2.drawText(sigDateText + ' ', { x: sepaLeft, y: signY2, size: 12, font: helv })
  const sigDateStartX = sepaLeft + helv.widthOfTextAtSize(sigDateText + ' ', 12)
  const sigDateWidth = 160
  page2.drawRectangle({ x: sigDateStartX, y: signY2 - 2, width: sigDateWidth, height: 1, color: rgb(0,0,0) })
  page2.drawText('Datum', { x: sigDateStartX + sigDateWidth / 2 - helv.widthOfTextAtSize('Datum', 11) / 2, y: signY2 - 18, size: 11, font: helv })
  // create a date form field on page 2 centered under the date line
  const sepaDateFieldWidth = 120
  const sepaDateFieldX = sigDateStartX + sigDateWidth / 2 - sepaDateFieldWidth / 2
  // position sepa date field so its bottom edge is on the signature line
  // raise SEPA date field by the same amount so its top/bottom alignment matches requested position
  createUnderlinedTextField('sepa_datum', page2, { x: sepaDateFieldX, y: signY2 - 2 - fieldHeight2 + dateRaise, width: sepaDateFieldWidth, height: fieldHeight2, font: helv, drawUnderline: false })

  // footer on page 2: right-aligned 'Seite 2 von 3' 2cm from bottom
  const footerText2 = 'Seite 2 von 3'
  const footerSize2 = 10
  const footerWidth2 = helv.widthOfTextAtSize(footerText2, footerSize2)
  page2.drawText(footerText2, { x: width2 - footerWidth2 - leftX, y: 56.7, size: footerSize2, font: helv })

  // signature line
  // move signature label/line 2cm (≈56.7pt) further down
  const signLineY = signY2 - 36 - 56.7
  const signLineWidth = 300
  page2.drawRectangle({ x: sepaLeft, y: signLineY - 2, width: signLineWidth, height: 1, color: rgb(0,0,0) })
  page2.drawText('Unterschrift des Kontoinhabers', { x: sepaLeft, y: signLineY - 18, size: 11, font: helv })
  // no form field for signature on page 2 (physical signature)
  page2.drawText('Unterschrift des Kontoinhabers', { x: sepaLeft, y: signLineY - 18, size: 11, font: helv })
  // no form field for signature on page 2 (physical signature)

  // --- Add a third page with same header/bar/footer and title 'Einwilligungserklärung' ---
  const page3 = pdfDoc.addPage([595.28, 841.89])
  const { width: width3, height: height3 } = page3.getSize()
  const headerY3 = drawHeader(page3)

  // title for page 3
  const page3Title = 'Einwilligungserklärung'
  const page3TitleSize = 14
  const page3TitleX = leftX
  const page3TitleY = headerY3 - 48
  page3.drawText(page3Title, { x: page3TitleX, y: page3TitleY, size: page3TitleSize, font: helvBold })

  // footer on page 3
  const footerText3 = 'Seite 3 von 3'
  const footerSize3 = 10
  const footerWidth3 = helv.widthOfTextAtSize(footerText3, footerSize3)
  page3.drawText(footerText3, { x: width3 - footerWidth3 - leftX, y: 56.7, size: footerSize3, font: helv })

  // --- consent paragraphs on page 3 (wrapped) ---
  const consentText = `für die Veröffentlichung von Mitgliederdaten im Internet.

Der Vereinsvorstand weist hiermit darauf hin, dass ausreichende technische Maßnahmen zur Gewährleistung des Datenschutzes getroffen wurden. Dennoch kann bei einer Veröffentlichung von personenbezogenen Mitgliederdaten im Internet ein umfassender Datenschutz nicht garantiert werden.
Daher nimmt das Vereinsmitglied die Risiken für eine eventuelle Persönlichkeitsrechtsverletzung zur
Kenntnis und ist sich bewusst, dass:
• die personenbezogenen Daten auch in Staaten abrufbar sind, die keine der Bundesrepublik Deutschland vergleichbaren Datenschutzbestimmungen kennen,
• die Vertraulichkeit, die Integrität (Unverletzlichkeit), die Authentizität (Echtheit) und die Verfügbarkeit der personenbezogenen Daten nicht garantiert ist.

Das Vereinsmitglied trifft die Entscheidung zur Veröffentlichung seiner Daten im Internet freiwillig und kann seine Einwilligung gegenüber dem Vereinsvorstand jederzeit widerrufen.`

  // helper for wrapped text on page3
  const wrapMaxWidth3 = width3 - leftX - 48
  function drawWrappedOnPage3(text, x, y, size, font) {
    // handle bullet lines: split by newline to preserve existing bullet markers
    const lines = text.split(/\r?\n/)
    let curY = y
    const indent = 14 // indent for text following bullet
    for (const rawLine of lines) {
      const line = rawLine.trim()
      if (!line) { curY -= size + 4; continue }
      if (line.startsWith('•')) {
        // draw bullet circle and then wrap remainder with indentation
        const after = line.replace(/^•\s?/, '')
        // bullet position
        const bx = x + 4
  // place bullet aligned with the first text line (slightly above center)
  const by = curY - size * 0.25
        page3.drawCircle({ x: bx, y: by, size: 1.8, color: rgb(0,0,0) })
        // wrap the 'after' text with indent
        const words = after.replace(/\s+/g, ' ').trim().split(' ')
        let curLine = ''
        for (const w of words) {
          const test = curLine ? curLine + ' ' + w : w
          const testWidth = helv.widthOfTextAtSize(test, size)
          if (testWidth > wrapMaxWidth3 - indent) {
            page3.drawText(curLine, { x: x + indent, y: curY, size, font })
            curLine = w
            curY -= size + 4
          } else {
            curLine = test
          }
        }
        if (curLine) {
          page3.drawText(curLine, { x: x + indent, y: curY, size, font })
          curY -= size + 4
        }
      } else {
        // regular paragraph line: wrap normally
        const words = line.replace(/\s+/g, ' ').trim().split(' ')
        let curLine = ''
        for (const w of words) {
          const test = curLine ? curLine + ' ' + w : w
          const testWidth = helv.widthOfTextAtSize(test, size)
          if (testWidth > wrapMaxWidth3) {
            page3.drawText(curLine, { x, y: curY, size, font })
            curLine = w
            curY -= size + 4
          } else {
            curLine = test
          }
        }
        if (curLine) {
          page3.drawText(curLine, { x, y: curY, size, font })
          curY -= size + 4
        }
      }
    }
    return curY
  }

  // split into paragraphs and draw with 0.5cm (~14.17pt) paragraph spacing
  const paras = consentText.split('\n\n')
  let py = page3TitleY - 28
  const paraSpacing = 14.17
  const paraSize = 11
  for (const p of paras) {
    py = drawWrappedOnPage3(p.trim(), leftX, py, paraSize, helv)
    py -= paraSpacing
  }

  // Additional confirmation block (formatted) with 0.4cm spacing
  const blockSpacing = 11.34 // 0.4 cm
  const boldSize = 12
  const normalSize = 11
  // ensure a bit of space before the block
  py -= blockSpacing
  py = drawWrappedOnPage3('Erklärung:', leftX, py, boldSize, helvBold)
  py -= blockSpacing
  py = drawWrappedOnPage3('Ich bestätige das Vorstehende zur Kenntnis genommen zu haben und willige ein, dass der', leftX, py, normalSize, helv)
  py -= blockSpacing
  py = drawWrappedOnPage3('Harheimer Tischtennis-Club 1954 e.V.', leftX, py, boldSize, helvBold)
  py -= blockSpacing
  py = drawWrappedOnPage3('folgende allgemeine Daten zu meiner Person:', leftX, py, normalSize, helv)
  py -= blockSpacing

  // Rebuild a simple, single-column, non-overlapping form area on page 3
  const formLeft = leftX
  const formFieldW = 360
  const formFieldH = 14
  const formGap = 22
  // start a bit lower to separate from the block text
  py -= 28
  // Row layout
  const colGap = 220
  // Shifts (in points): 1 cm = ~28.35 pt
  const leftColShift = 0.3 * 28.35 // 0.3 cm -> ~8.505 pt
  const vornameLabelShift = 1.0 * 28.35 // 1.0 cm -> ~28.35 pt
  const vornameFieldShift = 1.3 * 28.35 // 1.3 cm -> ~36.855 pt
  const leftColX = formLeft + leftColShift
  const rightColX = formLeft + colGap

  // Row 1: Name (left) and Vorname (right)
  // Keep the left label at the original formLeft, move only the input field slightly right by 0.1cm
  const leftInputShift = 0.35 * 28.35 // 0.35 cm -> ~9.9225 pt
  // extra small horizontal nudge for all non-date inputs: 1mm
  const extraHShift = 0.1 * 28.35 // 0.1 cm (1 mm) -> ~2.835 pt
  // vertical shift for all input fields (including date): 0.6 cm up
  const verticalFieldShift = 0.6 * 28.35 // 0.6 cm -> ~17.01 pt
  // downward nudge for non-date inputs requested now: 0.2 cm -> ~5.67 pt
  const nonDateDownShift = 0.2 * 28.35 // 0.2 cm -> ~5.67 pt
  page3.drawText('Name:', { x: formLeft, y: py, size: normalSize, font: helv })
  createUnderlinedTextField('page3_name', page3, { x: formLeft + 70 + leftInputShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 160, height: formFieldH, font: helv })
  // Vorname label and field moved further right as requested
  page3.drawText('Vorname:', { x: rightColX + vornameLabelShift, y: py, size: normalSize, font: helv })
  createUnderlinedTextField('page3_vorname', page3, { x: rightColX + 70 + vornameFieldShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 160, height: formFieldH, font: helv })
  py -= formGap
  // Anschrift (full width)
  page3.drawText('Anschrift:', { x: formLeft, y: py, size: normalSize, font: helv })
  createUnderlinedTextField('page3_anschrift', page3, { x: formLeft + 70 + leftInputShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: formFieldW + 40, height: formFieldH, font: helv })
  py -= formGap
  // Row 3: Telefonnummer (left) and E-Mail (right)
  // Keep left label at formLeft, shift only the input field by leftInputShift
  page3.drawText('Telefonnummer:', { x: formLeft, y: py, size: normalSize, font: helv })
  createUnderlinedTextField('page3_telefon', page3, { x: formLeft + 70 + leftInputShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 160, height: formFieldH, font: helv })
  page3.drawText('E-Mail-Adresse:', { x: rightColX + vornameLabelShift, y: py, size: normalSize, font: helv })
  createUnderlinedTextField('page3_email', page3, { x: rightColX + 70 + vornameFieldShift + extraHShift, y: py - formFieldH + verticalFieldShift - nonDateDownShift, width: 180, height: formFieldH, font: helv })
  py -= formGap
  // remove fax field/label per request (space preserved)
  py -= formGap
  py -= formGap
  // Date and signature line
  const dateFieldW = 120
  page3.drawText('Frankfurt/Main-Harheim, den', { x: formLeft, y: py, size: normalSize, font: helv })
  const dateX = formLeft + helv.widthOfTextAtSize('Frankfurt/Main-Harheim, den ', normalSize)
  // date field also moves up by verticalFieldShift (but not horizontally shifted by extraHShift)
  // now move the date and signature line 0.2cm down as requested
  const dateFieldY = py - formFieldH + verticalFieldShift - nonDateDownShift
  createUnderlinedTextField('page3_datum', page3, { x: dateX, y: dateFieldY, width: dateFieldW, height: formFieldH, font: helv, drawUnderline: false })
  // signature line starts directly under the (moved) date field
  page3.drawRectangle({ x: dateX, y: dateFieldY - 6, width: 300, height: 1, color: rgb(0,0,0) })
  // label under signature line
  const sigLabel = 'Datum, Unterschrift (bei Jugendlichen gesetzlicher Vertreter)'
  const sigLabelSize = 10
  page3.drawText(sigLabel, { x: dateX, y: dateFieldY - 18, size: sigLabelSize, font: helv })

  // Ensure appearance streams are generated for all form fields using the embedded font
  try {
    form.updateFieldAppearances(helv)
  } catch (e) {
    console.warn('Warning: updateFieldAppearances failed while generating template:', e)
  }

  const pdfBytes = await pdfDoc.save()
  fs.mkdirSync('server/templates', { recursive: true })
  fs.mkdirSync('public/documents', { recursive: true })
  fs.writeFileSync('server/templates/mitgliedschaft-fillable.pdf', pdfBytes)
  fs.writeFileSync('public/documents/beitrittserklärung_template.pdf', pdfBytes)
  console.log('Wrote server/templates/mitgliedschaft-fillable.pdf')
  console.log('Wrote public/documents/beitrittserklärung_template.pdf')
}


create().catch(e => {
  console.error(e)
  process.exit(1)
})
