<?php
$tenant = $_POST['tenant'] ?? '';
if ($tenant !== '' && file_exists('../../../' . $tenant . '/config.php')) {
    require_once('../../../' . $tenant . '/config.php');
}
if (file_exists('/config.php')) {
    require_once('/config.php');
}

$rawItems = $_POST['items'] ?? '';
if (is_array($rawItems)) {
    $rawItems = implode(',', $rawItems);
}

$items = array_values(array_filter(array_map('trim', explode(',', (string) $rawItems)), function ($item) {
    return $item !== '';
}));
$iCount = count($items);
$itemListValue = htmlspecialchars(implode(',', $items), ENT_QUOTES, 'UTF-8');
$clientnumberRaw = $_POST['clientnumber'] ?? '';
$clientnumber = htmlspecialchars($clientnumberRaw, ENT_QUOTES, 'UTF-8');
$clientnumberJs = htmlspecialchars($clientnumberRaw, ENT_QUOTES, 'UTF-8');
$tenantValue = htmlspecialchars(defined('TENANT_URL') ? TENANT_URL : $tenant, ENT_QUOTES, 'UTF-8');

require_once('../master/form_functions.php');
$rd = formApplyDefaultText('503' ?? '', $rd ?? []);
$repid = "001";
?>
<style>
.pna-progress-wrap {
    max-width: 900px;
    margin: 0 auto;
}

.pna-stat-row {
    justify-content: center;
}

.pna-stat-col {
    flex: 0 0 220px;
    max-width: 220px;
}

.pna-stat-card {
    border-radius: 0.5rem;
}

.pna-stat-card .card-body {
    padding: 1rem 0.75rem;
}

.pna-stat-label {
    font-size: 0.85rem;
    text-transform: uppercase;
    line-height: 1.2;
}

.pna-stat-value {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1.1;
    margin-top: 0.25rem;
}

@media (max-width: 767.98px) {
    .pna-stat-col {
        flex: 0 0 100%;
        max-width: 260px;
    }
}
</style>

<div id="loadingPNA" style="display:none">
    <div class="card shadow-4 mt-3">
        <div class="card-body text-center">
            <h1 class="mb-3">
                <i class="fad fa-flux-capacitor fa-spin fa-3x fa-fw"
                    style="--fa-primary-color: #0055A6; --fa-secondary-color: gray;"></i><br>
                Creating PNA
            </h1>

            <p class="lead mb-2">
                Please wait. This can take some time depending on the number of items being processed.
            </p>

            <div class="mb-4 fw-bold">
                Total items: <span id="pnaTotalCount"><?= $iCount ?></span>
            </div>

            <div class="pna-progress-wrap">
                <div class="row g-3 pna-stat-row mb-4">
                    <div class="col-auto pna-stat-col">
                        <div class="card success-color-dark text-light h-100 pna-stat-card">
                            <div class="card-body">
                                <div class="pna-stat-label">Processed</div>
                                <div class="pna-stat-value" id="pnaProcessedCount">0</div>
                            </div>
                        </div>
                    </div>

                    <div class="col-auto pna-stat-col">
                        <div class="card warning-color-dark text-light h-100 pna-stat-card">
                            <div class="card-body">
                                <div class="pna-stat-label">Remaining</div>
                                <div class="pna-stat-value" id="pnaRemainingCount"><?= $iCount ?></div>
                            </div>
                        </div>
                    </div>

                    <div class="col-auto pna-stat-col">
                        <div class="card danger-color-dark text-light h-100 pna-stat-card">
                            <div class="card-body">
                                <div class="pna-stat-label">Errors</div>
                                <div class="pna-stat-value" id="pnaFailedCount">0</div>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="mb-3">
                    <div class="progress" style="height: 24px;">
                        <div id="pnaProgressBar" class="progress-bar bg-info" role="progressbar" style="width: 0%;"
                            aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">0%</div>
                    </div>
                </div>

                <div class="mb-3 fw-bold" id="pnaProgressText">0 of <?= $iCount ?> processed</div>

                <div class="alert info-color-dark text-light mb-0">
                    <div class="fw-bold mb-1">Current item</div>
                    <div id="pnaCurrentItem">Preparing request...</div>
                </div>
            </div>
        </div>
    </div>
</div>

