<?php
// ---------------------------------------------------------------------
// Fills the REAL official government PDF templates (W-4, DE4, I-9, WOTC)
// server-side, using pdftk — verified working against the actual uploaded
// templates (see project notes). This replaces the old client-side
// pdf-lib filling (fillOfficialPdf() in the old Index.html) with an
// equivalent server-side version using the exact same AcroForm field
// names, so the resulting PDFs are identical in structure to what the
// Apps Script version produced.
//
// REQUIRES: pdftk installed on the server (`apt install pdftk` on
// Debian/Ubuntu, or pdftk-java). This is a system dependency, not a
// Composer package — check `which pdftk` on your host before deploying.
// ---------------------------------------------------------------------

function pdf_escape_fdf(string $v): string {
    // Escape parentheses/backslashes for FDF literal strings.
    return str_replace(['\\', '(', ')'], ['\\\\', '\\(', '\\)'], $v);
}

// $fields: [ 'Exact PDF Field Name' => 'value', ... ]
// $templatePath: path to the blank official PDF (fw4.pdf / de4.pdf / i-9.pdf / 8850_WOTC_Form_2.pdf)
// $outPath: where to write the filled, flattened PDF
function fill_pdf_template(string $templatePath, array $fields, string $outPath): bool {
    if (!is_file($templatePath)) {
        error_log("PDF template missing: $templatePath");
        return false;
    }
    $fdf = "%FDF-1.2\n1 0 obj<</FDF<</Fields[\n";
    foreach ($fields as $name => $value) {
        if ($value === null || $value === '') continue;
        $fdf .= '<</T(' . pdf_escape_fdf($name) . ')/V(' . pdf_escape_fdf((string)$value) . ")>>\n";
    }
    $fdf .= "]>>>>\nendobj\ntrailer<</Root 1 0 R>>\n%%EOF";

    $tmpFdf = tempnam(sys_get_temp_dir(), 'fdf_') . '.fdf';
    file_put_contents($tmpFdf, $fdf);

    $cmd = sprintf(
        'pdftk %s fill_form %s output %s flatten 2>&1',
        escapeshellarg($templatePath),
        escapeshellarg($tmpFdf),
        escapeshellarg($outPath)
    );
    exec($cmd, $out, $exitCode);
    unlink($tmpFdf);

    if ($exitCode !== 0) {
        error_log('pdftk fill failed: ' . implode("\n", $out));
        return false;
    }
    return is_file($outPath);
}

// Checkbox/radio fields use pdftk's on-state name (usually "Yes" or "1" —
// verify per-template with `pdftk template.pdf dump_data_fields` if a
// checkbox doesn't check correctly; DE4/W-4 checkboxes below use the
// on-states confirmed against the real templates).
function fill_pdf_checkbox(array &$fields, string $name, bool $checked, string $onState = 'Yes'): void {
    if ($checked) $fields[$name] = $onState;
}

// ---------------------------------------------------------------------
// Builds the field map for each of the 4 templates from the employee +
// Phase A fields + I-9 §2 data — same source data, same field names, as
// the original JS fillOfficialPdf().
// ---------------------------------------------------------------------

function build_w4_fields(array $h, array $f): array {
    $full = trim(($h['first'] ?? '') . ' ' . ($h['last'] ?? ''));
    $csz = onb_city_state_zip($h);
    $fields = [
        'topmostSubform[0].Page1[0].Step1a[0].f1_01[0]' => $f['w4_first'] ?? $h['first'] ?? '',
        'topmostSubform[0].Page1[0].Step1a[0].f1_02[0]' => $f['w4_last'] ?? $h['last'] ?? '',
        'topmostSubform[0].Page1[0].Step1a[0].f1_03[0]' => $f['w4_address'] ?? $h['address'] ?? '',
        'topmostSubform[0].Page1[0].Step1a[0].f1_04[0]' => $f['w4_csz'] ?? $csz,
        'topmostSubform[0].Page1[0].f1_05[0]'           => $f['w4_ssn'] ?? '',
        'topmostSubform[0].Page1[0].Step3_ReadOrder[0].f1_06[0]' => $f['w4_children'] ?? '',
        'topmostSubform[0].Page1[0].Step3_ReadOrder[0].f1_07[0]' => $f['w4_other'] ?? '',
        'topmostSubform[0].Page1[0].f1_08[0]' => $f['w4_dep_total'] ?? '',
        'topmostSubform[0].Page1[0].f1_09[0]' => $f['w4_4a'] ?? '',
        'topmostSubform[0].Page1[0].f1_10[0]' => $f['w4_4b'] ?? '',
        'topmostSubform[0].Page1[0].f1_11[0]' => $f['w4_4c'] ?? '',
    ];
    // Filing status is 3 mutually exclusive checkboxes (c1_1[0..2]).
    $filing = $f['w4_filing'] ?? '';
    if ($filing === 'single')  $fields['topmostSubform[0].Page1[0].c1_1[0]'] = '1';
    if ($filing === 'married') $fields['topmostSubform[0].Page1[0].c1_1[1]'] = '1';
    if ($filing === 'hoh')     $fields['topmostSubform[0].Page1[0].c1_1[2]'] = '1';
    return $fields;
}

