/**
 * PDF Form Filler - Handles filling PDF form fields
 * Clean Code: Single Responsibility Principle
 */

import { StandardFonts } from 'pdf-lib'
import { mapFieldValue, shouldCheckField, shouldCheckByValue } from './pdf-field-mapper.js'

/**
 * Safely sets text field value if it's empty
 * @param {Object} field - PDF form field
 * @param {string} value - Value to set
 */
export function setTextFieldIfEmpty(field, value) {
  if (typeof field.setText !== 'function') {
    return
  }
  
  try {
    // Check if field already has content
    if (typeof field.getText === 'function') {
      const currentValue = field.getText()
      if (currentValue && String(currentValue).trim() !== '') {
        return // Field already has content, don't overwrite
      }
    }
  } catch (_error) {
    // Ignore getter errors and proceed to set
  }
  
  if (value != null && String(value).trim() !== '') {
    field.setText(value)
  }
}

/**
 * Safely sets checkbox field based on membership type
 * @param {Object} field - PDF form field
 * @param {string} fieldName - Field name
 * @param {Object} data - Form data
 */
export function setCheckboxIfNeeded(field, fieldName, data) {
  if (!(typeof field.check === 'function' || typeof field.isChecked === 'function')) {
    return
  }
  
  const lowerName = fieldName.toLowerCase()
  
  try {
    // Handle membership type checkboxes
    if (lowerName.includes('aktiv') || lowerName.includes('passiv') || lowerName.includes('mitglied')) {
      if (typeof field.isChecked === 'function' && field.isChecked()) {
        return // Already checked
      }
      
      if (shouldCheckField(lowerName, data.mitgliedschaftsart)) {
        field.check && field.check()
      }
      return
    }
    
    // Handle other boolean fields
    const mappedValue = mapFieldValue(data, lowerName)
    if (shouldCheckByValue(mappedValue)) {
      try {
        if (!(typeof field.isChecked === 'function' && field.isChecked())) {
          field.check && field.check()
        }
      } catch (_error) {
        field.check && field.check()
      }
    }
  } catch (_error) {
    // Ignore errors
  }
}

/**
 * Fills all form fields in a PDF document
 * @param {PDFDocument} pdfDoc - PDF document
 * @param {Object} form - PDF form
 * @param {Object} data - Form data
 */
export async function fillFormFields(pdfDoc, form, data) {
  const fields = form.getFields()
  
  for (const field of fields) {
    const fieldName = field.getName()
    const lowerName = fieldName.toLowerCase()
    
    // Handle text fields
    if (typeof field.setText === 'function') {
      const value = mapFieldValue(data, lowerName)
      setTextFieldIfEmpty(field, value)
      continue
    }
    
    // Handle checkbox fields
    if (typeof field.check === 'function' || typeof field.isChecked === 'function') {
      setCheckboxIfNeeded(field, lowerName, data)
      continue
    }
  }
  
  // Update field appearances
  try {
    const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
    form.updateFieldAppearances(helveticaFont)
  } catch (_error) {
    console.warn('Could not update field appearances:', error.message)
  }
}

/**
 * Fills PDF form fields with fallback to positional drawing
 * @param {PDFDocument} pdfDoc - PDF document
 * @param {Object} form - PDF form
 * @param {Object} data - Form data
 */
export async function fillPdfForm(pdfDoc, form, data) {
  try {
    await fillFormFields(pdfDoc, form, data)
    
    // Check if PLZ/Ort field on page 1 is empty and fix it
    await fixPLZOrtField(pdfDoc, data)
  } catch (_error) {
    console.warn('Form filling failed, using fallback:', error.message)
    await fillFormFieldsPositionally(pdfDoc, data)
  }
}

/**
 * Fixes the PLZ/Ort field on page 1 if it's empty
 * @param {PDFDocument} pdfDoc - PDF document
 * @param {Object} data - Form data
 */