<div id="start" class="row">
    <div class="col-12 alert warning-color-dark text-light p-1 text-center align-middle">
        <i class="fad fa-triangle-exclamation fa-2x" style="--fa-primary-color: white; --fa-secondary-color: red;"></i>
        This will apply to all selected items
        and cannot be undone automatically<br>
        <small>All items will share the same REASON, EXAMINATION DATE, NEXT INSPECTION and SURVEYOR, irrespective of
            original values</small>
    </div>

    <p class="lead">You have chosen to mass PNA the following <b><?= $iCount ?></b> items</p>

    <div class="col-12 mb-4" style="max-height:250px; overflow:auto">
        <div class="row">
            <?php
            foreach ($items as $item) {
                $itemDisplay = preg_replace('/^C/i', '', $item);
                $itemName = htmlspecialchars(getItemDetails($itemDisplay, 'name'), ENT_QUOTES, 'UTF-8');
            ?>
            <div class="col-md-3">
                <div class="card me-2 mb-2 p-2"><?= htmlspecialchars($itemDisplay, ENT_QUOTES, 'UTF-8') ?> - <?= $itemName ?></div>
            </div>
            <?php } ?>
        </div>
    </div>

    <form id="F<?= $repid ?>">
        <?php require_once('../../..' . TENANT_URL . '/forms/items/503.php'); ?>
        <?php require_once('../../..' . TENANT_URL . '/forms/items/base_data_modal.php'); ?>
        <input id="itemList" type="hidden" value="<?= $itemListValue ?>">
        <input type="hidden" name="clientnumber" id="clientnumber" value="<?= $clientnumber ?>" />
        <input type="hidden" name="locnumber" id="locnumber" value="<?= $d[1] ?>" />
        <input type="hidden" name="reptype" id="reptype" value="503" />
        <input type="hidden" name="FUNCTION" id="FUNCTION" value="create" />
        <input type="hidden" name="imageMode" id="imageSet" value="<?= $iMode ?>" />
        <input type="hidden" name="pageMode" id="pageSet" value="1" />
        <input type="hidden" id="btn_save" value="save" />
        <input type="hidden" name="tenant" value="<?= $tenantValue ?>" />
    </form>
</div>

<div id="loader" style="display:none">
    <div class="col-12 text-center text-dark">
        <h1>
            <i class="fad fa-ring fa-spin fa-3x fa-fw"
                style="--fa-primary-color: #0055A6; --fa-secondary-color: grey;"></i><br>Processing
            Request<br><small>Please wait</small>
        </h1>
    </div>
</div>

<script>
const surveyorElement = document.getElementById('surveyor');
if (surveyorElement) {
    var mySelect = new mdb.Select(surveyorElement, {
        filter: true,
        container: '#pnaBoxes'
    });
}

// autofill Function
function autofill(f, s, t) {
    var dest = encodeURI(
        `${ROOT_URL}/includes/master/form_options.php?form=F<?= $repid ?>&source=${s}&type=${t}&tenant=${TENANT_URL}`
    );
    loadModalContent(dest, "popupBox", "modal-xl", 1061, "false", "Select Text", "cancel");
}

function resetBox(t) {
    document.getElementById(t).value = "None";
    const event = new Event('keyup');
    document.getElementById(t).dispatchEvent(event);
}

function getPnaNextDateField() {
    return document.getElementById('nextDate') ||
        document.getElementById('date_next') ||
        document.querySelector('[name="nextDate"]') ||
        document.querySelector('[name="date_next"]') ||
        document.querySelector('[name="nextInspection"]') ||
        document.querySelector('[name="nextinspection"]');
}

let massPnaNextPeriodChosen = false;

function initMassPnaNextInspectionOverride() {
    massPnaNextPeriodChosen = false;

    document.querySelectorAll('.freq').forEach((btn) => {
        btn.classList.remove('active');
    });

    const nextDateEl = document.getElementById('nextDate');
    if (nextDateEl) {
        nextDateEl.value = '';
    }

    const nextDateVisibleEl = document.getElementById('nextdate');
    if (nextDateVisibleEl) {
        nextDateVisibleEl.value = '';
    }

    document.querySelectorAll('.freq').forEach((btn) => {
        btn.addEventListener('click', function() {
            massPnaNextPeriodChosen = true;

            setTimeout(() => {
                const nextDateField = document.getElementById('nextDate');
                if (nextDateField && nextDateField.value.trim() === '') {
                    const activeBtn = document.querySelector('.freq.active');
                    if (activeBtn) {
                        const months = String(activeBtn.textContent || '').trim();
                        if (months !== '') {
                            changedate(months);
                        }
                    }
                }
            }, 0);
        });
    });
}

