<?php
// includes/table_rows.php
// Renders ONLY the <tr> rows for the jobs register. Used two ways:
//   1. include'd directly inside index.php's <tbody> for the first page load
//   2. requested directly via fetch() as an AJAX endpoint after a save, to
//      refresh the table WITHOUT reloading or navigating the page at all.
//
// Reads the same filters index.php's filter bar uses, so a refresh always
// respects whatever the user currently has filtered.

if (!isset($pdo)) {
    require __DIR__ . '/../db.php';
}

// SECURITY FIX: this fragment is fetched directly via AJAX (see
// index.php's refreshTable()), which bypasses index.php's own
// require_login() gate entirely. Without an equivalent check here, the
// full jobs register (job numbers, client names, item names, serial
// numbers, inspection results) was readable by anyone unauthenticated who
// requested this file directly. ajax=true returns a clean 401 instead of
// an HTML redirect, so a logged-out request never dumps a login page's
// HTML into the register table body.
if (!function_exists('current_user')) { require_once __DIR__ . '/auth.php'; }
require_login(true);
if (!isset($me)) { $me = function_exists('current_user') ? current_user() : null; }
if (!function_exists('getApplicableChecklistIds')) {
    require_once __DIR__ . '/checklist_helper.php';
}

$client   = $_GET['client'] ?? '';
$category = $_GET['category'] ?? '';
$status   = $_GET['status'] ?? '';
$pendingOnly = isset($_GET['pending']) && $_GET['pending'] === '1';

// Querying tbl_jobs directly instead of the qry_jobs_master view here —
// Is_Locked lives on tbl_jobs and it's safer not to assume the view
// definition exposes it (avoids another "unknown column" surprise like
// tbl_clients.Deleted_At was). Every column used below already exists
// directly on tbl_jobs per the schema.
// Deleted_At IS NULL: excludes soft-deleted jobs (see delete_job.php /
// trash.php) — the project's strict rule is soft delete only, never a hard
// DELETE FROM, so this filter is what actually makes a "deleted" job
// disappear from the active register while the row (and every related
// checklist/photo/inspection record via its foreign keys) stays intact.
$sql = "SELECT * FROM tbl_jobs WHERE (Is_Locked = 0 OR Is_Locked IS NULL) AND Deleted_At IS NULL";
$params = [];

if (!empty($client)) {
    // Unified search: one box now matches Job No, Client Name, OR Serial No
    // together instead of Client Name only — no need to remember which
    // field a particular search term belongs to.
    $sql .= " AND (Client_Name LIKE ? OR Job_No LIKE ? OR Serial_No LIKE ?)";
    $params[] = "%$client%";
    $params[] = "%$client%";
    $params[] = "%$client%";
}
if (!empty($category)) {
    $sql .= " AND Category = ?";
    $params[] = $category;
}
if (!empty($status)) {
    $sql .= " AND Approval = ?";
    $params[] = $status;
}

$sql .= " ORDER BY ID DESC";

$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$jobs = $stmt->fetchAll(PDO::FETCH_ASSOC);

/**
 * Mirrors the exact completion check approve_job.php uses server-side —
 * both now call the same getApplicableChecklistIds() helper, so this can
 * never silently diverge from what Approve actually validates again.
 */
function jobIsReadyToApprove(PDO $pdo, array $job): bool {
    $isTraining = strcasecmp((string) $job['Category'], 'Training') === 0;

    if ($isTraining) {
        $stmtT = $pdo->prepare("SELECT Trainee_Name, Trainee_ID FROM tbl_training_records WHERE JobID = ?");
        $stmtT->execute([$job['ID']]);
        $t = $stmtT->fetch(PDO::FETCH_ASSOC);
        return !empty($t['Trainee_Name']) && !empty($t['Trainee_ID']) && !empty($job['Item_Name']);
    }

    $expectedCount = count(getApplicableChecklistIds($pdo, $job['Category'], $job['Item_Name']));

    $actualStmt = $pdo->prepare("SELECT COUNT(*) FROM tbl_job_checklists WHERE JobID = ?");
    $actualStmt->execute([$job['ID']]);
    $actualCount = (int) $actualStmt->fetchColumn();

    return $expectedCount === 0 || $actualCount >= $expectedCount;
}

if ($pendingOnly) {
    $jobs = array_values(array_filter($jobs, fn($j) => jobIsReadyToApprove($pdo, $j)));
}
?>
<?php if (count($jobs) > 0): ?>
    <?php if ($pendingOnly): ?>
        <tr class="table-warning"><td colspan="9" class="small text-center py-1"><i class="fa-solid fa-hourglass-half me-1"></i> Showing only jobs ready to approve (<?= count($jobs); ?>)</td></tr>
    <?php endif; ?>
    <?php foreach ($jobs as $j): ?>
        <tr data-job-id="<?= (int) $j['ID']; ?>">
            <td class="ps-3 fw-bold text-primary">
                <a href="javascript:void(0);" onclick='openInspectionModal(<?= (int) $j['ID']; ?>, <?= json_encode($j['Category'] ?? ''); ?>)' class="text-decoration-none fw-bold"><?= htmlspecialchars($j['Job_No']); ?></a>
            </td>
            <td><?= htmlspecialchars($j['Issue_Date'] ?? '-'); ?></td>
            <td class="fw-semibold"><?= htmlspecialchars($j['Client_Name'] ?? 'N/A'); ?></td>
            <td><span class="badge bg-secondary"><?= htmlspecialchars($j['Category'] ?? 'NDT'); ?></span></td>
            <td><?= htmlspecialchars($j['Item_Name'] ?? 'N/A'); ?></td>
            <td><code><?= htmlspecialchars($j['Serial_No'] ?? 'N/A'); ?></code></td>
            <td><?= htmlspecialchars($j['Engineer'] ?? 'Abdulla Qasim'); ?></td>
            <td>
                <?php
                    $app = strtolower($j['Approval'] ?? 'pending');
                    $badgeClass = $app === 'pass' ? 'badge-pass' : ($app === 'fail' ? 'badge-fail' : 'badge-pending');
                ?>
                <span class="badge <?= $badgeClass; ?> fw-bold">
                    <?= strtoupper(htmlspecialchars($j['Approval'] ?? 'PENDING')); ?>
                </span>
            </td>
            <td class="text-center">
                <button type="button" class="btn btn-sm btn-outline-secondary me-1" onclick='openInspectionModal(<?= (int) $j['ID']; ?>, <?= json_encode($j['Category'] ?? ''); ?>)' title="View/Edit Details">
                    <i class="fa-solid fa-eye"></i> View
                </button>
                <?php if ($me && $me['role'] === 'admin'): ?>
                    <!-- Delete = soft delete only (sets Deleted_At via
                         delete_job.php, never a hard DELETE) — moves the job
                         to the Trash (trash.php), where it can be restored.
                         Admin-only, and only ever reachable here for
                         NOT-YET-APPROVED jobs, since this whole table is
                         already filtered to Is_Locked = 0 — an approved/
                         locked certificate has no delete path at all. -->
                    <button type="button" class="btn btn-sm btn-outline-danger js-delete-job" data-job-id="<?= (int) $j['ID']; ?>" title="Move to Trash">
                        <i class="fa-solid fa-trash"></i>
                    </button>
                <?php endif; ?>
            </td>
        </tr>
    <?php endforeach; ?>
<?php else: ?>
    <tr>
        <td colspan="9" class="text-center text-muted py-4">No inspection jobs match your search parameters.</td>
    </tr>
<?php endif; ?>
