<?php
// add_job.php
// Loaded as a FRAGMENT into index.php's shared modal (see openAddJobModal()
// in index.php) — no <html>/<head><meta charset="utf-8">/<body>, matching view_appliance_job.php's
// existing pattern. POST requests return JSON instead of redirecting, so
// the browser never navigates away from index.php.

require_once 'includes/auth.php';
require_role(['admin', 'inspector'], true); // Coordinator is read-only, cannot create jobs

require_once 'db.php';
require_once 'includes/activity_log.php';

$isAjax = $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['add_job']);

// 1. Auto-generate the next Job No / Certificate No in sequence (LTG-IQ/00001)
$nextJobNo = 'LTG-IQ/00001';
try {
    $stmtSeq = $pdo->query("SELECT Job_No FROM tbl_jobs WHERE Job_No LIKE 'LTG-IQ/%' ORDER BY ID DESC LIMIT 1");
    $lastJob = $stmtSeq->fetchColumn();
    if ($lastJob) {
        $parts = explode('/', $lastJob);
        $lastNum = intval($parts[1] ?? 0);
        $nextJobNo = 'LTG-IQ/' . str_pad($lastNum + 1, 5, '0', STR_PAD_LEFT);
    }
} catch (\PDOException $e) {}

$masterItems = [];
try {
    $stmtMaster = $pdo->query("SELECT * FROM tbl_master_items ORDER BY item_name ASC");
    $masterItems = $stmtMaster->fetchAll(PDO::FETCH_ASSOC);
} catch (\PDOException $e) {}

// Trainer/Assessor and Inspector/Engineer are the same people — real
// Admin/Inspector accounts — not free text anymore.
$staffUsers = [];
try {
    $me = current_user();
    $stmtStaff = $pdo->query("SELECT UserID, Name FROM tbl_users WHERE Role IN ('admin','inspector') AND Is_Active = 1 AND Deleted_At IS NULL ORDER BY Name ASC");
    $staffUsers = $stmtStaff->fetchAll(PDO::FETCH_ASSOC);
} catch (\PDOException $e) {}