function setPnaText(id, value) {
    const el = document.getElementById(id);
    if (el) {
        el.textContent = value;
    }
}

function updatePnaProgress(total, processed, failed, currentText = '') {
    const remaining = Math.max(total - processed, 0);
    const percent = total > 0 ? Math.round((processed / total) * 100) : 0;

    setPnaText('pnaTotalCount', total);
    setPnaText('pnaProcessedCount', processed);
    setPnaText('pnaRemainingCount', remaining);
    setPnaText('pnaFailedCount', failed);
    setPnaText('pnaProgressText', `${processed} of ${total} processed`);
    setPnaText('pnaCurrentItem', currentText !== '' ? currentText : 'Preparing request...');

    const progressBar = document.getElementById('pnaProgressBar');
    if (progressBar) {
        progressBar.style.width = `${percent}%`;
        progressBar.setAttribute('aria-valuenow', percent);
        progressBar.textContent = `${percent}%`;
    }
}

setTimeout(initMassPnaNextInspectionOverride, 0);

function processPna() {
    if (!massPnaNextPeriodChosen) {
        showResponse('warning', 'Please select a Next Inspection Period before processing PNA items');
        return;
    }

    if (!document.getElementById('surveyor') || document.getElementById('surveyor').value === "NULL") {
        showResponse('danger', 'Please select surveyor before proceeding');
        return;
    }

    document.querySelectorAll('.actionButton').forEach((button) => {
        button.disabled = true;
    });

    const pageSet = document.getElementById('pageSet').value;
    const imageSet = document.getElementById('imageSet').value;
    const items = document.getElementById('itemList').value
        .split(',')
        .map((item) => String(item).trim())
        .filter((item) => item !== '');

    if (items.length === 0) {
        showResponse('warning', 'No items were supplied for processing');
        document.querySelectorAll('.actionButton').forEach((button) => {
            button.disabled = false;
        });
        return;
    }

    const startContainer = document.getElementById('start');
    const formContainer = document.getElementById('formContainer');
    const loadingPNA = document.getElementById('loadingPNA');

    if (formContainer) {
        formContainer.style.opacity = '0.33';
        formContainer.style.transition = 'opacity 0.5s ease';
    }

    if (loadingPNA && startContainer) {
        startContainer.style.display = 'none';
        loadingPNA.style.display = 'block';
    }

    let processedCount = 0;
    let failedCount = 0;
    const totalCount = items.length;

    updatePnaProgress(totalCount, processedCount, failedCount, 'Preparing request...');

    const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
    const LAST_INSPECTION_TIMEOUT_MS = 30000;
    const REPORT_CREATE_TIMEOUT_MS = 60000;
    const PDF_GENERATE_TIMEOUT_MS = 120000;
    const SESSION_KEEPALIVE_MS = 60000;
    const KEEPALIVE_TIMEOUT_MS = 15000;

    const fetchWithTimeout = async (url, options = {}, timeoutMs = 60000) => {
        const controller = new AbortController();
        const timer = setTimeout(() => controller.abort(), timeoutMs);

        try {
            const response = await fetch(url, {
                ...options,
                signal: controller.signal
            });

            if (!response.ok) {
                throw new Error(`Request failed with status ${response.status}`);
            }

            return response;
        } catch (error) {
            if (error.name === 'AbortError') {
                throw new Error(`Request timed out after ${Math.round(timeoutMs / 1000)} seconds`);
            }

            throw error;
        } finally {
            clearTimeout(timer);
        }
    };

    const retryFetch = async (url, options, maxRetries = 2, retryDelay = 2000, timeoutMs = PDF_GENERATE_TIMEOUT_MS) => {
        let attempts = 0;

        while (attempts < maxRetries) {
            try {
                const response = await fetchWithTimeout(url, options, timeoutMs);
                const text = await response.text();
                return text;
            } catch (error) {
                console.error(`Attempt ${attempts + 1} PDF fetch error:`, error);
            }

            attempts++;
            await delay(retryDelay);
        }

        return null;
    };

    const sendPnaKeepalive = async () => {
        try {
            await fetchWithTimeout(`${ROOT_URL}/includes/mass/pnaProcess.php`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded'
                },
                body: new URLSearchParams({
                    mode: 'keepalive',
                    tenant: TENANT_URL,
                    total: totalCount,
                    processed: processedCount
                })
            }, KEEPALIVE_TIMEOUT_MS);
        } catch (error) {
            console.error('Mass PNA keepalive failed:', error);
        }
    };

    const processItems = async () => {
        const keepaliveTimer = setInterval(sendPnaKeepalive, SESSION_KEEPALIVE_MS);
        sendPnaKeepalive();

        for (const item of items) {
            const itemDisplay = String(item).replace(/^C/i, '');
            updatePnaProgress(
                totalCount,
                processedCount,
                failedCount,
                `Processing item ${processedCount + 1} of ${totalCount}: ${itemDisplay}`
            );

            try {
                const oldDateResponse = await fetchWithTimeout(`${ROOT_URL}/includes/master/form_functions.php`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    body: new URLSearchParams({
                        FUNCTION: 'getLastInspection',
                        tenant: TENANT_URL,
                        itemnumber: item
                    })
                }, LAST_INSPECTION_TIMEOUT_MS);

                const olddate = (await oldDateResponse.text()).trim();
                const olddateForItem = olddate === '' ? 'Not Known' : olddate;

                const formData = new FormData(document.getElementById('F001'));
                formData.append('itemnumber', item);
                formData.append('olddate', olddateForItem);

                const formResponse = await fetchWithTimeout(`${ROOT_URL}/includes/master/form_functions.php`, {
                    method: 'POST',
                    body: formData
                }, REPORT_CREATE_TIMEOUT_MS);

                const formResult = await formResponse.text();
                const parts = formResult.trim().split('|');

                if (parts[0] !== "success") {
                    failedCount++;
                    showResponse('danger', `Report creation failed for item ${itemDisplay}`);
                    processedCount++;
                    updatePnaProgress(
                        totalCount,
                        processedCount,
                        failedCount,
                        `Failed on item ${itemDisplay}`
                    );
                    continue;
                }

                const repnumber = parts[1];
                const expectedSuccess = repnumber + "-0-0" + item;

                const pdfPostData = {
                    orientation: pageSet,
                    imageMode: imageSet,
                    clientnumber: '<?= $clientnumberJs ?>',
                    repnumber: repnumber,
                    items: item,
                    form: '503',
                    tenant: TENANT_URL
                };

                const pdfParams = new URLSearchParams(pdfPostData);
                const pdfOptions = {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    body: pdfParams.toString()
                };

                const pdfResult = await retryFetch(
                    `${ROOT_URL}/functions/generators/genPDF2.php`,
                    pdfOptions,
                    2,
                    2000,
                    PDF_GENERATE_TIMEOUT_MS
                );

                if (!pdfResult || pdfResult.trim() !== expectedSuccess) {
                    failedCount++;
                    showResponse('danger', `PDF generation failed for item ${itemDisplay}`);
                }

                processedCount++;
                updatePnaProgress(
                    totalCount,
                    processedCount,
                    failedCount,
                    processedCount < totalCount ?
                    `Completed item ${itemDisplay}` :
                    'Finalising request...'
                );

                await delay(1500);
            } catch (error) {
                console.error(`Error processing item ${item}:`, error);
                failedCount++;
                processedCount++;

                updatePnaProgress(
                    totalCount,
                    processedCount,
                    failedCount,
                    `Error on item ${itemDisplay}`
                );

                showResponse('danger', `Error processing item ${itemDisplay}`);
            }
        }

        clearInterval(keepaliveTimer);

        updatePnaProgress(
            totalCount,
            processedCount,
            failedCount,
            failedCount > 0 ?
            `Complete. ${failedCount} item(s) had an error. Redirecting...` :
            'Complete. Redirecting...'
        );

        showResponse(
            failedCount > 0 ? 'warning' : 'success',
            failedCount > 0 ?
            `Mass PNA complete. ${processedCount} processed, ${failedCount} with errors` :
            `Mass PNA complete. ${processedCount} items processed successfully`
        );

        setTimeout(() => {
            window.location.href = '<?= $_SESSION['returnLanding'] ?>';
        }, 800);
    };

    processItems();
}
</script>
