<?php
$outstandingReportsMode = trim((string)($_REQUEST['mode'] ?? ''));

if (in_array($outstandingReportsMode, ['pdf', 'stats'], true) && (!isset($GLOBALS['con']) || !($GLOBALS['con'] instanceof mysqli))) {
    $tenantSegment = trim(str_replace('\\', '/', (string)($_REQUEST['tenant'] ?? '')), '/');
    if ($tenantSegment === '' || strpos($tenantSegment, '..') !== false || !preg_match('/\A[A-Za-z0-9][A-Za-z0-9._-]{0,190}\z/', $tenantSegment)) {
        http_response_code(400);
        echo 'Invalid tenant';
        exit;
    }

    $configCandidates = [
        __DIR__ . '/../../../' . $tenantSegment . '/config.php',
        __DIR__ . '/../../../../' . $tenantSegment . '/config.php',
    ];

    $loadedConfig = false;
    foreach ($configCandidates as $configPath) {
        if (!is_file($configPath)) {
            continue;
        }

        $previousCwd = getcwd();
        chdir(dirname($configPath));
        require_once $configPath;
        if ($previousCwd !== false) {
            chdir($previousCwd);
        }
        $loadedConfig = true;
        break;
    }

    if (!$loadedConfig) {
        http_response_code(400);
        echo 'Tenant config not found';
        exit;
    }
}

$con = $GLOBALS['con'] ?? null;
if (!$con instanceof mysqli) {
    http_response_code(500);
    echo 'Database connection not available';
    exit;
}

$con->set_charset('utf8mb4');