// ---------------------------------------------------------------------------
// AJAX form submission — returns JSON, never redirects.
// ---------------------------------------------------------------------------
if ($isAjax) {
    header('Content-Type: application/json');
    require_csrf();

    // Job Number is generated server-side and is NEVER accepted from the
    // client input — it's shown read-only in the form purely for display.
    // This is what makes it immutable: there is no code path where a
    // submitted value can override it.
    $jobNo       = $nextJobNo;
    $workOrderRef = trim($_POST['work_order_ref'] ?? '') ?: null;
    $clientName  = trim($_POST['client_name'] ?? '');
    $category    = $_POST['category'] ?? 'LLG';
    $itemName    = trim($_POST['item_name'] ?? '');
    $serialNo    = trim($_POST['serial_no'] ?? '');
    $issueDate   = $_POST['issue_date'] ?? date('Y-m-d');
    $expiryDate  = $_POST['expiry_date'] ?? date('Y-m-d');
    $approval    = $_POST['approval'] ?? 'Pass';
    $engineer    = trim($_POST['engineer'] ?? '') ?: 'Abdulla Qasim';
    $itemDetails = $_POST['item_details'] ?? '';
    $traineeName = trim($_POST['trainee_name'] ?? '');
    $traineeId   = trim($_POST['trainee_id'] ?? '');
    $nationality = trim($_POST['nationality'] ?? '');
    $trainingParameters = $_POST['training_parameters'] ?? '';

    if ($clientName === '' || $itemName === '') {
        echo json_encode(['status' => 'error', 'message' => 'Client Name and Item Name are required.']);
        exit;
    }

    if ($workOrderRef === null || $workOrderRef === '') {
        echo json_encode(['status' => 'error', 'message' => 'Work Order Ref is required — it links this certificate to your accounting record.']);
        exit;
    }

    if (strcasecmp($category, 'Training') === 0 && $traineeName === '') {
        echo json_encode(['status' => 'error', 'message' => 'Trainee Name is required for Training jobs.']);
        exit;
    }

    try {
        $pdo->beginTransaction();

        // Resolve or create the client (supports both picking an existing
        // client from the searchable dropdown and typing a brand new one).
        $clientId = null;
        $stmtClientFind = $pdo->prepare("SELECT ClientID FROM tbl_clients WHERE Client_Name = ? LIMIT 1");
        $stmtClientFind->execute([$clientName]);
        $clientId = $stmtClientFind->fetchColumn();

        if (!$clientId) {
            $stmtClientIns = $pdo->prepare("INSERT INTO tbl_clients (Client_Name) VALUES (?)");
            $stmtClientIns->execute([$clientName]);
            $clientId = $pdo->lastInsertId();
        }

        $sqlJob = "INSERT INTO tbl_jobs (Job_No, Work_Order_Ref, ClientID, Client_Name, Category, Item_Name, Serial_No, Issue_Date, Expiry_Date, Approval, Engineer)
                   VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
        $stmtJob = $pdo->prepare($sqlJob);
        $stmtJob->execute([$jobNo, $workOrderRef, $clientId, $clientName, $category, $itemName, $serialNo, $issueDate, $expiryDate, $approval, $engineer]);

        $newJobId = $pdo->lastInsertId();

        if (strcasecmp($category, 'Appliance') === 0 || strcasecmp($category, 'Mis') === 0) { // FIX (docx follow-up): DB category is 'Mis', not 'Misc' — this meant no tbl_appliance_inspections row (and so no item description) was ever created for a new MIS job, unlike Appliance/LLG.
            if (empty($itemDetails)) {
                $stmtTpl = $pdo->prepare("SELECT description_template FROM tbl_master_items WHERE item_name = ? LIMIT 1");
                $stmtTpl->execute([$itemName]);
                $mItem = $stmtTpl->fetch(PDO::FETCH_ASSOC);
                $itemDetails = $mItem['description_template'] ?? '';
            }

            $sqlAppliance = "INSERT INTO tbl_appliance_inspections (JobID, Serial_No, item_name_description, item_description, Approval_Status) VALUES (?, ?, ?, ?, ?)";
            $stmtAppliance = $pdo->prepare($sqlAppliance);
            $stmtAppliance->execute([$newJobId, $serialNo, $itemName, $itemDetails, $approval]);

        } elseif (strcasecmp($category, 'Training') === 0) {
            // Course Content is a snapshot of the master item's description
            // template at creation time (Item Name = Course Name, since the
            // master item selector already doubles as the course picker).
            if (empty($itemDetails)) {
                $stmtTpl = $pdo->prepare("SELECT description_template FROM tbl_master_items WHERE item_name = ? LIMIT 1");
                $stmtTpl->execute([$itemName]);
                $mItem = $stmtTpl->fetch(PDO::FETCH_ASSOC);
                $itemDetails = $mItem['description_template'] ?? '';
            }

            $sqlTraining = "INSERT INTO tbl_training_records
                             (JobID, Trainee_Name, Trainee_ID, Nationality, Course_Name, Course_Content, Training_Parameters, Issue_Date, Expiry_Date, Approval_Status)
                             VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
            $stmtTraining = $pdo->prepare($sqlTraining);
            $stmtTraining->execute([$newJobId, $traineeName, $traineeId, $nationality, $itemName, $itemDetails, $trainingParameters, $issueDate, $expiryDate, $approval]);

        } else {
            // Default LLG insertion (also covers legacy/NDT data being
            // viewed, but NDT is no longer selectable when creating new jobs)
            $sqlLlg = "INSERT INTO tbl_llg_inspections (JobID, Item_Description, Visual_Inspection, Approval_Status) VALUES (?, ?, 'Pass', ?)";
            $stmtLlg = $pdo->prepare($sqlLlg);
            $stmtLlg->execute([$newJobId, $itemDetails, $approval]);
        }

        $pdo->commit();

        logActivity($pdo, (int) $newJobId, 'created', "Category: {$category}, Item: {$itemName}");

        echo json_encode([
            'status' => 'success',
            'message' => 'Job ' . $jobNo . ' created successfully.',
            'job_id' => $newJobId,
        ]);
        exit;

    } catch (\PDOException $e) {
        $pdo->rollBack();
        error_log('add_job.php DB error: ' . $e->getMessage());
        echo json_encode(['status' => 'error', 'message' => 'A database error occurred while saving. Please try again.']);
        exit;
    }
}
?>
<div class="modal-header bg-primary text-white">
    <h5 class="modal-title"><i class="fa-solid fa-circle-plus me-2"></i> New Inspection Job</h5>
    <button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
    <div id="addJobAlert"></div>

    <form class="ajax-job-form" action="add_job.php" method="POST">
        <input type="hidden" name="add_job" value="1">
        <?php csrf_field(); ?>

        <!-- Master Equipment Selector — now searchable (was a plain <select>
             with 1000+ items, painful to scroll through). Filters the same
             data client-side as you type, no extra server round-trip. -->
        <div class="mb-4 p-3 bg-white border rounded shadow-sm position-relative">
            <label class="form-label fw-bold text-primary"><i class="fa-solid fa-database me-1"></i> Select Master Equipment / Course</label>
            <div class="input-group">
                <input type="text" id="masterItemSearch" class="form-control" placeholder="Type to search Master Bank (e.g. Shackle, Crane, Banksman...)" autocomplete="off">
                <button type="button" class="btn btn-outline-primary" id="browseMasterItemsBtn" title="Browse full list"><i class="fa-solid fa-list"></i></button>
            </div>
            <div id="masterItemSuggestions" class="list-group position-absolute w-100 shadow-sm" style="z-index: 1060; display:none; max-height: 260px; overflow-y: auto;"></div>
        </div>
        <script>
            var masterItemsData = <?= json_encode(array_map(function ($m) {
                return [
                    'item_name' => $m['item_name'],
                    'category' => $m['category'] ?? 'LLG',
                    'standard' => $m['reference_standards'] ?? '',
                    'procedure' => $m['inspection_procedure'] ?? '',
                    'template' => $m['description_template'] ?? '',
                    'period' => (int) ($m['certificate_period_months'] ?? 12),
                ];
            }, $masterItems)); ?>;
        </script>

        <!-- Reorganized (task 21) into clearly titled/bordered groups instead
             of one long undifferentiated grid, now that Item Name (task 18)
             and Required Inspection Details (task 20) are no longer shown
             here (both are already chosen/filled via the Master Equipment
             selector above, or re-entered later during inspection). Both
             fields are KEPT in the DOM (see the hidden block near the end
             of this form) since applyMasterItem(), toggleTrainingFields(),
             and the server-side POST handler above all still read/write
             them by name= — deleting them would break those, only hiding
             them from view is safe. -->
        <div class="row g-3">
            <div class="col-12">
                <div class="border rounded p-3 bg-light-subtle">
                    <div class="fw-bold text-primary small text-uppercase mb-3"><i class="fa-solid fa-hashtag me-1"></i> Job Identification</div>
                    <div class="row g-3">
                        <div class="col-md-6">
                            <label class="form-label small fw-bold">Job No / Certificate No (Auto)</label>
                            <input type="text" class="form-control bg-light font-monospace fw-bold text-primary" value="<?= htmlspecialchars($nextJobNo); ?>" readonly tabindex="-1">
                            <div class="form-text">Generated automatically. Cannot be edited, here or later.</div>
                        </div>
                        <div class="col-md-6">
                            <label class="form-label small fw-bold">Work Order Ref <span class="text-danger fw-bold">*</span></label>
                            <input type="text" name="work_order_ref" class="form-control" placeholder="e.g. WO-2026-014" required>
                            <div class="form-text">Links this certificate to your accounting/payment record. Use the same reference across several items from one site visit — each still gets its own unique Job No.</div>
                        </div>
                        <div class="col-md-6">
                            <label class="form-label small fw-bold">Issue Date</label>
                            <input type="date" id="issueDateInput" name="issue_date" class="form-control" value="<?= date('Y-m-d'); ?>">
                        </div>
                        <div class="col-md-6">
                            <label class="form-label small fw-bold">Next Inspection / Expiry Date (Auto-Calculated)</label>
                            <input type="date" id="expiryDateInput" name="expiry_date" class="form-control fw-bold" value="<?= date('Y-m-d', strtotime('+6 months')); ?>">
                            <input type="hidden" id="certificatePeriodMonths" value="6">
                        </div>
                    </div>
                </div>
            </div>

            <div class="col-12">
                <div class="border rounded p-3 bg-light-subtle">
                    <div class="fw-bold text-primary small text-uppercase mb-3"><i class="fa-solid fa-building me-1"></i> Client &amp; Category</div>
                    <div class="row g-3">
                        <div class="col-md-8 position-relative">
                            <label class="form-label small fw-bold">Client Name</label>
                            <div class="input-group">
                                <input type="text" id="clientNameInput" name="client_name" class="form-control" placeholder="Start typing to search, or browse..." autocomplete="off" required>
                                <button type="button" class="btn btn-outline-secondary" id="browseClientsBtn" title="Browse all clients"><i class="fa-solid fa-list"></i></button>
                            </div>
                            <div id="clientSuggestions" class="list-group position-absolute w-100 shadow-sm" style="z-index: 1060; display:none; max-height: 220px; overflow-y: auto;"></div>
                        </div>

                        <!-- Category is auto-set from the Master Equipment
                             selection above (or defaults to LLG) — no longer
                             a visible editable field, since letting it be
                             picked independently of the actual item just
                             invited mismatched category/item combos. Still
                             submits normally via the hidden input. -->
                        <input type="hidden" id="categoryInput" name="category" value="LLG">
                        <div class="col-md-4 d-flex align-items-end">
                            <div class="small text-muted">Category: <span id="categoryBadge" class="badge bg-secondary">LLG</span> <span class="fst-italic">(auto-set from the item selected above)</span></div>
                        </div>
                    </div>
                </div>
            </div>

            <div class="col-12">
                <div class="border rounded p-3 bg-light-subtle">
                    <div class="fw-bold text-primary small text-uppercase mb-3"><i class="fa-solid fa-clipboard-list me-1"></i> Equipment / Course Details</div>
                    <div class="row g-3">
                        <div class="col-md-6" id="serialNoField">
                            <label class="form-label small fw-bold">Serial Number / Identification</label>
                            <input type="text" name="serial_no" class="form-control font-monospace" placeholder="e.g. SN-88492">
                        </div>

                        <!-- Training-only fields — shown only when Category = Training -->
                        <div class="col-md-6 d-none" id="traineeNameField">
                            <label class="form-label small fw-bold">Trainee Name</label>
                            <input type="text" name="trainee_name" class="form-control" placeholder="Full name">
                        </div>
                        <div class="col-md-6 d-none" id="traineeIdField">
                            <label class="form-label small fw-bold">Trainee ID (Identification No.)</label>
                            <input type="text" name="trainee_id" class="form-control font-monospace" placeholder="e.g. 199595955113">
                        </div>
                        <div class="col-md-6 d-none" id="nationalityField">
                            <label class="form-label small fw-bold">Nationality</label>
                            <input type="text" name="nationality" class="form-control" placeholder="e.g. Iraqi">
                        </div>
                        <div class="col-12 d-none" id="trainingParametersField">
                            <label class="form-label small fw-bold">Training Parameters</label>
                            <textarea name="training_parameters" class="form-control" rows="3" placeholder="e.g. equipment used, assessment method, pass criteria..."></textarea>
                        </div>

                        <div class="col-md-6" id="standardField">
                            <label class="form-label small fw-bold text-muted">Reference Standard <span class="fw-normal fst-italic">(system setting — not editable per job)</span></label>
                            <input type="text" id="standardInput" name="reference_standards" class="form-control bg-light" placeholder="Auto-filled from Master Bank selection" readonly tabindex="-1">
                        </div>
                        <div class="col-md-6" id="procedureField">
                            <label class="form-label small fw-bold text-muted">Inspection Procedure <span class="fw-normal fst-italic">(system setting — not editable per job)</span></label>
                            <input type="text" id="procedureInput" name="inspection_procedure" class="form-control bg-light" placeholder="Auto-filled from Master Bank selection" readonly tabindex="-1">
                        </div>
                    </div>
                </div>
            </div>

            <div class="col-12">
                <div class="border rounded p-3 bg-light-subtle">
                    <div class="fw-bold text-primary small text-uppercase mb-3"><i class="fa-solid fa-user-check me-1"></i> Inspector &amp; Approval</div>
                    <div class="row g-3">
                        <div class="col-md-6">
                            <label class="form-label small fw-bold" id="engineerLabel">Inspector / Engineer</label>
                            <select name="engineer" class="form-select">
                                <?php foreach ($staffUsers as $u): ?>
                                    <option value="<?= htmlspecialchars($u['Name']); ?>" <?= ($me && (int) $u['UserID'] === (int) $me['id']) ? 'selected' : ''; ?>><?= htmlspecialchars($u['Name']); ?></option>
                                <?php endforeach; ?>
                            </select>
                        </div>
                        <div class="col-md-6">
                            <label class="form-label small fw-bold">Overall Status</label>
                            <select name="approval" class="form-select fw-bold text-success">
                                <option value="Pass">Pass</option>
                                <option value="Fail">Fail</option>
                                <option value="Pending">Pending</option>
                            </select>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Item Name (task 18) and Required Inspection Details (task 20)
                 are intentionally hidden from the visible layout — both are
                 already captured via the "Select Master Equipment / Course"
                 picker above and re-entered later during the actual
                 inspection, so showing them again here was redundant.
                 IMPORTANT: fields are kept in the DOM (not deleted) with
                 their original id/name attributes intact, since
                 applyMasterItem(), toggleTrainingFields(), draft
                 restore, and the server-side POST handler at the top of
                 this file all still depend on them. The `required`
                 attribute was removed from Item Name here: a hidden
                 required field cannot receive focus, which would make the
                 browser's native validation silently block submission
                 with no visible cue. It's still enforced server-side
                 (see the empty-check above). -->
            <div class="d-none">
                <label class="form-label small fw-bold">Item Name <span id="itemNameHint" class="text-muted fw-normal"></span></label>
                <input type="text" id="itemNameInput" name="item_name" class="form-control" placeholder="e.g. Telescopic Mobile Crane">
                <label class="form-label small fw-bold text-primary" id="templateLabel">Required Inspection Details (Auto-seeded from Master Template)</label>
                <textarea id="templateTextarea" name="item_details" class="form-control font-monospace" rows="5">Brand/Manufacturer :