async function fixPLZOrtField(pdfDoc, data) {
  try {
    const pages = pdfDoc.getPages()
    await pdfDoc.embedFont(StandardFonts.Helvetica)
    
    // Draw PLZ/Ort at the correct position on page 1
    const plzOrtText = `${data.plz || ''} ${data.ort || ''}`.trim()
    
    // Instead of drawing rectangles, let's find and fix the actual form field
    const form = pdfDoc.getForm()
    const fields = form.getFields()
    
    // Look for PLZ/Ort related fields and fix them
    for (const field of fields) {
      const fieldName = field.getName().toLowerCase()
      if (fieldName.includes('plz') && fieldName.includes('ort')) {
        if (typeof field.setText === 'function') {
          field.setText(plzOrtText)
        }
      } else if (fieldName.includes('plz') && !fieldName.includes('vorname') && !fieldName.includes('nachname')) {
        if (typeof field.setText === 'function') {
          field.setText(plzOrtText)
        }
      }
    }
    
  } catch (_error) {
    console.warn('Could not fix PLZ/Ort field:', error.message)
  }
}

/**
 * Fallback: Fill form fields by drawing text at specific positions
 * @param {PDFDocument} pdfDoc - PDF document
 * @param {Object} data - Form data
 */
async function fillFormFieldsPositionally(pdfDoc, data) {
  try {
    const pages = pdfDoc.getPages()
    const helveticaFont = await pdfDoc.embedFont(StandardFonts.Helvetica)
    
    // First page coordinates
    const firstPage = pages[0]
    const coords = {
      nachname: { x: 156, y: 160 },
      vorname: { x: 470, y: 160 },
      strasse: { x: 156, y: 132 },
      plz_ort: { x: 470, y: 132 },
      geburtsdatum: { x: 156, y: 104 },
      telefon: { x: 470, y: 104 },
      email: { x: 156, y: 76 },
      telefon_mobil: { x: 470, y: 76 }
    }
    
    // Fill first page fields
    firstPage.drawText(data.nachname || '', { x: coords.nachname.x, y: coords.nachname.y, size: 11, font: helveticaFont })
    firstPage.drawText(data.vorname || '', { x: coords.vorname.x, y: coords.vorname.y, size: 11, font: helveticaFont })
    firstPage.drawText(data.strasse || '', { x: coords.strasse.x, y: coords.strasse.y, size: 11, font: helveticaFont })
    firstPage.drawText(`${data.plz || ''} ${data.ort || ''}`.trim(), { x: coords.plz_ort.x, y: coords.plz_ort.y, size: 11, font: helveticaFont })
    firstPage.drawText(new Date(data.geburtsdatum).toLocaleDateString('de-DE') || '', { x: coords.geburtsdatum.x, y: coords.geburtsdatum.y, size: 11, font: helveticaFont })
    firstPage.drawText(data.telefon_privat || data.telefon_mobil || '', { x: coords.telefon.x, y: coords.telefon.y, size: 11, font: helveticaFont })
    firstPage.drawText(data.email || '', { x: coords.email.x, y: coords.email.y, size: 11, font: helveticaFont })
    firstPage.drawText(data.telefon_mobil || '', { x: coords.telefon_mobil.x, y: coords.telefon_mobil.y, size: 11, font: helveticaFont })
    
    // Bank data on second page
    const secondPage = pages[1]
    if (secondPage) {
      const bankCoords = {
        kontoinhaber: { x: 156, y: 400 },
        iban: { x: 156, y: 370 },
        bic: { x: 156, y: 340 },
        bank: { x: 156, y: 310 }
      }
      
      secondPage.drawText(data.kontoinhaber || '', { x: bankCoords.kontoinhaber.x, y: bankCoords.kontoinhaber.y, size: 11, font: helveticaFont })
      secondPage.drawText(data.iban || '', { x: bankCoords.iban.x, y: bankCoords.iban.y, size: 11, font: helveticaFont })
      secondPage.drawText(data.bic || '', { x: bankCoords.bic.x, y: bankCoords.bic.y, size: 11, font: helveticaFont })
      secondPage.drawText(data.bank || '', { x: bankCoords.bank.x, y: bankCoords.bank.y, size: 11, font: helveticaFont })
    }
    
    // Membership checkbox
    if (data.mitgliedschaftsart === 'aktiv') {
      firstPage.drawText('X', { x: 116, y: 20, size: 12, font: helveticaFont })
    } else if (data.mitgliedschaftsart === 'passiv') {
      firstPage.drawText('X', { x: 116, y: -8, size: 12, font: helveticaFont })
    }
    
  } catch (_error) {
    console.error('Positional filling failed:', error.message)
  }
}