if (!function_exists('outstandingReportsText')) {
    function outstandingReportsText($value): string
    {
        return htmlspecialchars(trim((string)($value ?? '')), ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
    }
}

if (!function_exists('outstandingReportsDisplay')) {
    function outstandingReportsDisplay($value, string $fallback = '-'): string
    {
        $value = trim((string)($value ?? ''));
        return $value !== '' ? $value : $fallback;
    }
}

if (!function_exists('outstandingReportsColumnExists')) {
    function outstandingReportsColumnExists(mysqli $con, string $table, string $column): bool
    {
        $table = preg_replace('/[^A-Za-z0-9_]/', '', $table);
        $column = preg_replace('/[^A-Za-z0-9_]/', '', $column);
        if ($table === '' || $column === '') {
            return false;
        }

        $stmt = $con->prepare("SELECT `{$column}` FROM `{$table}` LIMIT 1");
        if (!$stmt) {
            return false;
        }

        $stmt->execute();
        $stmt->close();

        return true;
    }
}

if ($outstandingReportsMode === 'stats') {
    header('Content-Type: application/json; charset=utf-8');

    $clientnumber = filter_var($_REQUEST['clientnumber'] ?? 0, FILTER_VALIDATE_INT);
    $clientnumber = $clientnumber !== false ? (int)$clientnumber : 0;
    if ($clientnumber < 1) {
        echo json_encode([
            'success' => false,
            'message' => 'Invalid client',
            'totalItems' => 0,
            'totalSubsites' => 0,
            'descriptions' => [],
        ]);
        exit;
    }

    $hascurrdate = outstandingReportsColumnExists($con, 'itemdetails', 'currdate');
    $currdateWhere = $hascurrdate
        ? " AND (a.`currdate` IS NULL OR a.`currdate` = '' OR a.`currdate` = '0' OR a.`currdate` = 0)"
        : '';

    $sql = "
        SELECT
            a.`desc`,
            a.`subloc`,
            b.`locname`
        FROM `itemdetails` a
        LEFT JOIN `locations` b
            ON b.`clientnumber` = a.`clientnumber`
           AND b.`locnumber` = a.`locnumber`
        LEFT JOIN `reportitems` r
            ON r.`clientnumber` = a.`clientnumber`
           AND r.`itemnumber` = a.`itemnumber`
        WHERE a.`clientnumber` = ?
          AND a.`statuslive` = 1
          AND r.`repitem` IS NULL
          {$currdateWhere}
        ORDER BY a.`desc` ASC
    ";

    $stmt = $con->prepare($sql);
    if (!$stmt) {
        echo json_encode([
            'success' => false,
            'message' => 'Unable to load outstanding stats',
            'totalItems' => 0,
            'totalSubsites' => 0,
            'descriptions' => [],
        ]);
        exit;
    }

    $stmt->bind_param('i', $clientnumber);
    $stmt->execute();
    $result = $stmt->get_result();

    $totalItems = 0;
    $subsites = [];
    $descriptions = [];
    while ($row = $result->fetch_assoc()) {
        $location = outstandingReportsDisplay($row['locname'] ?? '', 'Unassigned location');
        $subloc = outstandingReportsDisplay($row['subloc'] ?? '', 'No sub-location');
        $description = outstandingReportsDisplay($row['desc'] ?? '', 'No description');

        $subsites[$location . "\n" . $subloc] = true;
        $descriptions[$description] = ($descriptions[$description] ?? 0) + 1;
        $totalItems++;
    }
    $stmt->close();

    ksort($descriptions, SORT_NATURAL | SORT_FLAG_CASE);

    $descriptionRows = [];
    foreach ($descriptions as $description => $count) {
        $descriptionRows[] = [
            'description' => $description,
            'count' => $count,
        ];
    }

    echo json_encode([
        'success' => true,
        'message' => '',
        'totalItems' => $totalItems,
        'totalSubsites' => count($subsites),
        'descriptions' => $descriptionRows,
    ]);
    exit;
}

if ($outstandingReportsMode === 'pdf') {
    require_once __DIR__ . '/../../packages/mpd/vendor/autoload.php';

    $clientnumber = filter_var($_REQUEST['clientnumber'] ?? 0, FILTER_VALIDATE_INT);
    $clientnumber = $clientnumber !== false ? (int)$clientnumber : 0;
    if ($clientnumber < 1) {
        http_response_code(400);
        echo 'Invalid client';
        exit;
    }

    $stmt = $con->prepare("SELECT `clientname` FROM `clientdetails` WHERE `clientnumber` = ? LIMIT 1");
    if (!$stmt) {
        http_response_code(500);
        echo 'Unable to load client';
        exit;
    }
    $stmt->bind_param('i', $clientnumber);
    $stmt->execute();
    $clientResult = $stmt->get_result();
    $clientRow = $clientResult ? $clientResult->fetch_assoc() : null;
    $stmt->close();

    if (!$clientRow) {
        http_response_code(404);
        echo 'Client not found';
        exit;
    }

    $clientName = (string)($clientRow['clientname'] ?? '');
    $hascurrdate = outstandingReportsColumnExists($con, 'itemdetails', 'currdate');
    $currdateWhere = $hascurrdate
        ? " AND (a.`currdate` IS NULL OR a.`currdate` = '' OR a.`currdate` = '0' OR a.`currdate` = 0)"
        : '';

    $sql = "
        SELECT
            a.`itemnumber`,
            a.`desc`,
            a.`plantnumber`,
            a.`serialnumber`,
            a.`subloc`,
            b.`locname`
        FROM `itemdetails` a
        LEFT JOIN `locations` b
            ON b.`clientnumber` = a.`clientnumber`
           AND b.`locnumber` = a.`locnumber`
        LEFT JOIN `reportitems` r
            ON r.`clientnumber` = a.`clientnumber`
           AND r.`itemnumber` = a.`itemnumber`
        WHERE a.`clientnumber` = ?
          AND a.`statuslive` = 1
          AND r.`repitem` IS NULL
          {$currdateWhere}
        ORDER BY
            COALESCE(NULLIF(b.`locname`, ''), 'Unassigned location') ASC,
            COALESCE(NULLIF(a.`subloc`, ''), 'No sub-location') ASC,
            a.`desc` ASC,
            a.`plantnumber` ASC,
            a.`serialnumber` ASC
    ";

    $stmt = $con->prepare($sql);
    if (!$stmt) {
        http_response_code(500);
        echo 'Unable to load unserviced items';
        exit;
    }
    $stmt->bind_param('i', $clientnumber);
    $stmt->execute();
    $result = $stmt->get_result();

    $groups = [];
    $totalItems = 0;
    while ($row = $result->fetch_assoc()) {
        $location = outstandingReportsDisplay($row['locname'] ?? '', 'Unassigned location');
        $subloc = outstandingReportsDisplay($row['subloc'] ?? '', 'No sub-location');
        $groupKey = $location . "\n" . $subloc;

        if (!isset($groups[$groupKey])) {
            $groups[$groupKey] = [
                'location' => $location,
                'subloc' => $subloc,
                'items' => [],
            ];
        }

        $groups[$groupKey]['items'][] = $row;
        $totalItems++;
    }
    $stmt->close();

    $reportDate = date('d-m-Y');
    $title = 'Unserviced Items';

    $css = '
body {
    color: #25313f;
    font-family: DejaVu Sans, Arial, sans-serif;
    font-size: 10pt;
}
.report-title {
    border-bottom: 2px solid #0055A6;
    margin-bottom: 14px;
    padding-bottom: 10px;
}
.report-title h1 {
    color: #0055A6;
    font-size: 20pt;
    margin: 0 0 4px 0;
}
.meta {
    border-collapse: collapse;
    margin-top: 8px;
    width: 100%;
}
.meta td {
    border: 1px solid #d9e1ec;
    padding: 7px 9px;
}
.meta-label {
    background: #eef3f8;
    color: #4a5b70;
    font-weight: bold;
    width: 22%;
}
.summary-heading {
    color: #2d4661;
    font-size: 13pt;
    margin: 16px 0 6px 0;
}
.subloc-summary {
    border-collapse: collapse;
    margin-bottom: 14px;
    width: 100%;
}
.subloc-summary th {
    background: #eef3f8;
    border: 1px solid #cfd9e6;
    color: #2d4661;
    font-size: 8.5pt;
    padding: 6px;
    text-align: left;
}
.subloc-summary td {
    border: 1px solid #d9e1ec;
    padding: 6px;
}
.group {
    margin-top: 14px;
}
.group-heading {
    background: #25313f;
    color: #ffffff;
    font-size: 11pt;
    font-weight: bold;
    padding: 7px 9px;
}
.group-location {
    color: #d7e5f4;
    font-size: 8.5pt;
    font-weight: normal;
}
table.items {
    border-collapse: collapse;
    width: 100%;
}
table.items th {
    background: #eef3f8;
    border: 1px solid #cfd9e6;
    color: #2d4661;
    font-size: 8.5pt;
    padding: 6px;
    text-align: left;
}
table.items td {
    border: 1px solid #d9e1ec;
    padding: 6px;
    vertical-align: top;
}
.empty {
    border: 1px solid #d9e1ec;
    color: #4a5b70;
    margin-top: 18px;
    padding: 14px;
    text-align: center;
}
';

    $html = '<div class="report-title">'
        . '<h1>' . outstandingReportsText($title) . '</h1>'
        . '<table class="meta">'
        . '<tr><td class="meta-label">Client</td><td>' . outstandingReportsText($clientName) . '</td></tr>'
        . '<tr><td class="meta-label">Date</td><td>' . outstandingReportsText($reportDate) . '</td></tr>'
        . '<tr><td class="meta-label">Total items</td><td>' . (int)$totalItems . '</td></tr>'
        . '</table>'
        . '</div>';

    if ($totalItems < 1) {
        $html .= '<div class="empty">No active items were found without a recorded inspection.</div>';
    } else {
        $html .= '<h2 class="summary-heading">Sub-locations</h2>'
            . '<table class="subloc-summary">'
            . '<thead><tr>'
            . '<th width="45%">Sub-location</th>'
            . '<th width="40%">Location</th>'
            . '<th width="15%">Items</th>'
            . '</tr></thead><tbody>';

        foreach ($groups as $group) {
            $html .= '<tr>'
                . '<td>' . outstandingReportsText($group['subloc']) . '</td>'
                . '<td>' . outstandingReportsText($group['location']) . '</td>'
                . '<td>' . count($group['items']) . '</td>'
                . '</tr>';
        }

        $html .= '</tbody></table>';

        foreach ($groups as $group) {
            $html .= '<div class="group">'
                . '<div class="group-heading">'
                . outstandingReportsText($group['subloc'])
                . ' <span class="group-location">(' . outstandingReportsText($group['location']) . ' - ' . count($group['items']) . ' items)</span>'
                . '</div>'
                . '<table class="items">'
                . '<thead><tr>'
                . '<th width="50%">Description</th>'
                . '<th width="25%">Plant number</th>'
                . '<th width="25%">Serial number</th>'
                . '</tr></thead><tbody>';

            foreach ($group['items'] as $item) {
                $html .= '<tr>'
                    . '<td>' . outstandingReportsText(outstandingReportsDisplay($item['desc'] ?? '')) . '</td>'
                    . '<td>' . outstandingReportsText(outstandingReportsDisplay($item['plantnumber'] ?? '')) . '</td>'
                    . '<td>' . outstandingReportsText(outstandingReportsDisplay($item['serialnumber'] ?? '')) . '</td>'
                    . '</tr>';
            }

            $html .= '</tbody></table></div>';
        }
    }

    $mpdf = new \Mpdf\Mpdf([
        'mode' => 'utf-8',
        'format' => 'A4',
        'margin_left' => 10,
        'margin_right' => 10,
        'margin_top' => 12,
        'margin_bottom' => 12,
    ]);
    $mpdf->SetTitle($title . ' - ' . $clientName);
    $mpdf->SetHTMLFooter('<div style="font-size:8pt;color:#667085;text-align:right;">Page {PAGENO} of {nbpg}</div>');
    $mpdf->WriteHTML($css, \Mpdf\HTMLParserMode::HEADER_CSS);
    $mpdf->WriteHTML($html);

    while (ob_get_level() > 0) {
        @ob_end_clean();
    }

    $safeClient = preg_replace('/[^A-Za-z0-9_-]+/', '_', trim($clientName));
    $filename = 'unserviced-items-' . ($safeClient !== '' ? $safeClient : 'client-' . $clientnumber) . '-' . date('Ymd') . '.pdf';
    $mpdf->Output($filename, (($_REQUEST['download'] ?? '') === '1') ? 'D' : 'I');
    exit;
}

$clients = [];
$stmt = $con->prepare("
    SELECT `clientnumber`, `clientname`
    FROM `clientdetails`
    WHERE `statuslive` = 1
    ORDER BY `clientname` ASC
");
if ($stmt) {
    $stmt->execute();
    $result = $stmt->get_result();
    while ($row = $result->fetch_assoc()) {
        $clients[] = $row;
    }
    $stmt->close();
}
?>

<style>
.outstanding-tool-panel {
    background: #f8fafc;
    border: 1px solid #d9e1ec;
    border-left: 4px solid #0055A6;
    border-radius: 6px;
    margin-bottom: 1rem;
    padding: 1rem;
}
.outstanding-tool-title {
    color: #2d4661;
    font-weight: 600;
    margin: 0;
}
.outstanding-tool-actions {
    align-items: end;
    background: #ffffff;
    border: 1px solid #dde4ee;
    border-radius: 6px;
    display: grid;
    gap: .75rem;
    grid-template-columns: minmax(240px, 1fr) auto;
    margin-top: .8rem;
    padding: .75rem;
}
.outstanding-tool-actions .select-wrapper {
    width: 100%;
}
.outstanding-tool-empty {
    border: 1px solid #d9e1ec;
    border-radius: 6px;
    color: #4a5b70;
    padding: 1rem;
    text-align: center;
}
.outstanding-stats-panel {
    background: #ffffff;
    border: 1px solid #dde4ee;
    border-radius: 6px;
    display: none;
    margin-top: .8rem;
    padding: .75rem;
}
.outstanding-stats-panel.is-visible {
    display: block;
}
.outstanding-stat-grid {
    display: grid;
    gap: .75rem;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    margin-bottom: .75rem;
}
.outstanding-stat-box {
    background: #f8fafc;
    border: 1px solid #d9e1ec;
    border-radius: 6px;
    padding: .7rem;
}
.outstanding-stat-label {
    color: #667085;
    font-size: .82rem;
}
.outstanding-stat-value {
    color: #0055A6;
    font-size: 1.35rem;
    font-weight: 700;
    line-height: 1.2;
}
.outstanding-description-table {
    margin-bottom: 0;
}
.outstanding-generate-status {
    background: #eef3f8;
    border: 1px solid #d9e1ec;
    border-radius: 6px;
    color: #2d4661;
    display: none;
    margin-top: .75rem;
    padding: .75rem;
}
.outstanding-generate-status.is-visible {
    align-items: center;
    display: flex;
    gap: .55rem;
}
@media (max-width: 767.98px) {
    .outstanding-tool-actions {
        grid-template-columns: 1fr;
    }
    .outstanding-tool-actions .btn {
        width: 100%;
    }
}
</style>

<div class="row">
    <div class="col-12 col-xl-9">
        <div class="outstanding-tool-panel">
            <div class="d-flex align-items-start justify-content-between flex-wrap gap-2">
                <div>
                    <p class="outstanding-tool-title">
                        <i class="fad fa-file-pdf me-1"></i> Unserviced Items Report
                    </p>
                    <div class="text-muted small">Select a client and generate a PDF of active items with no recorded inspection date.</div>
                </div>
            </div>

            <div class="note note-secondary mt-3 mb-0">
                The PDF includes the client name, generated date, total item count, a sub-location summary, and grouped item breakdowns with description, plant number, and serial number.
            </div>

            <?php if (empty($clients)) { ?>
                <div class="outstanding-tool-empty mt-3">No active clients are available.</div>
            <?php } else { ?>
                <div class="outstanding-tool-actions">
                    <div>
                        <label for="outstandingReportsClient" class="form-label mb-1">Client</label>
                        <div>
                            <select id="outstandingReportsClient" class="form-control" data-mdb-select-init data-mdb-filter="true">
                                <option value="" selected disabled>Select a client</option>
                                <?php foreach ($clients as $client) { ?>
                                    <option value="<?= (int)$client['clientnumber'] ?>"><?= outstandingReportsText($client['clientname'] ?? '') ?></option>
                                <?php } ?>
                            </select>
                        </div>
                    </div>
                    <div>
                        <button type="button" id="outstandingReportsGenerate" class="btn btn-info text-light" disabled>
                            <i class="fad fa-file-pdf me-1"></i> Generate PDF
                        </button>
                    </div>
                </div>
                <div id="outstandingReportsGenerateStatus" class="outstanding-generate-status" aria-live="polite">
                    <i class="fad fa-spinner fa-spin"></i>
                    <span>Generating PDF...</span>
                </div>
                <div id="outstandingReportsStats" class="outstanding-stats-panel" aria-live="polite"></div>
            <?php } ?>
        </div>
    </div>
</div>

<script>
document.getElementById('navBox').innerHTML =
    '<li class="breadcrumb-item">Tools <i class="fad fa-angle-double-right mx-2 mt-1" aria-hidden="true"></i></li><li class="breadcrumb-item active">Unserviced Items Report</li>';

document.addEventListener('DOMContentLoaded', function() {
    const clientSelect = document.getElementById('outstandingReportsClient');
    const generateButton = document.getElementById('outstandingReportsGenerate');
    const generateStatus = document.getElementById('outstandingReportsGenerateStatus');
    const statsPanel = document.getElementById('outstandingReportsStats');
    let statsRequestId = 0;
    let isGenerating = false;
    let pendingPdfUrl = '';

    if (!clientSelect || !generateButton) {
        return;
    }

    function selectedClientnumber() {
        return String(clientSelect.value || '').trim();
    }

    function isTabletOrMobile() {
        return window.matchMedia('(max-width: 991.98px)').matches;
    }

    function updateGenerateState() {
        generateButton.disabled = isGenerating || selectedClientnumber() === '';
    }

    function escapeHtml(value) {
        return String(value ?? '')
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#039;');
    }

    function renderStatsLoading() {
        if (!statsPanel) return;
        statsPanel.classList.add('is-visible');
        statsPanel.innerHTML = '<div class="text-muted small"><i class="fad fa-spinner fa-spin me-1"></i> Loading outstanding item stats...</div>';
    }

    function renderStats(data) {
        if (!statsPanel) return;

        if (!data || data.success !== true) {
            statsPanel.classList.add('is-visible');
            statsPanel.innerHTML = '<div class="alert alert-warning mb-0">Unable to load the outstanding item stats.</div>';
            return;
        }

        const rows = Array.isArray(data.descriptions) ? data.descriptions : [];
        const descriptionRows = rows.length
            ? rows.map((row) => `
                <tr>
                    <td>${escapeHtml(row.description || 'No description')}</td>
                    <td class="text-end">${Number(row.count || 0)}</td>
                </tr>
            `).join('')
            : '<tr><td colspan="2" class="text-center text-muted">No outstanding descriptions.</td></tr>';

        statsPanel.classList.add('is-visible');
        statsPanel.innerHTML = `
            <div class="outstanding-stat-grid">
                <div class="outstanding-stat-box">
                    <div class="outstanding-stat-label">Outstanding items</div>
                    <div class="outstanding-stat-value">${Number(data.totalItems || 0)}</div>
                </div>
                <div class="outstanding-stat-box">
                    <div class="outstanding-stat-label">Sub-locations with outstanding items</div>
                    <div class="outstanding-stat-value">${Number(data.totalSubsites || 0)}</div>
                </div>
            </div>
            <div class="table-responsive">
                <table class="table table-sm table-striped table-bordered outstanding-description-table">
                    <thead class="table-dark">
                        <tr>
                            <th>Description</th>
                            <th class="text-end" width="120">Items</th>
                        </tr>
                    </thead>
                    <tbody>${descriptionRows}</tbody>
                </table>
            </div>
        `;
    }

    function loadStats() {
        const clientnumber = selectedClientnumber();
        if (clientnumber === '') {
            if (statsPanel) {
                statsPanel.classList.remove('is-visible');
                statsPanel.innerHTML = '';
            }
            return;
        }

        const requestId = ++statsRequestId;
        renderStatsLoading();

        fetch(ROOT_URL + '/includes/tools/outstanding_reports.php?mode=stats&clientnumber=' +
            encodeURIComponent(clientnumber) + '&tenant=' + encodeURIComponent(TENANT_URL))
            .then((response) => response.json())
            .then((data) => {
                if (requestId === statsRequestId) {
                    renderStats(data);
                }
            })
            .catch(() => {
                if (requestId === statsRequestId) {
                    renderStats(null);
                }
            });
    }

    function handleClientChange() {
        updateGenerateState();
        loadStats();
    }

    function setGenerating(active) {
        isGenerating = active;
        updateGenerateState();

        if (generateStatus) {
            if (active) {
                generateStatus.classList.add('is-visible');
                generateStatus.innerHTML = '<i class="fad fa-spinner fa-spin"></i><span>Generating PDF...</span>';
            } else if (!pendingPdfUrl) {
                generateStatus.classList.remove('is-visible');
            }
        }

        generateButton.innerHTML = active
            ? '<i class="fad fa-spinner fa-spin me-1"></i> Generating PDF'
            : '<i class="fad fa-file-pdf me-1"></i> Generate PDF';
    }

    function showGeneratedPdfAction(pdfUrl, filename) {
        if (!generateStatus) return;

        pendingPdfUrl = pdfUrl;
        generateStatus.classList.add('is-visible');
        generateStatus.innerHTML = `
            <i class="fad fa-check-circle text-success"></i>
            <span>PDF generated.</span>
            <button type="button" class="btn btn-success btn-sm ms-auto" id="outstandingReportsOpenPdf">
                <i class="fad fa-external-link me-1"></i> Open PDF
            </button>
            <button type="button" class="btn btn-outline-secondary btn-sm" id="outstandingReportsDownloadPdf">
                <i class="fad fa-cloud-download-alt me-1"></i> Download
            </button>
        `;

        const openButton = document.getElementById('outstandingReportsOpenPdf');
        const downloadButton = document.getElementById('outstandingReportsDownloadPdf');

        if (openButton) {
            openButton.addEventListener('click', function() {
                window.open(pendingPdfUrl, '_blank', 'noopener');
            });
        }

        if (downloadButton) {
            downloadButton.addEventListener('click', function() {
                const link = document.createElement('a');
                link.href = pendingPdfUrl;
                link.download = filename || 'unserviced-items.pdf';
                document.body.appendChild(link);
                link.click();
                link.remove();
            });
        }
    }

    function filenameFromDisposition(disposition) {
        const match = String(disposition || '').match(/filename\*?=(?:UTF-8''|")?([^";]+)/i);
        return match ? decodeURIComponent(match[1].replace(/"/g, '').trim()) : 'unserviced-items.pdf';
    }

    function downloadPdfBlob(blob, filename) {
        const blobUrl = URL.createObjectURL(blob);
        const link = document.createElement('a');
        link.href = blobUrl;
        link.download = filename || 'unserviced-items.pdf';
        document.body.appendChild(link);
        link.click();
        link.remove();
        setTimeout(() => URL.revokeObjectURL(blobUrl), 30000);
    }

    function openPdfBlobViewer(blob, filename) {
        const pdfBlob = blob.type === 'application/pdf' ? blob : new Blob([blob], { type: 'application/pdf' });
        const pdfUrl = URL.createObjectURL(pdfBlob);
        const title = escapeHtml(filename || 'Unserviced Items');
        const viewer = window.open('', '_blank');

        if (!viewer) {
            showGeneratedPdfAction(pdfUrl, filename);
            return;
        }

        viewer.document.open();
        viewer.document.write(`<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>${title}</title>
    <style>
        html, body { height: 100%; margin: 0; }
        iframe { border: 0; height: 100%; width: 100%; }
    </style>
</head>
<body>
    <iframe src="${pdfUrl}" title="${title}"></iframe>
</body>
</html>`);
        viewer.document.close();
        setTimeout(() => URL.revokeObjectURL(pdfUrl), 60000);
    }

    clientSelect.addEventListener('change', handleClientChange);
    clientSelect.addEventListener('input', handleClientChange);
    updateGenerateState();

    generateButton.addEventListener('click', function() {
        const clientnumber = selectedClientnumber();
        if (clientnumber === '') {
            showResponse('warning', 'Please select a client first');
            return;
        }

        if (isGenerating) {
            return;
        }

        const download = isTabletOrMobile() ? '1' : '0';
        const url = ROOT_URL + '/includes/tools/outstanding_reports.php?mode=pdf&clientnumber=' +
            encodeURIComponent(clientnumber) + '&download=' + download + '&tenant=' + encodeURIComponent(TENANT_URL);

        setGenerating(true);
        if (pendingPdfUrl) {
            URL.revokeObjectURL(pendingPdfUrl);
            pendingPdfUrl = '';
        }

        fetch(url)
            .then((response) => {
                if (!response.ok) {
                    throw new Error('PDF generation failed');
                }

                const filename = filenameFromDisposition(response.headers.get('Content-Disposition'));
                return response.blob().then((blob) => ({ blob, filename }));
            })
            .then(({ blob, filename }) => {
                if (download === '1') {
                    downloadPdfBlob(blob, filename);
                } else {
                    openPdfBlobViewer(blob, filename);
                }
            })
            .catch(() => {
                showResponse('danger', 'Unable to generate the PDF');
            })
            .finally(() => {
                setGenerating(false);
            });
    });
});
</script>