Serial Number / ID :
Year of Manufacture :
Safe Working Load (SWL / WLL) :</textarea>
            </div>
        </div>

        <div class="d-flex justify-content-end align-items-center mt-4 pt-3 border-top">
            <button type="button" class="btn btn-secondary me-2" data-bs-dismiss="modal">Cancel</button>
            <button type="button" class="btn btn-outline-primary fw-bold me-2" id="saveDuplicateBtn"><i class="fa-solid fa-clone me-1"></i> Save &amp; Duplicate</button>
            <button type="submit" class="btn btn-primary fw-bold px-4"><i class="fa-solid fa-save me-1"></i> Save & Generate Job</button>
        </div>
    </form>
</div>

<script>
(function () {
    function calculateExpiryDate() {
        var issueDateVal = document.getElementById('issueDateInput').value;
        var monthsToAdd = parseInt(document.getElementById('certificatePeriodMonths').value) || 12;

        if (issueDateVal) {
            var d = new Date(issueDateVal);
            d.setMonth(d.getMonth() + monthsToAdd);
            d.setDate(d.getDate() - 1);
            var year = d.getFullYear();
            var month = String(d.getMonth() + 1).padStart(2, '0');
            var day = String(d.getDate()).padStart(2, '0');
            document.getElementById('expiryDateInput').value = year + '-' + month + '-' + day;
        }
    }

    document.getElementById('issueDateInput').addEventListener('change', calculateExpiryDate);

    // Applies a selected master item's data to the form — same logic as
    // before, just triggered by picking a search result instead of a
    // native <select> option.
    function applyMasterItem(item) {
        document.getElementById('itemNameInput').value = item.item_name;
        document.getElementById('categoryInput').value = item.category;
        document.getElementById('standardInput').value = item.standard;
        document.getElementById('procedureInput').value = item.procedure;

        // Category is no longer a visible field — keep the small badge
        // next to it in sync so the user still sees what got auto-set.
        var badge = document.getElementById('categoryBadge');
        if (badge) badge.textContent = item.category;

        if (item.period) document.getElementById('certificatePeriodMonths').value = item.period;
        if (item.template) document.getElementById('templateTextarea').value = item.template;

        calculateExpiryDate();
        toggleTrainingFields();
    }

    // Searchable Master Bank picker — filters masterItemsData client-side
    // as you type (no server round-trip needed, the data's already here).
    // Matches on item name OR category, so typing "Training" narrows to
    // every training course, not just exact name matches.
    var masterSearchInput = document.getElementById('masterItemSearch');
    var masterSuggestBox = document.getElementById('masterItemSuggestions');
    var browseMasterBtn = document.getElementById('browseMasterItemsBtn');

    function renderMasterMatches(matches) {
        if (!matches.length) {
            masterSuggestBox.innerHTML = '<div class="list-group-item text-muted small">No matching items.</div>';
            masterSuggestBox.style.display = 'block';
            return;
        }
        masterSuggestBox.innerHTML = matches.map(function (item, idx) {
            var safeName = item.item_name.replace(/</g, '&lt;');
            return '<button type="button" class="list-group-item list-group-item-action py-1 small" data-idx="' + idx + '">' +
                   safeName + ' <span class="text-muted">(' + item.category + ' — ' + item.period + ' Mos)</span></button>';
        }).join('');
        masterSuggestBox.dataset.matches = JSON.stringify(matches);
        masterSuggestBox.style.display = 'block';
    }

    masterSearchInput.addEventListener('input', function () {
        var q = masterSearchInput.value.trim().toLowerCase();

        if (q.length < 1) {
            masterSuggestBox.style.display = 'none';
            return;
        }

        var matches = masterItemsData.filter(function (item) {
            return item.item_name.toLowerCase().includes(q) || item.category.toLowerCase().includes(q);
        }).slice(0, 30); // cap the list so it stays fast/scrollable with 1000+ items

        renderMasterMatches(matches);
    });

    // Browse: shows the full list (capped for performance) without typing —
    // covers "let me scroll through everything" instead of only search.
    browseMasterBtn.addEventListener('click', function () {
        if (masterSuggestBox.style.display === 'block' && masterSuggestBox.dataset.browsing === '1') {
            masterSuggestBox.style.display = 'none';
            masterSuggestBox.dataset.browsing = '0';
            return;
        }
        renderMasterMatches(masterItemsData.slice(0, 200));
        masterSuggestBox.dataset.browsing = '1';
    });

    masterSuggestBox.addEventListener('click', function (e) {
        var btn = e.target.closest('button[data-idx]');
        if (!btn) return;
        var matches = JSON.parse(masterSuggestBox.dataset.matches || '[]');
        var item = matches[parseInt(btn.getAttribute('data-idx'), 10)];
        if (item) {
            masterSearchInput.value = item.item_name;
            applyMasterItem(item);
        }
        masterSuggestBox.style.display = 'none';
    });

    // BUG FIX (task 23): this handler was missing the browse-button
    // exclusion that the analogous client-search handler below already
    // has. Without it, clicking #browseMasterItemsBtn fired its own click
    // listener (which shows the box) and then the SAME click event bubbled
    // up to this document-level handler, which immediately hid the box
    // again because e.target (the button) !== masterSearchInput — net
    // effect: the Browse button looked completely unresponsive.
    document.addEventListener('click', function (e) {
        if (e.target !== masterSearchInput && e.target !== browseMasterBtn && !browseMasterBtn.contains(e.target)) {
            masterSuggestBox.style.display = 'none';
        }
    });

    calculateExpiryDate();

    // Toggle Training-specific fields (Trainee Name/ID) and relabel
    // "Item Name" to indicate it doubles as Course Name when Training is
    // selected. The Master Item selector above already serves as the
    // course picker for Training jobs.
    var categorySelect = document.getElementById('categoryInput');
    var traineeNameField = document.getElementById('traineeNameField');
    var traineeIdField = document.getElementById('traineeIdField');
    var nationalityField = document.getElementById('nationalityField');
    var trainingParametersField = document.getElementById('trainingParametersField');
    var serialNoField = document.getElementById('serialNoField');
    var standardField = document.getElementById('standardField');
    var procedureField = document.getElementById('procedureField');
    var itemNameHint = document.getElementById('itemNameHint');
    var templateLabel = document.getElementById('templateLabel');
    var engineerLabel = document.getElementById('engineerLabel');
    var traineeNameInput = traineeNameField.querySelector('input');

    function toggleTrainingFields() {
        var isTraining = categorySelect.value.toUpperCase() === 'TRAINING'; // FIX (docx item 4): case-insensitive — item.category from the DB is stored as 'TRAINING' (see save handler's strcasecmp below), but this comparison was case-sensitive, so the Trainee Name/ID fields never un-hid and the field stayed empty + unrequired client-side while the server still required it, blocking every Training save.

        // Training-only fields
        traineeNameField.classList.toggle('d-none', !isTraining);
        traineeIdField.classList.toggle('d-none', !isTraining);
        nationalityField.classList.toggle('d-none', !isTraining);
        trainingParametersField.classList.toggle('d-none', !isTraining);
        traineeNameInput.required = isTraining;

        // Fields that don't apply to Training (equipment-only: serial no,
        // reference standard, inspection procedure) — hidden per request.
        serialNoField.classList.toggle('d-none', isTraining);
        standardField.classList.toggle('d-none', isTraining);
        procedureField.classList.toggle('d-none', isTraining);

        itemNameHint.textContent = isTraining ? '(= Course Name)' : '';
        templateLabel.textContent = isTraining
            ? 'Course Description (from Master Bank)'
            : 'Required Inspection Details (Auto-seeded from Master Template)';
        engineerLabel.textContent = isTraining ? 'Trainer / Assessor' : 'Inspector / Engineer';
    }

    categorySelect.addEventListener('change', toggleTrainingFields);
    toggleTrainingFields();

    // Searchable client dropdown — queries search_clients.php as the user
    // types, shows matches, and fills the field on click. Typing a name
    // that doesn't match anything is fine too: add_job.php creates a new
    // client record automatically on save.
    var clientInput = document.getElementById('clientNameInput');
    var suggestBox = document.getElementById('clientSuggestions');
    var browseClientsBtn = document.getElementById('browseClientsBtn');
    var debounceTimer = null;

    function renderClientMatches(clients) {
        if (!clients.length) {
            suggestBox.innerHTML = '<div class="list-group-item text-muted small">No clients found.</div>';
            suggestBox.style.display = 'block';
            return;
        }
        suggestBox.innerHTML = clients.map(function (c) {
            return '<button type="button" class="list-group-item list-group-item-action py-1 small">' +
                   c.Client_Name.replace(/</g, '&lt;') + '</button>';
        }).join('');
        suggestBox.style.display = 'block';
    }

    clientInput.addEventListener('input', function () {
        var q = clientInput.value.trim();
        clearTimeout(debounceTimer);

        if (q.length < 2) {
            suggestBox.style.display = 'none';
            return;
        }

        debounceTimer = setTimeout(function () {
            fetch('search_clients.php?q=' + encodeURIComponent(q))
                .then(function (r) { return r.json(); })
                .then(renderClientMatches);
        }, 200);
    });

    // Browse: lists all clients (not just search results) — covers "let
    // me scroll through the list" instead of only typing to search.
    browseClientsBtn.addEventListener('click', function () {
        if (suggestBox.style.display === 'block' && suggestBox.dataset.browsing === '1') {
            suggestBox.style.display = 'none';
            suggestBox.dataset.browsing = '0';
            return;
        }
        fetch('search_clients.php?browse=1')
            .then(function (r) { return r.json(); })
            .then(function (clients) {
                renderClientMatches(clients);
                suggestBox.dataset.browsing = '1';
            });
    });

    suggestBox.addEventListener('click', function (e) {
        if (e.target.tagName === 'BUTTON') {
            clientInput.value = e.target.textContent;
            suggestBox.style.display = 'none';
        }
    });

    document.addEventListener('click', function (e) {
        if (e.target !== clientInput && e.target !== browseClientsBtn) suggestBox.style.display = 'none';
    });

    // ---------------------------------------------------------------
    // Autosave — protects against losing a half-filled form if the tab
    // closes, the network drops, or the browser crashes mid-entry. Saves
    // to localStorage only (never sent anywhere), debounced so it doesn't
    // run on every keystroke.
    // ---------------------------------------------------------------
    var DRAFT_KEY = 'liftek_draft_add_job';
    var form = document.querySelector('.ajax-job-form');
    var draftFieldNames = ['client_name', 'category', 'item_name', 'serial_no', 'reference_standards',
        'inspection_procedure', 'item_details', 'engineer', 'work_order_ref', 'issue_date', 'expiry_date',
        'trainee_name', 'trainee_id', 'nationality', 'training_parameters', 'approval'];

    function collectDraft() {
        var data = {};
        draftFieldNames.forEach(function (name) {
            var el = form.querySelector('[name="' + name + '"]');
            if (el) data[name] = el.value;
        });
        return data;
    }

    function saveDraft() {
        try {
            localStorage.setItem(DRAFT_KEY, JSON.stringify({ savedAt: new Date().toISOString(), data: collectDraft() }));
        } catch (e) {}
    }

    function clearDraft() {
        try { localStorage.removeItem(DRAFT_KEY); } catch (e) {}
    }

    function restoreDraft(data) {
        Object.keys(data).forEach(function (name) {
            var el = form.querySelector('[name="' + name + '"]');
            if (el && data[name]) el.value = data[name];
        });

        // BUG FIX (task 19): the loop above only syncs elements that have a
        // matching name="" attribute — but item_name/category are also
        // mirrored into two VISIBLE display-only elements that have no
        // name attribute of their own: the search box text
        // (#masterItemSearch) and the "Category: X" badge. Without this,
        // the underlying form values were technically restored correctly,
        // but the two most prominent things a user actually looks at
        // appeared unchanged — making Restore look like it silently did
        // nothing.
        if (data['item_name']) {
            masterSearchInput.value = data['item_name'];
        }
        var badge = document.getElementById('categoryBadge');
        if (badge) {
            badge.textContent = data['category'] || 'LLG';
        }

        toggleTrainingFields();
    }

    // Offer to restore an existing draft, if one exists and has real content.
    try {
        var existingRaw = localStorage.getItem(DRAFT_KEY);
        if (existingRaw) {
            var existing = JSON.parse(existingRaw);
            var hasContent = Object.values(existing.data || {}).some(function (v) { return v && v.trim(); });
            if (hasContent) {
                var savedTime = new Date(existing.savedAt).toLocaleTimeString();
                var bannerHtml = '<div class="alert alert-warning d-flex justify-content-between align-items-center py-2 mb-3" id="draftBanner">' +
                    '<span><i class="fa-solid fa-clock-rotate-left me-1"></i> Unsaved draft found from ' + savedTime + '.</span>' +
                    '<span><button type="button" class="btn btn-sm btn-warning me-2" id="restoreDraftBtn">Restore</button>' +
                    '<button type="button" class="btn btn-sm btn-outline-secondary" id="discardDraftBtn">Discard</button></span></div>';
                form.insertAdjacentHTML('beforebegin', bannerHtml);
                document.getElementById('restoreDraftBtn').addEventListener('click', function () {
                    restoreDraft(existing.data);
                    document.getElementById('draftBanner').remove();
                });
                document.getElementById('discardDraftBtn').addEventListener('click', function () {
                    clearDraft();
                    document.getElementById('draftBanner').remove();
                });
            }
        }
    } catch (e) {}

    var autosaveTimer = null;
    form.addEventListener('input', function () {
        clearTimeout(autosaveTimer);
        autosaveTimer = setTimeout(saveDraft, 1000);
    });

    // Optimistic clear on submit — even if the server-side save later
    // fails validation, re-filling is a minor inconvenience versus
    // keeping a stale draft prompt showing up on every future visit.
    form.addEventListener('submit', clearDraft);

    // ---------------------------------------------------------------
    // "Save & Duplicate" (task 22) — saves the current form exactly like
    // a normal submit, then re-opens a fresh "New Inspection Job" form
    // pre-filled with the same data. Serial Number is explicitly blanked
    // on the copy: a duplicate MUST get its own unique serial/ID, never
    // silently inherit the original item's.
    // ---------------------------------------------------------------
    var saveDuplicateBtn = document.getElementById('saveDuplicateBtn');
    if (saveDuplicateBtn) {
        saveDuplicateBtn.addEventListener('click', function () {
            // Same native required-field validation a real submit would
            // trigger (Client Name, Work Order Ref, Trainee Name when
            // Training) — this button bypasses the form's own submit
            // event, so it must check this itself.
            if (!form.reportValidity()) return;

            var prefill = collectDraft();
            prefill.serial_no = '';

            var formData = new FormData(form);
            saveDuplicateBtn.disabled = true;

            fetch(form.getAttribute('action'), {
                method: 'POST',
                body: formData
            })
            .then(function (response) {
                if (response.status === 401) {
                    window.location.href = 'login.php';
                    return Promise.reject(new Error('Session expired.'));
                }
                return response.text().then(function (text) {
                    try { return JSON.parse(text); }
                    catch (e) { throw new Error('Server response error: ' + text.substring(0, 200)); }
                });
            })
            .then(function (data) {
                if (data.status === 'success') {
                    if (typeof showToast === 'function') showToast(data.message || 'Saved successfully.', false);
                    if (typeof refreshTable === 'function') refreshTable(data.job_id);
                    clearDraft();
                    // Reopens THIS SAME form fresh (still inside the shared
                    // modal — no new page/tab) with prefill data handed off
                    // via window.__pendingAddJobPrefill (see index.php's
                    // openAddJobModal()), instead of a polling loop.
                    if (typeof window.openAddJobModal === 'function') {
                        window.openAddJobModal(prefill);
                    }
                } else {
                    if (typeof showToast === 'function') showToast(data.message || 'Save failed.', true);
                    saveDuplicateBtn.disabled = false;
                }
            })
            .catch(function (err) {
                if (typeof showToast === 'function') showToast(err.message, true);
                console.error(err);
                saveDuplicateBtn.disabled = false;
            });
        });
    }

    // Consume a pending prefill left by a "Save & Duplicate" reopen. This
    // whole script re-executes fresh every time this fragment is
    // (re)injected via injectHtmlWithScripts(), so this line runs
    // synchronously right after the new blank form lands in the DOM.
    if (window.__pendingAddJobPrefill) {
        var prefillData = window.__pendingAddJobPrefill;
        window.__pendingAddJobPrefill = null;
        restoreDraft(prefillData);
    }
})();
</script>
