<?php
// =====================================================================
// auto_nid.php — Auto NID Card generator (User panel integrated)
// Admin controlled: price + service-only notice (nid/admin/auto_nid.php)
// Requirement: hosting-এ `pdftotext` (poppler-utils) ইনস্টল থাকতে হবে।
// =====================================================================

require_once __DIR__.'/../config/config.php';
require_user();
$U = current_user();

$AUTO_PRICE  = (float)setting($pdo, 'auto_nid_price', 0);
$AUTO_NOTICE = trim((string)setting($pdo, 'auto_nid_notice', ''));

// Ensure hidden service row exists so we can attach orders / count usage.
$AUTO_SVC_ID = 0;
try {
    $__svc = $pdo->query("SELECT id FROM services WHERE name='অটো NID মেক' LIMIT 1")->fetch();
    if (!$__svc) {
        $pdo->prepare("INSERT INTO services(name,description,kind,price,active,status,position)
                       VALUES('অটো NID মেক','Auto NID card generator','custom',?,0,'hidden',0)")
            ->execute([$AUTO_PRICE]);
        $__svc = ['id' => (int)$pdo->lastInsertId()];
    }
    $AUTO_SVC_ID = (int)$__svc['id'];
} catch (Throwable $e) {
    error_log('auto_nid service row failed: '.$e->getMessage());
}


error_reporting(E_ALL & ~E_NOTICE & ~E_WARNING);


// ---------- Helper: bn digits <-> en digits ----------
function bn2en($s) {
    return str_replace(['০','১','২','৩','৪','৫','৬','৭','৮','৯'],
                       ['0','1','2','3','4','5','6','7','8','9'], $s);
}
function en2bn($s) {
    return str_replace(['0','1','2','3','4','5','6','7','8','9'],
                       ['০','১','২','৩','৪','৫','৬','৭','৮','৯'], $s);
}

// ---------- Helper: extract PDF text ----------
function extract_pdf_text($pdfPath) {
    $cmd = 'pdftotext -layout -enc UTF-8 ' . escapeshellarg($pdfPath) . ' - 2>&1';
    return shell_exec($cmd) ?: '';
}
function extract_pdf_text_raw($pdfPath) {
    $cmd = 'pdftotext -raw -enc UTF-8 ' . escapeshellarg($pdfPath) . ' - 2>&1';
    return shell_exec($cmd) ?: '';
}

// ---------- Helpers for Citizen-Data PDF (column-based layout) ----------
function nid_grab_line($txt, $label) {
    if (preg_match('/^\s*' . preg_quote($label, '/') . '\s{2,}(\S.*?)(?:\s{2,}|$)/mu', $txt, $m)) return trim($m[1]);
    return '';
}

/**
 * Extract Present Address block lines between "Present Address" and "Permanent Address".
 * Preserves original spacing so we can use column positions.
 */
function nid_extract_present_block($txt) {
    $lines = explode("\n", $txt);
    $out = []; $in = false;
    foreach ($lines as $ln) {
        $t = ltrim($ln);
        if (!$in) {
            if (strpos($t, 'Present Address') === 0) { $in = true; $out[] = $ln; }
            continue;
        }
        if (strpos($t, 'Permanent Address') === 0 || strpos($t, 'Permanent') === 0) break;
        $out[] = $ln;
    }
    return $out;
}

/**
 * Robust Present-Address parser.
 * Uses `pdftotext -raw` for the address block only, then walks the resulting
 * token stream matching the longest known label at each position. Values are
 * whatever appears between one label and the next. This tolerates the wildly
 * inconsistent line-wrapping of Citizen Data PDFs.
 */
function nid_parse_present_address_raw($rawText) {
    $lines = explode("\n", $rawText);
    $blk = []; $in = false;
    foreach ($lines as $ln) {
        $t = trim($ln);
        if (!$in) {
            if (strpos($t, 'Present Address') === 0) {
                $in = true;
                $t = ltrim(substr($t, strlen('Present Address')));
                if ($t !== '') $blk[] = $t;
            }
            continue;
        }
        if ($t === 'Permanent Address' || strpos($t, 'Permanent Address') === 0 || $t === 'Permanent' || strpos($t, 'Permanent') === 0) break;
        if ($t !== '') $blk[] = $t;
    }
    if (!$blk) return '';
    $stream = implode(' ', $blk);
    // collapse multiple spaces
    $stream = preg_replace('/\s+/u', ' ', trim($stream));

    // Known labels — longest first so multi-word matches win
    $labels = [
        'City Corporation Or Municipality',
        'City Corporation / Municipality',
        'City Corporation',
        'Additional Mouza/Moholla',
        'Additional Village/Road',
        'Ward For Union Porishod',
        'Home/Holding No',
        'Smart Card Info',
        'Post Office',
        'Postal Code',
        'Union/Ward',
        'Village/Road',
        'Mouza/Moholla',
        'Additional',
        'Cantonment',
        'Division',
        'District',
        'Upozila',
        'Region',
        'RMO',
    ];

    // Walk the stream, extract (label, value) pairs.
    $fields = [];
    $curLbl = ''; $curVal = '';
    $flush = function() use (&$curLbl, &$curVal, &$fields) {
        if ($curLbl !== '') {
            $v = trim($curVal);
            if (!isset($fields[$curLbl]) || $fields[$curLbl] === '') $fields[$curLbl] = $v;
        }
        $curLbl = ''; $curVal = '';
    };

    $pos = 0; $len = mb_strlen($stream);
    while ($pos < $len) {
        // skip spaces
        while ($pos < $len && mb_substr($stream, $pos, 1) === ' ') $pos++;
        if ($pos >= $len) break;
        // try longest label match at $pos (must be followed by space or end)
        $matched = null;
        foreach ($labels as $lbl) {
            $L = mb_strlen($lbl);
            if (mb_substr($stream, $pos, $L) === $lbl) {
                $next = mb_substr($stream, $pos + $L, 1);
                if ($next === '' || $next === ' ') { $matched = $lbl; break; }
            }
        }
        if ($matched !== null) {
            $flush();
            $curLbl = $matched;
            $pos += mb_strlen($matched);
        } else {
            // take one word token as value
            $end = mb_strpos($stream, ' ', $pos);
            if ($end === false) $end = $len;
            $word = mb_substr($stream, $pos, $end - $pos);
            $curVal = ($curVal === '') ? $word : ($curVal . ' ' . $word);
            $pos = $end;
        }
    }
    $flush();

    // Cleaners
    $clean = function($s) {
        $s = preg_replace('/\s*\(\d+\)\s*$/u', '', $s);
        $s = trim($s);
        if ($s === '-' || $s === ',' || $s === '।') return '';
        return $s;
    };

    $get = function($k) use ($fields, $clean) {
        return isset($fields[$k]) ? $clean($fields[$k]) : '';
    };

    $district   = $get('District');
    $upozila    = $get('Upozila');
    $postOffice = $get('Post Office');
    $postalCode = $get('Postal Code');
    $village    = $get('Village/Road');
    if (!$village) $village = $get('Additional Village/Road');
    if (!$village) $village = $get('Additional');
    $mouza      = $get('Mouza/Moholla');
    if (!$mouza)   $mouza   = $get('Additional Mouza/Moholla');
    $home       = $get('Home/Holding No');
    $unionWard  = $get('Union/Ward');

    $parts = [];
    if ($home)       $parts[] = 'হোল্ডিং: ' . $home;
    // "গ্রাম:" label pre-written, only value follows
    if ($village)    $parts[] = 'গ্রাম: ' . $village;
    // avoid duplicate: skip mouza if same as village
    if ($mouza && mb_strtolower(trim($mouza)) !== mb_strtolower(trim($village))) $parts[] = $mouza;
    // Ward intentionally omitted per requirement
    if ($postOffice) {
        $po = 'ডাকঘর: ' . $postOffice;
        if ($postalCode) $po .= ' - ' . en2bn(bn2en($postalCode));
        $parts[] = $po;
    }
    if ($upozila)    $parts[] = $upozila;
    if ($district)   $parts[] = $district;
    return implode(', ', $parts);
}

// ---------- Signature normalizer: preserve original pixels ----------
// NOTE: Previously this function binarized the signature (every "ink" pixel
// forced to solid black), which visibly THICKENED strokes and over-enhanced
// the signature. We now keep the original image exactly as-is — only flatten
// transparency onto a white background so the PNG shows correctly on the
// card. No thresholding, no color change, no thickening.
function normalize_signature_dataurl($dataurl) {
    if (!$dataurl) return $dataurl;
    if (!function_exists('imagecreatefromstring')) return $dataurl;
    if (!preg_match('#^data:([^;]+);base64,(.*)$#', $dataurl, $m)) return $dataurl;
    $bin = base64_decode($m[2]);
    $src = @imagecreatefromstring($bin);
    if (!$src) return $dataurl;
    $w = imagesx($src); $h = imagesy($src);

    // If the source has no alpha channel, just return the original untouched.
    // (No transparency = nothing to flatten, and we don't want to re-encode
    // and risk any quality change.)
    $hasAlpha = false;
    imagealphablending($src, false);
    imagesavealpha($src, true);
    // Quick alpha probe on the four corners + center.
    $probe = [[0,0],[$w-1,0],[0,$h-1],[$w-1,$h-1],[intdiv($w,2), intdiv($h,2)]];
    foreach ($probe as $p) {
        $rgba = imagecolorat($src, $p[0], $p[1]);
        if ((($rgba >> 24) & 0x7f) > 0) { $hasAlpha = true; break; }
    }
    if (!$hasAlpha) {
        imagedestroy($src);
        return $dataurl; // return original bytes untouched
    }

    // Composite over solid white — preserves original stroke color, softness,
    // and thickness (anti-aliasing intact). No threshold, no enhancement.
    $dst = imagecreatetruecolor($w, $h);
    $white = imagecolorallocate($dst, 255, 255, 255);
    imagefilledrectangle($dst, 0, 0, $w, $h, $white);
    imagealphablending($dst, true);
    imagecopy($dst, $src, 0, 0, 0, 0, $w, $h);

    ob_start();
    imagepng($dst);
    $out = ob_get_clean();
    imagedestroy($src);
    imagedestroy($dst);
    return 'data:image/png;base64,' . base64_encode($out);
}

// ---------- Signature auto-crop (trim empty whitespace / transparency) ----------
function autocrop_signature_dataurl($dataurl) {
    if (!$dataurl) return $dataurl;
    if (!function_exists('imagecreatefromstring')) return $dataurl;
    if (!preg_match('#^data:([^;]+);base64,(.*)$#', $dataurl, $m)) return $dataurl;
    $bin = base64_decode($m[2]);
    $src = @imagecreatefromstring($bin);
    if (!$src) return $dataurl;
    $w = imagesx($src); $h = imagesy($src);
    imagealphablending($src, false);
    imagesavealpha($src, true);

    $minX = $w; $minY = $h; $maxX = -1; $maxY = -1;
    for ($y = 0; $y < $h; $y++) {
        for ($x = 0; $x < $w; $x++) {
            $rgba = imagecolorat($src, $x, $y);
            $alpha = ($rgba >> 24) & 0x7f;
            if ($alpha > 100) continue; // treat as transparent -> ignore
            $r = ($rgba >> 16) & 0xff;
            $g = ($rgba >> 8) & 0xff;
            $b = $rgba & 0xff;
            $lum = 0.299 * $r + 0.587 * $g + 0.114 * $b;
            if ($lum > 225) continue; // near-white background -> ignore
            if ($x < $minX) $minX = $x;
            if ($y < $minY) $minY = $y;
            if ($x > $maxX) $maxX = $x;
            if ($y > $maxY) $maxY = $y;
        }
    }
    if ($maxX < 0 || $maxY < 0) { imagedestroy($src); return $dataurl; }

    $pad = 4;
    $minX = max(0, $minX - $pad);
    $minY = max(0, $minY - $pad);
    $maxX = min($w - 1, $maxX + $pad);
    $maxY = min($h - 1, $maxY + $pad);
    $cw = $maxX - $minX + 1;
    $ch = $maxY - $minY + 1;

    $dst = imagecreatetruecolor($cw, $ch);
    $white = imagecolorallocate($dst, 255, 255, 255);
    imagefilledrectangle($dst, 0, 0, $cw, $ch, $white);
    imagealphablending($dst, true);
    imagecopy($dst, $src, 0, 0, $minX, $minY, $cw, $ch);

    ob_start(); imagepng($dst); $out = ob_get_clean();
    imagedestroy($src); imagedestroy($dst);
    return 'data:image/png;base64,' . base64_encode($out);
}

function nid_parse_present_address($layoutTxt) {
    // First try RAW mode via file path passthrough — but we only have layout text.
    // The parser above expects raw text; feed the layout text through it — the label
    // matching still works because labels are unique multi-word tokens.
    // Additionally the caller may pass raw text directly if it was extracted separately.
    return nid_parse_present_address_raw($layoutTxt);
}


// ---------- Parse NID fields ----------
function parse_nid($txt, $rawTxt = '') {
    $d = [
        'nameBangla'=>'', 'nameEnglish'=>'', 'nameFather'=>'',
        'nameMother'=>'', 'dob'=>'', 'nid'=>'', 'pin'=>'',
        'fulladdress'=>'', 'bloodGroup'=>'', 'birthPlace'=>'',
        'issued'=>'', 'gender'=>'male', 'maritalStatus'=>'unmarried',
        'spouseName'=>''
    ];
    $d['nameBangla']  = nid_grab_line($txt, 'Name(Bangla)');
    $d['nameEnglish'] = strtoupper(nid_grab_line($txt, 'Name(English)'));
    $d['nameFather']  = nid_grab_line($txt, 'Father Name');
    $d['nameMother']  = nid_grab_line($txt, 'Mother Name');
    $d['spouseName']  = nid_grab_line($txt, 'Spouse Name');
    $d['birthPlace']  = nid_grab_line($txt, 'Birth Place');
    $d['bloodGroup']  = nid_grab_line($txt, 'Blood Group');

    $g = strtolower(nid_grab_line($txt, 'Gender'));
    if ($g === 'female' || $g === 'male') $d['gender'] = $g;
    $m = strtolower(nid_grab_line($txt, 'Marital'));
    if ($m) $d['maritalStatus'] = $m;

    $dob = nid_grab_line($txt, 'Date of Birth');
    if ($dob && preg_match('/(\d{4})-(\d{2})-(\d{2})/', $dob, $mm)) {
        $months = ['01'=>'Jan','02'=>'Feb','03'=>'Mar','04'=>'Apr','05'=>'May','06'=>'Jun','07'=>'Jul','08'=>'Aug','09'=>'Sep','10'=>'Oct','11'=>'Nov','12'=>'Dec'];
        $d['dob'] = $mm[3] . ' ' . $months[$mm[2]] . ' ' . $mm[1];
    } else {
        $d['dob'] = $dob;
    }

    $pin = nid_grab_line($txt, 'Pin');
    $natid = nid_grab_line($txt, 'National ID');
    $d['pin'] = $pin ?: $natid;
    // ID NO: show whatever is in the "National ID" field verbatim
    // (could be 10, 13, or 17 digits). Fallback to Pin if no separate NID.
    $d['nid'] = $natid !== '' ? $natid : $pin;

    $d['fulladdress'] = nid_parse_present_address_raw($rawTxt !== '' ? $rawTxt : $txt);
    $d['issued'] = date('d/m/Y');
    return $d;
}


// ---------- Auto extract Photo + Signature images from Citizen PDF ----------
function extract_pdf_images_auto($pdfPath) {
    $photo = ''; $sign = '';
    $tmpDir = sys_get_temp_dir() . '/nidimg_' . uniqid();
    if (!@mkdir($tmpDir) && !is_dir($tmpDir)) return [$photo, $sign];
    $prefix = $tmpDir . '/img';
    // -all keeps original formats (jpg/png/etc.)
    @shell_exec('pdfimages -all ' . escapeshellarg($pdfPath) . ' ' . escapeshellarg($prefix) . ' 2>&1');
    $files = glob($tmpDir . '/img-*') ?: [];
    $cands = [];
    foreach ($files as $f) {
        $info = @getimagesize($f);
        if (!$info) continue;
        $w = $info[0]; $h = $info[1];
        if ($w < 20 || $h < 20) continue;
        $cands[] = [
            'file'=>$f,'w'=>$w,'h'=>$h,
            'mime'=>$info['mime'] ?: 'image/jpeg',
            'area'=>$w*$h,
            'ratio'=> $w / max(1,$h),
        ];
    }
    // Heuristics:
    //   Photo    → portrait-ish (ratio ~ 0.6-1.1), largest area
    //   Signature→ wide landscape (ratio > 1.4), typically smaller
    $photoCand = null; $signCand = null;
    // largest area first for photo
    usort($cands, function($a,$b){ return $b['area'] - $a['area']; });
    foreach ($cands as $c) {
        if (!$photoCand && $c['ratio'] >= 0.55 && $c['ratio'] <= 1.15) { $photoCand = $c; break; }
    }
    // signature: widest ratio
    $bestR = 0;
    foreach ($cands as $c) {
        if ($photoCand && $c['file'] === $photoCand['file']) continue;
        if ($c['ratio'] > 1.4 && $c['ratio'] > $bestR) { $bestR = $c['ratio']; $signCand = $c; }
    }
    // fallback: if no photo found, biggest image
    if (!$photoCand && !empty($cands)) $photoCand = $cands[0];
    if ($photoCand) {
        $photo = 'data:' . $photoCand['mime'] . ';base64,' . base64_encode(file_get_contents($photoCand['file']));
    }
    if ($signCand) {
        $sign = 'data:' . $signCand['mime'] . ';base64,' . base64_encode(file_get_contents($signCand['file']));
    }
    foreach ($files as $f) @unlink($f);
    @rmdir($tmpDir);
    return [$photo, $sign];
}

function file_to_dataurl_from($file) {
    if (empty($file['tmp_name']) || !is_uploaded_file($file['tmp_name'])) return '';
    $mime = mime_content_type($file['tmp_name']) ?: 'image/jpeg';
    $b64 = base64_encode(file_get_contents($file['tmp_name']));
    return "data:$mime;base64,$b64";
}

$action = $_POST['action'] ?? '';

// =====================================================================
// AJAX: PDF extract — returns JSON { ok, data|error }
// =====================================================================
if ($action === 'extract_ajax') {
    header('Content-Type: application/json; charset=utf-8');
    try {
        if (empty($_FILES['pdf']['tmp_name'])) throw new Exception('PDF আপলোড করেননি।');
        $rawText = extract_pdf_text($_FILES['pdf']['tmp_name']);
        $rawRaw  = extract_pdf_text_raw($_FILES['pdf']['tmp_name']);
        if (!$rawText) throw new Exception('pdftotext কাজ করেনি। হোস্টিং-এ poppler-utils দরকার।');
        $data = parse_nid($rawText, $rawRaw);
        list($autoPhoto, $autoSign) = extract_pdf_images_auto($_FILES['pdf']['tmp_name']);
        $data['imageUrl1'] = $autoPhoto ?: '';
        if ($autoSign) {
            $sig = normalize_signature_dataurl($autoSign);
            $sig = autocrop_signature_dataurl($sig);
            $data['imageUrl2'] = $sig;
        } else {
            $data['imageUrl2'] = '';
        }
        $data['pin17']    = '';
        $data['sig_asis'] = '';
        echo json_encode(['ok'=>true,'data'=>$data], JSON_UNESCAPED_UNICODE);
    } catch (Exception $e) {
        echo json_encode(['ok'=>false,'error'=>$e->getMessage()], JSON_UNESCAPED_UNICODE);
    }
    exit;
}

// =====================================================================
// STAGE 1: Preview / edit page (action=preview) — parse PDF, show form
// =====================================================================
if ($action === '' || $action === 'preview') {
    $data = [
        'nameBangla'=>'', 'nameEnglish'=>'', 'nameFather'=>'',
        'nameMother'=>'', 'dob'=>'', 'nid'=>'', 'pin'=>'',
        'fulladdress'=>'', 'bloodGroup'=>'', 'birthPlace'=>'',
        'issued'=>date('d/m/Y'), 'gender'=>'male', 'maritalStatus'=>'unmarried',
        'spouseName'=>'', 'imageUrl1'=>'', 'imageUrl2'=>'',
        'pin17'=>'', 'sig_asis'=>''
    ];
    if ($action === 'preview' && !empty($_FILES['pdf']['tmp_name'])) {
    $rawText = extract_pdf_text($_FILES['pdf']['tmp_name']);
    $rawRaw  = extract_pdf_text_raw($_FILES['pdf']['tmp_name']);
    if (!$rawText) exit('<h3 style="font-family:sans-serif;color:#b00">pdftotext কাজ করেনি। cPanel সাপোর্টে বলুন <b>poppler-utils</b> install করতে।</h3>');
    $data = parse_nid($rawText, $rawRaw);
    $data['imageUrl1'] = file_to_dataurl_from($_FILES['imageUrl1'] ?? []);
    $data['imageUrl2'] = file_to_dataurl_from($_FILES['imageUrl2'] ?? []);
    // Auto extract from PDF if user did not upload manually
    if (!$data['imageUrl1'] || !$data['imageUrl2']) {
        list($autoPhoto, $autoSign) = extract_pdf_images_auto($_FILES['pdf']['tmp_name']);
        if (!$data['imageUrl1'] && $autoPhoto) $data['imageUrl1'] = $autoPhoto;
        if (!$data['imageUrl2'] && $autoSign)  $data['imageUrl2'] = $autoSign;
    }
    // Normalize signature: transparent bg -> white, strokes -> black
    // Only normalize when auto-extracted from PDF. If the user uploaded a
    // signature file manually (usually a cropped screenshot), keep it as-is.
    $userUploadedSig = !empty($_FILES['imageUrl2']['tmp_name']) && is_uploaded_file($_FILES['imageUrl2']['tmp_name']);
    if ($data['imageUrl2'] && !$userUploadedSig) {
        $data['imageUrl2'] = normalize_signature_dataurl($data['imageUrl2']);
    }
    // Auto-crop signature (transparent / white background) so it fits without
    // requiring the user to manually trim.
    if ($data['imageUrl2']) {
        $data['imageUrl2'] = autocrop_signature_dataurl($data['imageUrl2']);
    }
    $data['pin17']     = (isset($_POST['pin17']) && $_POST['pin17']==='yes') ? 'yes' : '';
    $data['sig_asis']  = $userUploadedSig ? 'yes' : '';
    }
    ?>
    <!doctype html><html lang="bn"><head><meta charset="utf-8">
    <title>Preview &amp; Edit — NID Data</title>
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <style>
      *{box-sizing:border-box}
      html,body{margin:0;padding:0}
      body{font-family:'Segoe UI',system-ui,-apple-system,Arial,sans-serif;
        background:linear-gradient(135deg,#eef2f7,#dfe6ee);min-height:100vh;
        color:#1f2937;padding:22px 12px}
      .card{max-width:960px;margin:10px auto;background:#fff;border:1px solid #e5e7eb;
        border-radius:20px;padding:26px 22px;
        box-shadow:0 1px 2px rgba(16,24,40,.04),0 20px 40px -20px rgba(16,24,40,.18)}
      .cloud{display:flex;align-items:center;justify-content:center;
        width:120px;height:120px;margin:0 auto 6px;
        background:radial-gradient(circle at 50% 40%,#e6f3f7 0%,#ffffff 70%);border-radius:50%}
      .cloud svg{width:96px;height:96px}
      h1{margin:4px 0 2px;text-align:center;font-size:20px;color:#0f172a;font-weight:700}
      .sub{margin:0 0 18px;text-align:center;color:#64748b;font-size:13px}
      .grid{display:grid;grid-template-columns:1fr 1fr;gap:14px 18px}
      .full{grid-column:1/-1}
      @media (max-width:640px){.grid{grid-template-columns:1fr}}
      .field label{display:block;font-size:13px;font-weight:600;color:#334155;margin-bottom:6px}
      input[type=text],textarea,select{
        width:100%;padding:11px 12px;border:1px solid #cbd5e1;border-radius:10px;
        font-size:14px;background:#fff;font-family:inherit;color:#0f172a;
        transition:border-color .15s,box-shadow .15s;
      }
      input[type=text]:focus,textarea:focus,select:focus{
        outline:0;border-color:#0ea5e9;box-shadow:0 0 0 3px rgba(14,165,233,.15)
      }
      textarea{min-height:72px;resize:vertical}
      .file-drop{
        position:relative;display:flex;align-items:center;gap:10px;
        padding:11px 12px;border:1.5px dashed #cbd5e1;border-radius:10px;
        background:#f8fafc;cursor:pointer;font-size:13px;color:#64748b
      }
      .file-drop.has-file{border-style:solid;border-color:#0ea5e9;background:#fff;color:#0f172a}
      .file-drop input[type=file]{position:absolute;inset:0;opacity:0;cursor:pointer}
      .file-drop .fname{font-weight:600;color:#0f172a}
      .thumb-row{display:flex;gap:10px;margin-top:8px;flex-wrap:wrap}
      .thumb{max-width:80px;max-height:80px;border:1px solid #e2e8f0;border-radius:8px;background:#fff}
      .row{display:flex;align-items:center;gap:8px;margin-top:6px;font-size:13px;color:#334155}
      .parent-lbl{display:flex;align-items:center;gap:8px;margin-bottom:6px}
      .parent-lbl select{
        width:auto;padding:4px 8px;font-size:12.5px;font-weight:700;color:#0369a1;
        background:#e0f2fe;border:1px solid #7dd3fc;border-radius:8px;cursor:pointer
      }
      .parent-lbl .suffix{font-size:13px;font-weight:600;color:#334155}
      .actions{display:flex;gap:10px;margin-top:22px;flex-wrap:wrap;justify-content:flex-end}
      .btn{padding:12px 22px;border:0;border-radius:12px;font-size:14.5px;font-weight:700;
        cursor:pointer;text-decoration:none;display:inline-block;transition:.15s}
      .primary{background:linear-gradient(180deg,#0ea5e9,#0369a1);color:#fff;
        box-shadow:0 8px 18px -8px rgba(3,105,161,.55)}
      .primary:hover{transform:translateY(-1px)}
      .secondary{background:#e2e8f0;color:#0f172a}

      /* PDF drop zone (top of form) */
      .pdf-drop{position:relative;display:flex;align-items:center;gap:12px;
        padding:16px 14px;border:1.5px dashed #0ea5e9;border-radius:14px;
        background:#f0f9ff;cursor:pointer;transition:.15s;margin-bottom:16px}
      .pdf-drop:hover{background:#e0f2fe}
      .pdf-drop.has-file{border-style:solid;background:#fff}
      .pdf-drop .ic{flex:none;width:44px;height:44px;border-radius:12px;background:#0ea5e9;color:#fff;
        display:flex;align-items:center;justify-content:center;font-size:22px}
      .pdf-drop .txt{font-size:13.5px;color:#0369a1;line-height:1.4}
      .pdf-drop .txt b{display:block;color:#0f172a;font-weight:700;font-size:14.5px;margin-bottom:2px}
      .pdf-drop input[type=file]{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer}
      .infobar{margin:0 0 14px;padding:10px 12px;border-radius:12px;background:#f0f9ff;
        border:1px solid #bae6fd;color:#075985;font-size:13px;display:flex;
        justify-content:space-between;gap:8px;flex-wrap:wrap}
      .notice{margin:0 0 14px;padding:12px 14px;border-radius:12px;background:#fff7ed;
        border:1px solid #fdba74;color:#9a3412;font-size:13px;line-height:1.6}
      /* Full-screen loader */
      .loader-overlay{position:fixed;inset:0;background:rgba(15,23,42,.72);
        backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
        display:none;align-items:center;justify-content:center;z-index:9999;
        flex-direction:column;color:#fff}
      .loader-overlay.show{display:flex}
      .spinner{width:76px;height:76px;border:6px solid rgba(255,255,255,.18);
        border-top-color:#38bdf8;border-radius:50%;animation:spin .9s linear infinite}
      @keyframes spin{to{transform:rotate(360deg)}}
      .loader-overlay .title{margin-top:22px;font-size:18px;font-weight:700;letter-spacing:.3px}
      .loader-overlay .desc{margin-top:8px;font-size:13.5px;color:#cbd5e1;text-align:center;line-height:1.6;padding:0 22px}
      .dots{display:inline-block;width:26px;text-align:left}
      .dots::after{content:'';animation:dots 1.4s steps(4,end) infinite}
      @keyframes dots{0%{content:''}25%{content:'.'}50%{content:'..'}75%{content:'...'}100%{content:''}}
    
    </style></head><body>
      <div class="card">
        <div class="cloud">
          <svg viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
            <path d="M40 76c-11 0-20-9-20-20s9-20 20-20c2 0 4 .3 6 .9C50 25 60 18 72 18c17 0 30 13 30 30 0 1-.1 2-.2 3 8 2 14 9 14 18 0 10-8 18-18 18H40z" fill="#e0f2fe" stroke="#0ea5e9" stroke-width="3"/>
            <rect x="46" y="86" width="36" height="6" rx="2" fill="#0ea5e9"/>
            <path d="M64 52 v28 M52 64 l12 -12 l12 12" stroke="#0ea5e9" stroke-width="5" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
          </svg>
        </div>
        <h1>ডাটা প্রিভিউ ও এডিট করুন</h1>
        <p class="sub">সব ঘর অটো ফিলাপ হয়েছে — প্রয়োজনে ঠিক করে নিন।</p>

        <form method="post" id="editForm">
          <input type="hidden" name="action" value="render">


          <?php if ($AUTO_NOTICE !== ''): ?>
            <div class="notice">📢 <?=nl2br(e($AUTO_NOTICE))?></div>
          <?php endif; ?>
          <div class="infobar">
            <span>💰 প্রতি কার্ডের মূল্য: <b><?=e(money($AUTO_PRICE))?></b></span>
            <span>💳 আপনার ব্যালেন্স: <b><?=e(money($U['balance']))?></b></span>
          </div>
          <label class="pdf-drop" id="pdfDrop">
            <div class="ic">📄</div>
            <div class="txt"><b id="pdfName">Citizen Data PDF আপলোড করুন</b>ফাইল সিলেক্ট করলেই অটো ফিলাপ হবে</div>
            <input type="file" id="pdfInput" accept="application/pdf">
          </label>

          <div class="grid">
            <div class="field">
              <label>আইডি ফটো <small style="color:#94a3b8;font-weight:500">— পুনরায় দিতে চাইলে</small></label>
              <label class="file-drop" data-target="ph2">
                <span class="fname" id="ph2">Choose photo</span>
                <input type="file" name="imageUrl1_file" accept="image/*">
              </label>
              <div class="thumb-row" id="ph2Thumb" style="<?=$data['imageUrl1']?'':'display:none'?>"><img class="thumb" id="ph2Img" src="<?=$data['imageUrl1']?>"></div>
            </div>

            <div class="field">
              <label>আইডি স্বাক্ষর <small style="color:#94a3b8;font-weight:500">— পুনরায় দিতে চাইলে</small></label>
              <label class="file-drop" data-target="sg2">
                <span class="fname" id="sg2">Choose signature</span>
                <input type="file" name="imageUrl2_file" accept="image/*">
              </label>
              <div class="thumb-row" id="sg2Thumb" style="<?=$data['imageUrl2']?'':'display:none'?>"><img class="thumb" id="sg2Img" src="<?=$data['imageUrl2']?>"></div>
            </div>

            <div class="field">
              <label>আইডি নাম্বার:</label>
              <input type="text" name="nid" value="<?=htmlspecialchars($data['nid'])?>">
            </div>
            <div class="field">
              <label>পিন নাম্বার:</label>
              <input type="text" name="pin" value="<?=htmlspecialchars($data['pin'])?>">
            </div>

            <div class="field">
              <label>নাম (বাংলা):</label>
              <input type="text" name="nameBangla" value="<?=htmlspecialchars($data['nameBangla'])?>">
            </div>
            <div class="field">
              <label>নাম (ইংরেজি):</label>
              <input type="text" name="nameEnglish" value="<?=htmlspecialchars($data['nameEnglish'])?>">
            </div>

            <div class="field">
              <label>জন্ম তারিখ:</label>
              <input type="text" name="dob" value="<?=htmlspecialchars($data['dob'])?>">
            </div>
            <div class="field">
              <label>জন্মস্থান:</label>
              <input type="text" name="birthPlace" value="<?=htmlspecialchars($data['birthPlace'])?>">
            </div>

            <div class="field">
              <div class="parent-lbl">
                <select id="parentType">
                  <option value="father">পিতা</option>
                  <option value="spouse">স্বামী</option>
                </select>
                <span class="suffix">এর নাম:</span>
              </div>
              <input type="text" id="parentInput" value="">
              <input type="hidden" name="nameFather" id="nameFatherHidden" value="<?=htmlspecialchars($data['nameFather'])?>">
              <input type="hidden" name="spouseName" id="spouseNameHidden" value="<?=htmlspecialchars($data['spouseName'])?>">
            </div>

            <div class="field">
              <label>মায়ের নাম:</label>
              <input type="text" name="nameMother" value="<?=htmlspecialchars($data['nameMother'])?>">
            </div>

            <div class="field">
              <label>রক্তের গ্রুপ:</label>
              <input type="text" name="bloodGroup" value="<?=htmlspecialchars($data['bloodGroup'])?>">
            </div>
            <div class="field">
              <label>ইস্যু তারিখ (dd/mm/yyyy):</label>
              <input type="text" name="issued" value="<?=htmlspecialchars($data['issued'])?>">
            </div>

            <div class="field">
              <label>লিঙ্গ:</label>
              <select name="gender">
                <option value="male" <?=$data['gender']==='male'?'selected':''?>>Male</option>
                <option value="female" <?=$data['gender']==='female'?'selected':''?>>Female</option>
              </select>
            </div>
            <div class="field">
              <label>বৈবাহিক অবস্থা:</label>
              <select name="maritalStatus">
                <option value="unmarried" <?=$data['maritalStatus']==='unmarried'?'selected':''?>>Unmarried</option>
                <option value="married" <?=$data['maritalStatus']==='married'?'selected':''?>>Married</option>
              </select>
            </div>

            <div class="field">
              <label>ID টাইপ:</label>
              <select name="pin17">
                <option value="" <?=$data['pin17']===''?'selected':''?>>13 digit (NID)</option>
                <option value="yes" <?=$data['pin17']==='yes'?'selected':''?>>17 digit (Pin)</option>
              </select>
            </div>
            <div class="field">
              <label style="display:block;margin-top:32px">
                <input type="checkbox" name="sig_asis" value="yes" id="sig_asis" <?= ($data['sig_asis']==='yes'?'checked':'') ?>>
                <span style="font-weight:500;color:#475569;font-size:13px">স্বাক্ষর হুবহু বসাও (ক্রপ করা স্ক্রিনশট)</span>
              </label>
            </div>

            <div class="field full">
              <label>ঠিকানা:</label>
              <textarea name="fulladdress" placeholder="বাসা/হোল্ডি: (Holding), গ্রাম/রাস্তা: (গ্রাম, মৌজা), ডাকঘর: পোস্ট অফিস- পোস্ট কোড, উপজেলা, সিটি কর্পোরেশন/পৌরসভা, জেলা"><?=htmlspecialchars($data['fulladdress'])?></textarea>
            </div>
          </div>

          <input type="hidden" name="imageUrl1" id="imageUrl1Hidden" value="<?=htmlspecialchars($data['imageUrl1'])?>">
          <input type="hidden" name="imageUrl2" id="imageUrl2Hidden" value="<?=htmlspecialchars($data['imageUrl2'])?>">

          <div class="actions">
            <a href="?" class="btn secondary">← Back</a>
            <button type="submit" class="btn primary">Generate NID Card →</button>
          </div>
        </form>
      </div>

      <div class="loader-overlay" id="loader">
        <div class="spinner"></div>
        <div class="title" id="loaderTitle">PDF প্রসেস হচ্ছে<span class="dots"></span></div>
        <div class="desc" id="loaderDesc">ফাইল থেকে ডাটা এক্সট্রাক্ট করে ঘরগুলো অটো ফিলাপ করছি,<br>একটু অপেক্ষা করুন…</div>
      </div>

      <script>
        function showLoader(title, desc){
          document.getElementById('loaderTitle').innerHTML = (title||'প্রসেস হচ্ছে')+'<span class="dots"></span>';
          document.getElementById('loaderDesc').innerHTML  = desc||'';
          document.getElementById('loader').classList.add('show');
        }
        function hideLoader(){ document.getElementById('loader').classList.remove('show'); }

        // File-drop labels + client-side preview for photo & signature
        document.querySelectorAll('.file-drop').forEach(function(d){
          var inp=d.querySelector('input[type=file]');
          var lbl=document.getElementById(d.dataset.target);
          inp.addEventListener('change',function(){
            if(inp.files && inp.files[0]){
              var file = inp.files[0];
              lbl.textContent=file.name;
              d.classList.add('has-file');
              // Show loader while reading, then update thumb + hidden input
              showLoader('ছবি লোড হচ্ছে','একটু অপেক্ষা করুন…');
              var reader = new FileReader();
              reader.onload = function(ev){
                var dataUrl = ev.target.result;
                if (inp.name === 'imageUrl1_file'){
                  document.getElementById('imageUrl1Hidden').value = dataUrl;
                  var img = document.getElementById('ph2Img');
                  var box = document.getElementById('ph2Thumb');
                  img.src = dataUrl; box.style.display = '';
                } else if (inp.name === 'imageUrl2_file'){
                  document.getElementById('imageUrl2Hidden').value = dataUrl;
                  var img = document.getElementById('sg2Img');
                  var box = document.getElementById('sg2Thumb');
                  img.src = dataUrl; box.style.display = '';
                  // If user uploads signature manually, auto-check "sig_asis"
                  var sa = document.getElementById('sig_asis');
                  if (sa) sa.checked = true;
                }
                hideLoader();
              };
              reader.onerror = function(){ hideLoader(); alert('ফাইল লোড করা যায়নি।'); };
              reader.readAsDataURL(file);
            }
          });
        });

        // PDF drop → AJAX auto-extract & auto-fill
        (function(){
          var pdfInp = document.getElementById('pdfInput');
          var pdfDrop = document.getElementById('pdfDrop');
          var pdfLbl = document.getElementById('pdfName');
          if (!pdfInp) return;
          pdfInp.addEventListener('change', function(){
            if (!pdfInp.files || !pdfInp.files[0]) return;
            var file = pdfInp.files[0];
            pdfLbl.textContent = file.name;
            pdfDrop.classList.add('has-file');
            showLoader('PDF প্রসেস হচ্ছে','ফাইল থেকে ডাটা এক্সট্রাক্ট করে ঘরগুলো অটো ফিলাপ করছি…');
            var fd = new FormData();
            fd.append('action','extract_ajax');
            fd.append('pdf', file);
            fetch(window.location.pathname + window.location.search, {method:'POST', body: fd})
              .then(function(r){ return r.json(); })
              .then(function(res){
                if (!res.ok){ hideLoader(); alert(res.error||'এক্সট্রাক্ট ব্যর্থ হয়েছে।'); return; }
                var d = res.data || {};
                function setVal(name, v){
                  var el = document.querySelector('[name="'+name+'"]');
                  if (el && v != null) el.value = v;
                }
                setVal('nid', d.nid); setVal('pin', d.pin);
                setVal('nameBangla', d.nameBangla); setVal('nameEnglish', d.nameEnglish);
                setVal('dob', d.dob); setVal('birthPlace', d.birthPlace);
                setVal('nameMother', d.nameMother);
                setVal('bloodGroup', d.bloodGroup); setVal('issued', d.issued);
                setVal('fulladdress', d.fulladdress);
                if (d.gender)        setVal('gender', d.gender);
                if (d.maritalStatus) setVal('maritalStatus', d.maritalStatus);
                // Parent (father/spouse)
                document.getElementById('nameFatherHidden').value = d.nameFather || '';
                document.getElementById('spouseNameHidden').value = d.spouseName || '';
                initParent();
                // Photo
                if (d.imageUrl1){
                  document.getElementById('imageUrl1Hidden').value = d.imageUrl1;
                  document.getElementById('ph2Img').src = d.imageUrl1;
                  document.getElementById('ph2Thumb').style.display = '';
                }
                // Signature
                if (d.imageUrl2){
                  document.getElementById('imageUrl2Hidden').value = d.imageUrl2;
                  document.getElementById('sg2Img').src = d.imageUrl2;
                  document.getElementById('sg2Thumb').style.display = '';
                }
                hideLoader();
              })
              .catch(function(err){ hideLoader(); alert('সার্ভার এরর: '+err); });
          });
        })();

        // Father / Spouse toggle
        var pType   = document.getElementById('parentType');
        var pInput  = document.getElementById('parentInput');
        var fH      = document.getElementById('nameFatherHidden');
        var sH      = document.getElementById('spouseNameHidden');
        function initParent(){
          var f = (fH.value||'').trim();
          var s = (sH.value||'').trim();
          if(!f && s){ pType.value='spouse'; pInput.value=s; }
          else { pType.value='father'; pInput.value=f; }
        }
        initParent();
        function syncParent(){
          if(pType.value==='spouse'){ sH.value=pInput.value; fH.value=''; }
          else { fH.value=pInput.value; sH.value=''; }
        }
        pInput.addEventListener('input', syncParent);
        pType.addEventListener('change', function(){
          // Swap current typed value into the newly selected slot
          syncParent();
        });
        document.getElementById('editForm').addEventListener('submit', syncParent);
      </script>
    </body></html>
    </body></html>
    <?php
    exit;
}

// =====================================================================
// STAGE 2: Render final NID card (action=render)
// ---------------------------------------------------------------------
// Charge balance (once per unique card per session) and log order.
$__nameEn = strtoupper(trim($_POST['nameEnglish'] ?? ''));
$__nidNo  = trim($_POST['nid'] ?? '');
$__dobRaw = trim($_POST['dob'] ?? '');
$__cardKey = md5($__nameEn.'|'.$__nidNo.'|'.$__dobRaw.'|'.$U['id']);
if (empty($_SESSION['auto_nid_paid'][$__cardKey])) {
    if ((float)$U['balance'] < $AUTO_PRICE) {
        flash_set('err', 'ব্যালেন্স যথেষ্ট নয় ('.money($AUTO_PRICE).')। রিচার্জ করুন।');
        redirect('recharge.php');
    }
    // NOTE: transactions.ref_id is INT — passing '' breaks on strict MySQL (HTTP 500).
    try {
        $pdo->prepare("UPDATE users SET balance = balance - ? WHERE id = ?")
            ->execute([$AUTO_PRICE, $U['id']]);
        log_txn($pdo, $U['id'], 'debit', $AUTO_PRICE, null, 'অটো NID মেক');
        $pdo->prepare("INSERT INTO orders(user_id, service_id, price, status, custom_data, delivery_type, delivery_content, completed_at, user_notified)
                       VALUES(?,?,?, 'completed', ?, 'text', ?, NOW(), 1)")
            ->execute([
                $U['id'], ($AUTO_SVC_ID ?: null), $AUTO_PRICE,
                json_encode(['nameEnglish'=>$__nameEn,'nid'=>$__nidNo,'dob'=>$__dobRaw], JSON_UNESCAPED_UNICODE),
                'Auto NID card generated'
            ]);
    } catch (Throwable $e) {
        error_log('auto_nid billing failed: '.$e->getMessage());
    }
    if (!isset($_SESSION['auto_nid_paid'])) $_SESSION['auto_nid_paid'] = [];
    $_SESSION['auto_nid_paid'][$__cardKey] = 1;
    // refresh local balance for any downstream use
    $U['balance'] = (float)$U['balance'] - $AUTO_PRICE;
}

// ---------------------------------------------------------------------

// =====================================================================
$data = [
    'nameBangla'   => trim($_POST['nameBangla'] ?? ''),
    'nameEnglish'  => strtoupper(trim($_POST['nameEnglish'] ?? '')),
    'nameFather'   => trim($_POST['nameFather'] ?? ''),
    'nameMother'   => trim($_POST['nameMother'] ?? ''),
    'spouseName'   => trim($_POST['spouseName'] ?? ''),
    'dob'          => trim($_POST['dob'] ?? ''),
    'nid'          => trim($_POST['nid'] ?? ''),
    'pin'          => trim($_POST['pin'] ?? ''),
    'bloodGroup'   => trim($_POST['bloodGroup'] ?? ''),
    'birthPlace'   => trim($_POST['birthPlace'] ?? ''),
    'fulladdress'  => trim($_POST['fulladdress'] ?? ''),
    'issued'       => trim($_POST['issued'] ?? date('d/m/Y')),
    'gender'       => $_POST['gender'] ?? 'male',
    'maritalStatus'=> $_POST['maritalStatus'] ?? 'unmarried',
];
$imageUrl12 = file_to_dataurl_from($_FILES['imageUrl1_file'] ?? []);
if (!$imageUrl12) $imageUrl12 = $_POST['imageUrl1'] ?? '';
$sigReuploaded = !empty($_FILES['imageUrl2_file']['tmp_name']) && is_uploaded_file($_FILES['imageUrl2_file']['tmp_name']);
$imageUrl22 = file_to_dataurl_from($_FILES['imageUrl2_file'] ?? []);
if (!$imageUrl22) $imageUrl22 = $_POST['imageUrl2'] ?? '';
$sigAsIs = (($_POST['sig_asis'] ?? '') === 'yes') || $sigReuploaded;
if ($imageUrl22 && !$sigAsIs) $imageUrl22 = normalize_signature_dataurl($imageUrl22);
if ($imageUrl22) $imageUrl22 = autocrop_signature_dataurl($imageUrl22);
$is17 = (($_POST['pin17'] ?? '') === 'yes');
$idToShow = $is17 ? $data['pin'] : $data['nid'];

$barcodeData = '<pin>'.$data['pin'].'</pin><name>'.$data['nameEnglish'].'</name><DOB>'.$data['dob'].'</DOB><FP></FP><F>Right Index</F><TYPE>'.$data['bloodGroup'].'</TYPE><V>2.0</V> <ds>302c0214103fc01240542ed736c0b48858c1c03d80006215021416e73728de9618fedcd368c88d8f3a2e72096d</ds>';
$barcodeUrl = 'https://barcode.tec-it.com/barcode.ashx?data=' . urlencode($barcodeData) . '&code=PDF417&multiplebarcodes=false&translate-esc=false&unit=Fit&dpi=96&imagetype=Gif&rotation=0&color=%23000000&bgcolor=%23ffffff&codepage=Default&qunit=Mm&quiet=0';

$issuedBn = en2bn($data['issued']);
$showFather = !($is17 && $data['gender']==='female' && $data['maritalStatus']==='married');
// Override: user manually chose Spouse (পিতা ফাঁকা রেখে স্বামী সিলেক্ট করলে) → show স্বামী
if ($showFather && $data['nameFather']==='' && $data['spouseName']!=='') { $showFather = false; }
?>
<!doctype html>
<html lang="bn">
<head>
<meta charset="utf-8">
<title>nid-<?=htmlspecialchars($idToShow)?></title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link href="https://fonts.maateen.me/kalpurush/font.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+Bengali:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
  *{box-sizing:border-box}
  body{margin:0;padding:20px;background:#eef1f5;font-family:Arial,sans-serif;color:#111}
  .bn{font-family:'Kalpurush','Noto Sans Bengali','SolaimanLipi',Arial,sans-serif}
  /* wrapper flush — no padding so cards sit at page edge */
  #nid_wrapper{display:flex;gap:8px;justify-content:center;margin:0 auto;width:fit-content;background:#fff;padding:0}
  #nid_front,#nid_back{width:325px;background:#fff;border:1px solid #000;position:relative;overflow:hidden}
  #nid_front{height:198px}
  #nid_back{height:198px;position:relative}
  .front-head{display:flex;align-items:center;justify-content:space-between;padding:0 6px;position:relative;height:60px}
  .front-head img.gov{position:absolute;top:6px;left:4px;width:38px}
  .front-head .title{width:100%;display:flex;flex-direction:column;justify-content:center;align-self:center;padding-left:44px}
  .front-head h3{margin:0;text-align:center;font-size:14.5px;font-weight:500;line-height:1.05;padding-left:0}
  .front-head p.eng{margin:0;color:#007700;text-align:right;font-size:11.46px;line-height:1;letter-spacing:-.02px}
  .front-head p.mid{margin:0;text-align:center;padding-top:2px;line-height:1.1}
  .front-head p.mid .red{color:#ff0002;font-size:10px;font-weight:700}
  .front-head p.mid .slash{font-size:13px;margin:0 3px}
  .front-head p.mid .bntxt{font-size:13.33px}
  /* all dividers thin & uniform */
  .divider{border-bottom:1px solid #000;width:100%}
  .front-body{position:relative;padding:4px 4px 4px 2px;display:flex;gap:8px}
  .flower{position:absolute;left:0;right:0;top:2px;margin:auto;width:114px;height:114px;z-index:1;opacity:.70}
  .photo-col{position:relative;z-index:5;width:70px}
  .photo-col img.photo{width:68.2px;height:78px;object-fit:cover;object-position:50% 12%;background:#f2f2f2;display:block}
  .photo-col .sign{width:68.2px;height:38.5px;overflow:hidden;text-align:center;padding-top:5px}
  .photo-col .sign img{max-width:100%;max-height:100%}
  .info-col{position:relative;z-index:5;flex:1;padding-top:2px}
  /* Uniform label/value grid so all right-side values line up in one column */
  .info-col .line{margin-bottom:5px;line-height:1.2;display:flex;align-items:baseline;gap:2px}
  .info-col .line-name-en{margin-bottom:8px}
  .info-col .lbl-bn{font-size:10.8px;font-weight:700;min-width:32px;flex-shrink:0}
  .info-col .val-bn{font-size:11.8px;font-weight:700;word-break:break-word;flex:1}
  .info-col .bnname{font-family:'Kalpurush','Noto Sans Bengali','SolaimanLipi',Arial,sans-serif;font-size:12.6px;font-weight:900;-webkit-text-stroke:.22px currentColor;text-shadow:.25px 0 0 currentColor,-.25px 0 0 currentColor,0 .25px 0 currentColor;word-break:break-word;flex:1}
  .info-col .enname{font-size:11.2px;font-weight:400;flex:1}
  .info-col .lbl-en{font-size:10.5px;min-width:34px;flex-shrink:0;font-weight:400}
  .info-col .row-en{font-size:11px;display:flex;align-items:baseline;gap:2px;margin-bottom:6px}
  .info-col .row-en .val-en{flex:1;font-weight:500}
  .red{color:#ff0000}
  .bold{font-weight:700}
  /* BACK */
  .back-head{min-height:34px;display:flex;align-items:center;padding:5px 8px}
  .back-head p{margin:0;line-height:1.25;font-size:9.4px;letter-spacing:.03px;text-align:justify;font-weight:500}
  /* Back body sits between the header divider and the fixed footer.
     Give it a max-height so long addresses can never push the footer
     (permanent-address block + barcode) off its fixed bottom position. */
  .back-body{padding:3px 4px 6px;position:relative;font-size:11px;max-height:96px;overflow:hidden}
  .addr-row{display:flex;gap:3px;align-items:baseline}
  .addr-row .lbl{font-size:10.2px;padding:0 2px 0 4px;font-weight:700;flex-shrink:0}
  .addr-row .val{font-size:10.2px;flex:1;line-height:1.22;color:#000;font-weight:700}
  .meta-row{display:flex;justify-content:space-between;align-items:flex-end;font-size:10.5px;line-height:1.1;position:absolute;left:0;right:0;bottom:100%;padding:0 4px 2px}
  .meta-row .blood{color:#ff0000;font-weight:400;font-size:10.5px;margin:0 3px}
  /* Pin the entire footer block (divider + signature + barcode) to the
     bottom of the card so it stays at a fixed position regardless of
     how long the address above becomes. */
  .back-foot{padding:3px 8px 6px;position:absolute;left:0;right:0;bottom:0;background:#fff;border-top:1px solid #000}
  .back-foot .sign-img{width:78px;height:27px;margin-left:18px;display:block}
  .back-foot .sign-row{display:flex;justify-content:space-between;align-items:center;margin-top:-2px}
  .back-foot .sign-row p{margin:0;font-size:11.5px;font-weight:500}
  .back-foot .sign-row .issued{font-size:11px}
  #barcode{width:100%;height:39px;margin-top:2px}
  #barcode img{width:100%;height:100%;object-fit:fill}
  /* মূদ্রণ label sits on the border between address area and footer,
     with its bottom-right corner flush against the border/card edge. */
  .mudran{position:absolute;right:0;bottom:100%;font-size:9px;padding:1px 4px;background:#000;color:#fff;z-index:30;line-height:1;margin:0;-webkit-print-color-adjust:exact;print-color-adjust:exact}
  .toolbar{max-width:680px;margin:0 auto 12px;text-align:center}
  .toolbar button{padding:8px 16px;background:#0a58ca;color:#fff;border:0;border-radius:6px;cursor:pointer;font-size:14px}
  @media print{
    @page{margin:10mm 0 0 0;size:auto}
    html,body{-webkit-print-color-adjust:exact;print-color-adjust:exact}
    body{background:#fff;padding:40px 0 0 0}
    .toolbar{display:none}
    #nid_wrapper{padding:0}
    .mudran{background:#000!important;color:#fff!important;-webkit-print-color-adjust:exact;print-color-adjust:exact}
  }
</style>
</head>
<body>

<div class="toolbar">
  <button id="btnPrint" disabled>প্রস্তুত হচ্ছে...</button>
  <button onclick="history.back()" style="background:#666;margin-left:8px">← Edit</button>
  <div id="prepMsg" style="margin-top:6px;font-size:12px;color:#555">ছবি, বারকোড ও ফন্ট লোড হচ্ছে — সম্পূর্ণ হলে ডাউনলোড চালু হবে।</div>
</div>


<div id="nid_wrapper">
  <!-- FRONT -->
  <div id="nid_front">
    <div class="front-head">
      <img class="gov" src="https://i.ibb.co/qJHPs8Z/gov-logo-0b7f8514.png" alt="">
      <div class="title">
        <h3 class="bn">গণপ্রজাতন্ত্রী বাংলাদেশ সরকার</h3>
        <p class="eng">Government of the People's Republic of Bangladesh</p>
        <p class="mid"><span class="red">National ID Card</span><span class="slash">/</span><span class="bntxt bn">জাতীয় পরিচয় পত্র</span></p>
      </div>
    </div>
    <div class="divider"></div>
    <div class="front-body">
      <img class="flower" src="https://i.ibb.co/F3Y3Tp5/flower-logo.png" alt="">
      <div class="photo-col">
        <?php if($imageUrl12): ?><img class="photo" src="<?=$imageUrl12?>" alt=""><?php else: ?><div class="photo" style="width:68.2px;height:78px;background:#e5e5e5"></div><?php endif; ?>
        <div class="sign"><?php if($imageUrl22): ?><img src="<?=$imageUrl22?>" alt=""><?php endif; ?></div>
      </div>
      <div class="info-col">
        <div class="line"><span class="bn lbl-bn">নাম:</span><span class="bn bnname"><?=htmlspecialchars($data['nameBangla'])?></span></div>
        <div class="line line-name-en"><span class="lbl-en">Name:</span><span class="enname" style="font-size:<?= strlen($data['nameEnglish'])>25?'8.5':(strlen($data['nameEnglish'])>22?'9.8':'11.2') ?>px;font-weight:400"><?=htmlspecialchars($data['nameEnglish'])?></span></div>
        <?php if($showFather): ?>
          <div class="line"><span class="bn lbl-bn">পিতা:</span><span class="bn val-bn"><?=htmlspecialchars($data['nameFather'])?></span></div>
        <?php else: ?>
          <div class="line"><span class="bn lbl-bn">স্বামী:</span><span class="bn val-bn"><?=htmlspecialchars($data['spouseName'])?></span></div>
        <?php endif; ?>
        <div class="line"><span class="bn lbl-bn">মাতা:</span><span class="bn val-bn"><?=htmlspecialchars($data['nameMother'])?></span></div>
        <div class="row-en"><span class="lbl-en">Date of Birth:</span><span class="val-en red" style="font-weight:400"><?=htmlspecialchars($data['dob'])?></span></div>
        <div class="row-en"><span class="lbl-en">ID NO:</span><span class="val-en red bold"><?=htmlspecialchars($idToShow)?></span></div>
      </div>
    </div>
  </div>

  <!-- BACK -->
  <div id="nid_back">
    <div class="back-head">
      <p class="bn">এই কার্ডটি গণপ্রজাতন্ত্রী বাংলাদেশ সরকারের সম্পত্তি। কার্ডটি ব্যবহারকারী ব্যতীত অন্য কোথাও পাওয়া গেলে নিকটস্থ পোস্ট অফিসে জমা দেবার জন্য অনুরোধ করা হলো।</p>
    </div>
    <div class="divider"></div>
    <div class="back-body">
      <div class="addr-row">
        <div class="lbl bn">ঠিকানা:</div>
        <div class="val bn"><?=htmlspecialchars($data['fulladdress'])?></div>
      </div>
    </div>
    <div class="back-foot">
      <div class="meta-row bn">
        <p style="margin:0">
          <span>রক্তের গ্রুপ</span><span>/</span><span>Blood Group:</span>
          <b class="blood"><?=htmlspecialchars($data['bloodGroup'])?></b>
          <span>জন্মস্থান:</span> <span><?=htmlspecialchars($data['birthPlace'])?></span>
        </p>
      </div>
      <div class="mudran bn">মূদ্রণ: ০১</div>
      <img class="sign-img" src="https://i.postimg.cc/L8xxBR9n/IMG-20260527-163120-514.jpg" alt="">
      <div class="sign-row">
        <p class="bn">প্রদানকারী কর্তৃপক্ষের স্বাক্ষর</p>
        <span class="bn issued">প্রদানের তারিখ: <span><?=htmlspecialchars($issuedBn)?></span></span>
      </div>
      <div id="barcode" style="margin-top:1px"><img src="<?=htmlspecialchars($barcodeUrl)?>" alt="PDF417"></div>
    </div>
  </div>
</div>

<script>
  document.addEventListener('contextmenu', e => e.preventDefault());

  // ---------------------------------------------------------------
  // Reliable preview/download: only allow print after every image
  // (photo, signature, logos, barcode) and all Bangla fonts are
  // fully loaded/decoded. Otherwise the printed PDF comes out with
  // missing barcode / broken Bangla text.
  // ---------------------------------------------------------------
  (function () {
    var btn  = document.getElementById('btnPrint');
    var msg  = document.getElementById('prepMsg');

    function imgReady(img) {
      return new Promise(function (resolve) {
        if (img.complete && img.naturalWidth > 0) { resolve(true); return; }
        var done = false;
        function finish(ok) { if (!done) { done = true; resolve(ok); } }
        img.addEventListener('load', function () { finish(true); }, { once: true });
        img.addEventListener('error', function () { finish(false); }, { once: true });
        // never block forever on a slow external host
        setTimeout(function () { finish(false); }, 12000);
      });
    }

    var imgs = Array.prototype.slice.call(document.querySelectorAll('#nid_wrapper img'));
    var jobs = imgs.map(imgReady);

    // fonts (Kalpurush / Noto Sans Bengali) must be ready before print
    if (document.fonts && document.fonts.ready) {
      jobs.push(Promise.race([
        document.fonts.ready,
        new Promise(function (r) { setTimeout(r, 8000); })
      ]));
    }

    Promise.all(jobs).then(function (res) {
      var failed = res.filter(function (v) { return v === false; }).length;
      btn.disabled = false;
      btn.textContent = 'Download / Print';
      msg.textContent = failed
        ? 'কিছু ছবি লোড হয়নি (' + failed + ')। পেজটি রিফ্রেশ করে আবার চেষ্টা করুন।'
        : 'সবকিছু প্রস্তুত — এখন ডাউনলোড করতে পারেন।';
      msg.style.color = failed ? '#c00' : '#0a7d28';
    });

    btn.addEventListener('click', function () {
      if (btn.disabled) return;
      // give the layout one frame to settle, then print
      requestAnimationFrame(function () {
        setTimeout(function () { window.print(); }, 60);
      });
    });
  })();
</script>

</body></html>