function build_de4_fields(array $h, array $f, array $section2): array {
    $full = trim(($h['first'] ?? '') . ' ' . ($h['last'] ?? ''));
    $fields = [
        'Name 1' => $f['de4_name'] ?? $full,
        'Social Security Number 1' => $f['de4_ssn'] ?? '',
        'Address 1' => $f['de4_address'] ?? $h['address'] ?? '',
        'City' => $f['de4_city'] ?? $h['city'] ?? '',
        'State' => $f['de4_state'] ?? $h['state'] ?? '',
        'ZIP Code' => $f['de4_zip'] ?? $h['zip'] ?? '',
        '1a' => $f['de4_1a'] ?? '',
        '1b' => $f['de4_1b'] ?? '',
        '1c' => $f['de4_1c'] ?? '',
        '2' => $f['de4_2'] ?? '',
        "Employer's Name and Address" => $section2['employer_name_address'] ?? '',
        'California Employer Payroll Tax Account Number' => $section2['ca_payroll_acct'] ?? '',
    ];
    $filing = $f['de4_filing'] ?? '';
    if ($filing === 'single_two')  $fields['Filing Status 1'] = '1';
    if ($filing === 'married_one') $fields['Filing Status 2'] = '1';
    if ($filing === 'hoh')         $fields['Filing Status 3'] = '1';
    if (!empty($f['de4_exempt3'])) $fields['WHexempt'] = '1';
    if (!empty($f['de4_exempt4'])) $fields['notsubj2WH'] = '1';
    return $fields;
}

// I-9 field names — VERIFIED against the actual uploaded i-9.pdf via a
// real field dump (128 AcroForm fields). These match the original JS
// pdfSetText() calls exactly, confirming the same template/edition.
function build_i9_fields(array $h, array $f, array $section2): array {
    $fields = [
        'Last Name (Family Name)' => $f['last_name_family_name'] ?? $h['last'] ?? '',
        'First Name Given Name' => $f['first_name_given_name'] ?? $h['first'] ?? '',
        'Employee Middle Initial (if any)' => $f['middle_initial_if_any'] ?? '',
        'Employee Other Last Names Used (if any)' => $f['other_last_names_used_if_any'] ?? '',
        'Address Street Number and Name' => $f['address_street_number_and_name'] ?? $h['address'] ?? '',
        'Apt Number (if any)' => $f['apt_number_if_any'] ?? '',
        'City or Town' => $f['city_or_town'] ?? $h['city'] ?? '',
        'State' => $f['state'] ?? $h['state'] ?? '',
        'ZIP Code' => $f['zip_code'] ?? $h['zip'] ?? '',
        'Date of Birth mmddyyyy' => $f['date_of_birth_mm_dd_yyyy'] ?? '',
        'US Social Security Number' => $f['u_s_social_security_number'] ?? '',
        'Employees E-mail Address' => $f['email_address'] ?? $h['email'] ?? '',
        'Telephone Number' => $f['phone_number'] ?? $h['phone'] ?? '',
        // Section 2 (Rachel) — verified field names:
        'Document Title 1' => $section2['listA_title'] ?? '',
        'Issuing Authority 1' => $section2['listA_auth'] ?? '',
        'Document Number 0 (if any)' => $section2['listA_num'] ?? '',
        'Expiration Date if any' => $section2['listA_exp'] ?? '',
        'List B Document 1 Title' => $section2['listB_title'] ?? '',
        'List B Issuing Authority 1' => $section2['listB_auth'] ?? '',
        'List B Document Number 1' => $section2['listB_num'] ?? '',
        'List B Expiration Date 1' => $section2['listB_exp'] ?? '',
        'List C Document Title 1' => $section2['listC_title'] ?? '',
        'List C Issuing Authority 1' => $section2['listC_auth'] ?? '',
        'List C Document Number 1' => $section2['listC_num'] ?? '',
        'List C Expiration Date 1' => $section2['listC_exp'] ?? '',
        'Additional Information' => $section2['additional_info'] ?? '',
        'FirstDayEmployed mmddyyyy' => !empty($h['hire_date']) ? onb_fmt_mdy($h['hire_date']) : '',
        'Last Name First Name and Title of Employer or Authorized Representative' => $section2['employer_rep'] ?? '',
        'Employers Business or Org Name' => $section2['employer_business_name'] ?? '',
        'Employers Business or Org Address' => $section2['employer_address'] ?? '',
        'USCIS ANumber' => $f['uscis_a_number_if_applicable'] ?? '',
        'Form I94 Admission Number' => $f['form_i_94_admission_number_if_applicable'] ?? '',
        'Foreign Passport Number and Country of IssuanceRow1' => trim(($f['foreign_passport_number_if_applicable'] ?? '') . ' ' . ($f['country_of_issuance_if_passport_used'] ?? '')),
        '3 A lawful permanent resident Enter USCIS or ANumber' => ($f['i9cit'] ?? '') === 'lpr' ? ($f['uscis_a_number_if_applicable'] ?? '') : '',
    ];
    // NOTE: The citizenship attestation (boxes 1-4) is NOT an AcroForm
    // checkbox in this template — like the original JS version, it must
    // be drawn as an "X" at a fixed coordinate. pdftk can't do coordinate
    // drawing; that one element needs the FPDI overlay step in
    // overlay_i9_citizenship_mark() below, run on the pdftk output.
    return $fields;
}

// Draws the citizenship "X" mark at the same coordinates the original JS
// pdfMark() used (page 1, x=184, y depends on which of the 4 boxes).
// Requires: composer require setasign/fpdi setasign/fpdi-fpdf
// If FPDI isn't installed, this is skipped gracefully — the PDF still
// has all text fields filled and Section 2 completed; only the small
// citizenship checkbox mark is missing until FPDI is added.
function overlay_i9_citizenship_mark(string $pdfPath, string $cit): void {
    if (!class_exists('setasign\Fpdi\Fpdi')) return; // composer package not installed — skip safely
    $yMap = ['us' => 525, 'natl' => 513, 'lpr' => 501, 'alien' => 489];
    if (!isset($yMap[$cit])) return;
    $pdf = new \setasign\Fpdi\Fpdi();
    $pageCount = $pdf->setSourceFile($pdfPath);
    for ($i = 1; $i <= $pageCount; $i++) {
        $tpl = $pdf->importPage($i);
        $size = $pdf->getTemplateSize($tpl);
        $pdf->AddPage($size['orientation'], [$size['width'], $size['height']]);
        $pdf->useTemplate($tpl);
        if ($i === 1) {
            $pdf->SetFont('Helvetica', '', 9);
            $pdf->SetXY(184 / 2.83465, ($size['height'] - $yMap[$cit] / 2.83465)); // pt -> mm
            $pdf->Cell(10, 5, 'X');
        }
    }
    $pdf->Output($pdfPath, 'F');
}

// WOTC (Form 8850): the uploaded 8850_WOTC_Form_2.pdf template has only
// 2 real AcroForm fields (verified via field dump: "Text40", "Text41").
// Based on field width/position (Text40 is the wider box, matching a
// name; Text41 the narrower box, matching an SSN), they map to name/SSN
// respectively — BUT WITH LESS CERTAINTY than the W-4/DE4/I-9 mappings
// above, since this template has no descriptive field labels to confirm
// against. Fill one test employee and visually check the output PDF
// before relying on this in production; swap the two keys below if the
// values land in the wrong boxes.
function build_wotc_fields(array $h, array $f): array {
    return [
        'Text40' => trim(($h['first'] ?? '') . ' ' . ($h['last'] ?? '')), // name (wider field)
        'Text41' => $f['wotc_ssn'] ?? '',                                  // SSN (narrower field)
    ];
}

// onb_fmt_mdy() is defined in Support.php (already required by callers).
