KAAUH Lab Suite - Verification, Alerts & Enhancements

Combines verification buttons (F7/F8), dynamic alerts, critical result reporting, checkbox automation, toggle back-nav, and inline sample counters.

当前为 2025-05-22 提交的版本,查看 最新版本

// ==UserScript==
// @name         KAAUH Lab Suite - Verification, Alerts & Enhancements
// @namespace    Violentmonkey Scripts
// @version      7.15.0
// @description  Combines verification buttons (F7/F8), dynamic alerts, critical result reporting, checkbox automation, toggle back-nav, and inline sample counters.
// @match        *://his.kaauh.org/lab/*
// @grant        none
// @author       Hamad AlShegifi (modified by Gemini)
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // --- Styling Adjustments (Global) ---
    function applySingleLineStyles() {
        const anchor = document.querySelector('li > a[href="#/lab-orders/doctor-request"]');
        if (anchor) {
            anchor.style.setProperty('white-space', 'nowrap', 'important');
            anchor.style.setProperty('overflow', 'visible', 'important');
            anchor.style.setProperty('text-overflow', 'unset', 'important');
            const spans = anchor.querySelectorAll('span');
            spans.forEach(span => {
                span.style.setProperty('display', 'inline', 'important');
                span.style.setProperty('font-size', '13px', 'important');
                span.style.setProperty('white-space', 'nowrap', 'important');
            });
        }

        const simplifySpan = (selector) => {
            const span = document.querySelector(selector);
            if (span) {
                span.style.setProperty('display', 'inline', 'important');
                span.style.setProperty('font-size', '20px', 'important');
                span.style.setProperty('white-space', 'nowrap', 'important');
                span.style.setProperty('overflow', 'visible', 'important');
                span.style.setProperty('text-overflow', 'unset', 'important');
                span.textContent = span.textContent.replace(/\s+/g, '');
            }
        };
        simplifySpan('span.to-do');
        simplifySpan('span.pending-orders');
    }

    function debounceStyle(func, wait) { // Renamed to avoid conflict if user copies debounce elsewhere
        let timeout;
        return function(...args) {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    }

    const debouncedStyleUpdater = debounceStyle(applySingleLineStyles, 300);
    const styleObserver = new MutationObserver(debouncedStyleUpdater);
    styleObserver.observe(document.body, { childList: true, subtree: true });
    applySingleLineStyles(); // Initial application
})();

// Main Userscript Logic (Alerts, F7/F8 buttons, etc.)
(function () {
    'use strict';

    // Debounce function (copied here for local scope)
    function debounce(func, wait) {
        let timeout;
        return function(...args) {
            clearTimeout(timeout);
            timeout = setTimeout(() => func.apply(this, args), wait);
        };
    }

    const CONFIG_MAIN = {
        URLS: {
            EDIT_PAGE_PREFIX: 'https://his.kaauh.org/lab/#/lab-orders/edit-lab-order/',
        },
        SELECTORS: {
            VERIFY1_BTN: '#custom-script-buttons button.verify1-btn',
            VERIFY2_BTN: '#custom-script-buttons button.verify2-btn',
            REPORT_CRITICAL_BTN: '#custom-script-buttons button.report-critical-btn',
            COMPLETE_TECH: 'button.dropdown-item[translateid="test-results.CompleteTechnicalVerification"]',
            COMPLETE_MED: 'button.dropdown-item[translateid="test-results.CompleteMedicalVerification"]',
            FINAL_VERIFY: 'button.btn-success.btn-sm.min-width[translateid="test-verification.Verify"]',
            NEXT_BTN: 'button#btnNext',
            UNCHECKED_BOX: 'span.ag-icon-checkbox-unchecked[unselectable="on"]',
            CHECKBOX_ROW: '.ag-row',
            TEST_DESC_CELL: '[col-id="TestDesc"]',
            ORDERED_STATUS_CELL: 'div[col-id="ResultStatus"]',
            TOAST: {
                CONTAINER: '#toast-container',
                CLOSE_BTN: 'button.toast-close-button',
                SUCCESS: '.toast-success',
            },
            SAMPLE_RECEIVE_MODAL: 'modal-container.show',
            ALL_TEST_ROWS_CENTER: '.ag-center-cols-container .ag-row',
            ALL_TEST_ROWS_PINNED: '.ag-pinned-left-cols-container .ag-row',
            TEST_RESULT_CELL_GENERAL: 'div[role="gridcell"][col-id="TestResult"] app-result-value-render div',
            TEST_UOM_CELL_GENERAL: 'div[col-id="UomValue"]',
            TEST_FLAG_CELL_GENERAL: 'div[role="gridcell"][col-id="LTFlag"] app-ref-high-low div span.critial-alret-indication',
        },
        CHECK_INTERVALS: {
            UNDEFINED_URL: 200,
            ORDERED_SCAN: 500, // This is defined but monitorOrderedStatus is not called by setInterval
            DISABLED_BTN_CHECK: 1000,
        },
        EXCLUDE_WORDS: [
            'culture', "gram's stain", 'stain', 'bacterial', 'fungal',
            'pcr', 'meningitis', 'mrsa', 'mid', 'stream', 'cryptococcus'
        ]
    };

    let verify1Clicked = false;
    let verify2Clicked = false;
    let verify1Toggle = localStorage.getItem('verify1Toggle') === 'true';
    let verify2Toggle = localStorage.getItem('verify2Toggle') === 'true';
    let hasScrolledToOrderedRow = false;
    let lastDisabledButtonAlertTime = 0;
    const DISABLED_ALERT_COOLDOWN = 30000;
    let isReportModalOpen = false; // For the "Report Critical Result" modal (manual one)
    let isAlertModalOpen = false; // For the automatic alert modal (createCustomAlert)

    // Centralized logging functions
    const logDebugMain = msg => console.debug(`[LabScript Main] ${msg}`);
    const logAlertDebug = msg => console.debug(`[Alerts Scanner DEBUG] ${msg}`);
    const logAlertError = msg => console.error(`[Alerts Scanner ERROR] ${msg}`);

    const isCorrectPage = () => window.location.href.startsWith(CONFIG_MAIN.URLS.EDIT_PAGE_PREFIX);

    function showDisabledButtonAlert(message) {
        const now = Date.now();
        if (now - lastDisabledButtonAlertTime < DISABLED_ALERT_COOLDOWN) return;
        lastDisabledButtonAlertTime = now;

        const modalOverlay = document.createElement('div');
        modalOverlay.id = 'disabled-button-alert-overlay';
        Object.assign(modalOverlay.style, {
            position: 'fixed', top: '0', left: '0', width: '100vw', height: '100vh',
            backgroundColor: 'rgba(0, 0, 0, 0.7)', zIndex: '10000', display: 'flex',
            justifyContent: 'center', alignItems: 'center'
        });

        const modalBox = document.createElement('div');
        Object.assign(modalBox.style, {
            backgroundColor: '#fff', padding: '25px', borderRadius: '8px',
            boxShadow: '0 5px 15px rgba(0,0,0,0.3)', width: 'auto', maxWidth: '80%',
            textAlign: 'center', borderTop: '5px solid #f0ad4e'
        });

        const title = document.createElement('h3');
        title.textContent = 'Button Disabled';
        title.style.color = '#d9534f';
        title.style.marginTop = '0';
        modalBox.appendChild(title);

        const messageElem = document.createElement('p');
        messageElem.textContent = message;
        messageElem.style.fontSize = '16px';
        messageElem.style.marginBottom = '20px';
        modalBox.appendChild(messageElem);

        const okButton = document.createElement('button');
        okButton.textContent = 'OK';
        Object.assign(okButton.style, {
            padding: '8px 20px', borderRadius: '5px', backgroundColor: '#5cb85c',
            color: '#fff', border: 'none', cursor: 'pointer', fontSize: '16px'
        });
        okButton.onclick = () => document.body.removeChild(modalOverlay);
        modalBox.appendChild(okButton);

        modalOverlay.appendChild(modalBox);
        document.body.appendChild(modalOverlay);
        okButton.focus();
    }

    function addFontAwesome() {
        const fontAwesomeLink = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css';
        if (!document.querySelector(`link[href="${fontAwesomeLink}"]`)) {
            const link = document.createElement('link');
            link.rel = 'stylesheet';
            link.href = fontAwesomeLink;
            const head = document.head || document.body;
            if (head) head.appendChild(link);
        }
    }

    function createVerifyButton(label, className, onClick, id) {
        const button = document.createElement('button');
        button.type = 'button';
        button.className = className;
        button.classList.add(id);
        button.innerText = label;
        const styles = {
            'font-family': 'Arial, sans-serif',
            'font-size': '14px',
            'font-weight': 'normal',
            'color': '#ffffff',
            'background-color': className.includes('success') ? '#28a745' : '#2594d9',
            'padding': '8px 16px',
            'border': 'none',
            'border-radius': '5px',
            'text-shadow': 'none',
            'cursor': 'pointer',
            'margin-right': '5px',
            'line-height': '1.5',
            'vertical-align': 'middle',
        };
        for (const [prop, value] of Object.entries(styles)) {
            button.style.setProperty(prop, value, 'important');
        }
        button.onclick = onClick;
        return button;
    }

    async function initiateManualCriticalReport() {
        logDebugMain("Manual critical report initiated. [Phase 1]");
        if (isReportModalOpen || document.getElementById('report-selection-modal-overlay')) {
            logDebugMain("Report selection modal already open. Aborting.");
            return;
        }

        logDebugMain("Collecting testsData... [Phase 2]");
        const testsData = collectAllTestsWithResults(); // UOM is now collected as is from the grid
        if (testsData.length === 0) {
            showDisabledButtonAlert("No tests found on the page to report.");
            logDebugMain("No tests found. Aborting modal. [Phase 2.1]");
            return;
        }
        logDebugMain(`testsData collected: ${testsData.length} items. [Phase 2.2]`);

        logDebugMain("Introducing a small delay before fetching patient data for manual report... [Phase 2.5]");
        await new Promise(resolve => setTimeout(resolve, 300));

        try {
            logDebugMain("Attempting to get patient data... [Phase 3]");
            const patientInfoResult = await getPatientDataWithRetry({
                name: CONFIG_ALERTS.PATIENT_NAME_SELECTOR,
                mrn: CONFIG_ALERTS.PATIENT_MRN_SELECTOR,
                location: CONFIG_ALERTS.PATIENT_LOCATION_SELECTOR,
                barcode: CONFIG_ALERTS.SAMPLE_BARCODE_SELECTOR
            });
            logDebugMain(`Patient data received. Essential: ${patientInfoResult.allEssentialDataRetrieved}. Data: ${JSON.stringify(patientInfoResult.data)} [Phase 4]`);

            if (!patientInfoResult.allEssentialDataRetrieved) {
                logAlertError("Essential patient data could not be retrieved for manual report.");
            }

            const userIdElement = document.querySelector(CONFIG_ALERTS.USER_NAME_SELECTOR);
            const currentUserId = userIdElement ? userIdElement.textContent.trim() : 'N/A';
            logDebugMain(`User ID: ${currentUserId} [Phase 5]`);

            logDebugMain("Calling createReportSelectionModal... [Phase 6]");
            createReportSelectionModal(testsData, patientInfoResult.data, currentUserId);
            logDebugMain("createReportSelectionModal call finished. [Phase 7]");

        } catch (error) {
            logAlertError(`Error in initiateManualCriticalReport: ${error.message}`);
            console.error("Full error object in initiateManualCriticalReport:", error);
            alert("An error occurred while preparing the report. Please check the console for details.");
        }
    }

    function createReportCriticalResultButton() {
        const button = document.createElement('button');
        button.type = 'button';
        button.className = 'btn btn-danger btn-sm report-critical-btn'; // btn-danger for red
        button.innerText = 'Report Critical Result';
        const styles = {
            'font-family': 'Arial, sans-serif', 'font-size': '14px', 'font-weight': 'normal',
            'color': '#ffffff',
            'background-color': '#dc3545', // Red color
            'padding': '8px 16px', 'border': 'none', 'border-radius': '5px',
            'text-shadow': 'none', 'cursor': 'pointer', 'margin-right': '10px',
            'line-height': '1.5', 'vertical-align': 'middle',
        };
        for (const [prop, value] of Object.entries(styles)) {
            button.style.setProperty(prop, value, 'important');
        }
        button.onclick = initiateManualCriticalReport;
        return button;
    }

    function createToggleIcon(id, isActive, onClick) {
        const icon = document.createElement('span');
        icon.id = id;
        icon.innerHTML = `<i class="fas fa-arrow-circle-left" style="color: ${isActive ? '#008000' : '#d1cfcf'}; font-size: 1.3em; vertical-align: middle;"></i>`;
        icon.style.cursor = 'pointer';
        icon.style.marginRight = '10px';
        icon.style.marginLeft = '-1px';
        icon.title = "Toggle: Go back automatically after this verification success toast is clicked";
        icon.onclick = onClick;
        return icon;
    }

    function handleVerifyToggle(type) {
        const toggle = type === 'verify1' ? !verify1Toggle : !verify2Toggle;
        localStorage.setItem(type + 'Toggle', toggle);
        const icon = document.querySelector(`#${type}Icon i`);
        if (icon) icon.style.setProperty('color', toggle ? '#008000' : '#d1cfcf', 'important');

        if (type === 'verify1') verify1Toggle = toggle;
        else verify2Toggle = toggle;
    }

    function addButtons() {
        if (document.getElementById('custom-script-buttons') || !isCorrectPage()) return;
        const nextButton = document.querySelector(CONFIG_MAIN.SELECTORS.NEXT_BTN);
        if (!nextButton || !nextButton.parentNode) {
            setTimeout(addButtons, 500);
            return;
        }

        const buttonDiv = document.createElement('div');
        buttonDiv.id = 'custom-script-buttons';
        buttonDiv.style.setProperty('display', 'inline-block', 'important');
        buttonDiv.style.setProperty('margin-left', '10px', 'important');
        buttonDiv.style.setProperty('vertical-align', 'middle', 'important');

        const verify1Button = createVerifyButton('VERIFY1 (F7)', 'btn btn-success btn-sm', () => {
            verify1Clicked = true; verify2Clicked = false;
            checkAllVisibleBoxesWithoutDuplicates();
            setTimeout(clickCompleteTechnicalVerificationButton, 500);
        }, 'verify1-btn');

        const verify2Button = createVerifyButton('VERIFY2 (F8)', 'btn btn-primary btn-sm', () => {
            verify2Clicked = true; verify1Clicked = false;
            checkAllVisibleBoxesWithoutDuplicates();
            setTimeout(clickCompleteMedicalVerificationButton, 500);
        }, 'verify2-btn');

        const reportCriticalButton = createReportCriticalResultButton();

        const verify1Icon = createToggleIcon('verify1Icon', verify1Toggle, () => handleVerifyToggle('verify1'));
        const verify2Icon = createToggleIcon('verify2Icon', verify2Toggle, () => handleVerifyToggle('verify2'));

        const credit = document.createElement('span');
        credit.textContent = "Modded by: Hamad AlShegifi";
        credit.style.cssText = `font-size: 11px !important; font-weight: bold !important; color: #e60000 !important; margin-left: 15px !important; border: 1px solid #e60000 !important; border-radius: 5px !important; padding: 3px 6px !important; background-color: #ffffff !important; vertical-align: middle !important;`;

        buttonDiv.append(verify1Button, verify1Icon, verify2Button, verify2Icon, reportCriticalButton, credit);
        nextButton.parentNode.insertBefore(buttonDiv, nextButton.nextSibling);
        logDebugMain("Custom buttons added.");
    }

    function checkAllVisibleBoxesWithoutDuplicates() {
        const selectedTests = new Set();
        const boxes = document.querySelectorAll(CONFIG_MAIN.SELECTORS.UNCHECKED_BOX);
        boxes.forEach(box => {
            const row = box.closest(CONFIG_MAIN.SELECTORS.CHECKBOX_ROW);
            if (row && row.offsetParent !== null) { // Check if row is visible
                const testDescElement = row.querySelector(CONFIG_MAIN.SELECTORS.TEST_DESC_CELL);
                const descText = testDescElement?.textContent.trim().toLowerCase();
                if (descText) {
                    const isExcluded = CONFIG_MAIN.EXCLUDE_WORDS.some(word => descText.includes(word));
                    if (!selectedTests.has(descText) && !isExcluded) {
                        selectedTests.add(descText); box.click();
                    }
                }
            }
        });
        logDebugMain(`Checked ${selectedTests.size} unique, non-excluded, visible boxes.`);
    }

    const clickButton = (selector, callback) => {
        const btn = document.querySelector(selector);
        if (btn && !btn.disabled) {
            btn.click();
            if (callback) setTimeout(callback, 500);
            return true;
        } else if (btn && btn.disabled) {
            const buttonName = selector.includes('CompleteTechnicalVerification') ? 'Complete Technical Verification' :
                               selector.includes('CompleteMedicalVerification') ? 'Complete Medical Verification' :
                               selector.includes('Verify') ? 'Final Verify' : 'Button';
            showDisabledButtonAlert(`${buttonName} button is disabled. Please check if you have selected all required tests or if verification is already done.`);
        }
        return false;
    };

    const clickCompleteTechnicalVerificationButton = () => clickButton(CONFIG_MAIN.SELECTORS.COMPLETE_TECH, clickFinalVerifyButton);
    const clickCompleteMedicalVerificationButton = () => clickButton(CONFIG_MAIN.SELECTORS.COMPLETE_MED, clickFinalVerifyButton);
    const clickFinalVerifyButton = () => clickButton(CONFIG_MAIN.SELECTORS.FINAL_VERIFY);

    function checkForDisabledButtons() {
        // Proactive checks can be added here if needed
    }

    function checkUrlAndTriggerClickForUndefined() {
        if (window.location.href.endsWith('/undefined')) {
            const closeBtn = document.querySelector(`${CONFIG_MAIN.SELECTORS.TOAST.CONTAINER} ${CONFIG_MAIN.SELECTORS.TOAST.CLOSE_BTN}`);
            if (closeBtn) {
                logDebugMain("URL ends with /undefined, attempting to close toast.");
                closeBtn.click();
            }
        }
    }

    function monitorOrderedStatus() {
        if (!isCorrectPage()) return;
        const rows = document.querySelectorAll('div[role="row"]');
        let hasOrdered = false; let firstOrderedRow = null;
        rows.forEach(row => {
            if (row.offsetParent !== null) { // Check if row is visible
                const cell = row.querySelector(CONFIG_MAIN.SELECTORS.ORDERED_STATUS_CELL);
                if (cell?.textContent.includes('Ordered')) {
                    if (!firstOrderedRow) firstOrderedRow = row;
                    hasOrdered = true;
                }
            }
        });
        const btn = document.querySelector(CONFIG_MAIN.SELECTORS.VERIFY1_BTN);
        if (btn) {
            if (hasOrdered) {
                if (!btn.classList.contains('btn-warning')) {
                    btn.className = 'btn btn-warning verify1-btn'; btn.innerText = 'VERIFY1 (F7)'; // Class ensures ID for selector is maintained
                    btn.style.setProperty('background-color', '#fab641', 'important');
                    btn.style.setProperty('color', '#050505', 'important');
                    logDebugMain("Ordered status detected. VERIFY1 button changed to warning.");
                }
                if (firstOrderedRow && !hasScrolledToOrderedRow) {
                    document.documentElement.style.scrollBehavior = 'smooth';
                    firstOrderedRow.scrollIntoView({ behavior: 'auto', block: 'center' });
                    hasScrolledToOrderedRow = true;
                    setTimeout(() => document.documentElement.style.scrollBehavior = 'auto', 1000);
                    logDebugMain("Scrolled to first 'Ordered' row.");
                }
            } else {
                if (btn.classList.contains('btn-warning')) {
                    btn.className = 'btn btn-success btn-sm verify1-btn'; btn.innerText = 'VERIFY1 (F7)'; // Class ensures ID for selector is maintained
                    btn.style.setProperty('background-color', '#28a745', 'important');
                    btn.style.setProperty('color', '#ffffff', 'important');
                    logDebugMain("No ordered status. VERIFY1 button reverted to success.");
                }
                hasScrolledToOrderedRow = false;
            }
        }
    }
    // Debounced version of monitorOrderedStatus
    const debouncedMonitorOrderedStatus = debounce(monitorOrderedStatus, 400);


    const toastObserver = new MutationObserver(mutations => {
        mutations.forEach(mutation => {
            mutation.addedNodes.forEach(node => {
                if (node.nodeType === Node.ELEMENT_NODE) {
                    let successToast = node.matches(CONFIG_MAIN.SELECTORS.TOAST.SUCCESS) ? node : node.querySelector(CONFIG_MAIN.SELECTORS.TOAST.SUCCESS);
                    if (successToast) {
                        logDebugMain("Success toast detected.");
                        successToast.addEventListener('click', () => {
                            if ((verify1Clicked && verify1Toggle) || (verify2Clicked && verify2Toggle)) {
                                logDebugMain("Navigating back due to toast click and toggle state.");
                                window.history.back();
                            }
                            verify1Clicked = false; verify2Clicked = false;
                        }, { once: true });
                    }
                }
            });
        });
    });
    toastObserver.observe(document.body, { childList: true, subtree: true });

    document.addEventListener('keydown', e => {
        if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA' || e.target.tagName === 'SELECT') return;
        if (e.key === 'F7') { e.preventDefault(); document.querySelector(CONFIG_MAIN.SELECTORS.VERIFY1_BTN)?.click(); }
        else if (e.key === 'F8') { e.preventDefault(); document.querySelector(CONFIG_MAIN.SELECTORS.VERIFY2_BTN)?.click(); }
    });

    // --- Integrated Alerts Scanner Code ---
    if (typeof XLSX === 'undefined') {
        console.warn("[Alerts Scanner] SheetJS library (XLSX) not found. Local XLSX saving will not work.");
    }

    const CONFIG_ALERTS = {
        SCAN_INTERVAL: 500,
        FLASH_COLOR: "pink",
        FLASH_INTERVAL: 700,
        RESULT_CELL_SELECTOR: 'div[role="gridcell"][col-id="TestResult"] app-result-value-render div',
        UOM_CELL_SELECTOR: 'div[col-id="UomValue"]',
        CRITICAL_FLAG_SELECTOR: 'div[role="gridcell"][col-id="LTFlag"] app-ref-high-low div span.critial-alret-indication',
        TEST_DESC_PINNED_SELECTOR: '.ag-pinned-left-cols-container .ag-row div[col-id="TestDesc"]',
        NO_RESULT_MESSAGE: "NO-RESULT DETECTED!",
        DILUTION_MESSAGE: "DILUTION REQUIRED!",
        PATIENT_NAME_SELECTOR: 'div.patient-name-full',
        PATIENT_MRN_SELECTOR: 'div.mid.renal-demography span',
        PATIENT_LOCATION_SELECTOR: 'div.patient-info span[title]',
        USER_NAME_SELECTOR: 'div.profile-wrapper span.csi-dropdown-btn-text',
        SAMPLE_BARCODE_SELECTOR: 'div[style*="font-size: 13px; color: rgb(68, 68, 68);"]',
        LOCAL_SERVER_SAVE_URL: 'http://localhost:5000/save-alerts',
        CRITICAL_BACKGROUND_COLORS: [
            'rgb(255, 0, 0)', 'red', '#ff0000',
            'rgb(220, 53, 69)',
            'rgb(217, 83, 79)'
        ]
    };

    let isScanningActive = false;
    let issueScanIntervalId = null;

    const createModalButton = (text, styleType = 'primary') => {
        const button = document.createElement('button');
        button.textContent = text;
        Object.assign(button.style, {
            padding: '12px 24px', borderRadius: '8px', fontWeight: '600', fontSize: '15px',
            border: 'none', cursor: 'pointer',
            transition: 'background-color 0.2s ease, box-shadow 0.2s ease, transform 0.1s ease',
            marginLeft: '8px'
        });
        if (styleType === 'primary') {
            button.style.backgroundColor = '#007bff'; button.style.color = 'white';
            button.onmouseover = () => button.style.backgroundColor = '#0069d9';
            button.onmouseout = () => button.style.backgroundColor = '#007bff';
        } else if (styleType === 'success') {
            button.style.backgroundColor = '#28a745'; button.style.color = 'white';
            button.onmouseover = () => button.style.backgroundColor = '#218838';
            button.onmouseout = () => button.style.backgroundColor = '#28a745';
        } else {
            button.style.backgroundColor = '#6c757d'; button.style.color = 'white';
            button.onmouseover = () => button.style.backgroundColor = '#5a6268';
            button.onmouseout = () => button.style.backgroundColor = '#6c757d';
        }
        button.onmousedown = () => button.style.transform = 'scale(0.98)';
        button.onmouseup = () => button.style.transform = 'scale(1)';
        return button;
    };

     const createFormGroup = (label, inputId, placeholder, type = 'text') => {
        const formGroup = document.createElement('div');
        const formLabel = document.createElement('label');
        formLabel.textContent = label; formLabel.htmlFor = inputId;
        Object.assign(formLabel.style, { display: 'block', fontSize: '14px', fontWeight: '500', marginBottom: '6px', color: '#495057' });
        formGroup.appendChild(formLabel);
        const formInput = document.createElement('input');
        formInput.type = type; formInput.id = inputId; formInput.placeholder = placeholder;
        Object.assign(formInput.style, {
            width: '100%', padding: '12px', border: '1px solid #ced4da', borderRadius: '6px',
            fontSize: '14px', boxSizing: 'border-box',
            transition: 'border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out'
        });
        formInput.onfocus = () => { formInput.style.borderColor = '#80bdff'; formInput.style.boxShadow = '0 0 0 0.2rem rgba(0,123,255,.25)'; };
        formInput.onblur = () => { formInput.style.borderColor = '#ced4da'; formInput.style.boxShadow = 'none'; };
        formGroup.appendChild(formInput);
        return formGroup;
    };

    function applyFlashingEffect(row) {
        if (!row || row.dataset.flashing === 'true') return;
        row.dataset.flashing = 'true';
        const originalBg = row.style.backgroundColor || 'transparent';
        row.dataset.originalBg = originalBg;
        row.style.transition = "background-color 0.5s ease";
        let isPink = false;
        const intervalId = setInterval(() => {
            if (!document.body.contains(row) || row.dataset.flashing === 'false') {
                clearInterval(intervalId);
                row.style.transition = '';
                row.style.setProperty("background-color", row.dataset.originalBg || 'transparent', "important");
                delete row.dataset.flashing;
                delete row.dataset.originalBg;
                delete row.dataset.flashIntervalId;
                return;
            }
            isPink = !isPink;
            row.style.setProperty("background-color", isPink ? CONFIG_ALERTS.FLASH_COLOR : originalBg, "important");
        }, CONFIG_ALERTS.FLASH_INTERVAL);
        row.dataset.flashIntervalId = intervalId.toString();
    }

    function stopFlashingEffect(row) {
        if (row && row.dataset.flashing === 'true') {
            row.dataset.flashing = 'false';
            const intervalId = parseInt(row.dataset.flashIntervalId, 10);
            if (!isNaN(intervalId)) {
                clearInterval(intervalId);
            }
        }
    }

    function getNotificationSessionKey(type, identifier = 'general') {
        const safeIdentifier = String(identifier).replace(/[^a-zA-Z0-9_-]/g, '');
        return `labAlertNotified_${window.location.pathname}${window.location.hash}_${type}_${safeIdentifier}`;
    }

    function hasAlreadyNotified(type, identifier = 'general') {
        const key = getNotificationSessionKey(type, identifier);
        return sessionStorage.getItem(key) === 'true';
    }

    function setNotificationFlag(type, identifier = 'general') {
        const key = getNotificationSessionKey(type, identifier);
        logAlertDebug(`Setting notification flag for key: "${key}"`);
        sessionStorage.setItem(key, 'true');
    }

    function getNextEntryID() {
        const counterKey = 'labAlertEntryCounter';
        let currentID = parseInt(localStorage.getItem(counterKey), 10) || 0;
        currentID++;
        localStorage.setItem(counterKey, String(currentID));
        logAlertDebug(`Next Entry ID: ${currentID}`);
        return currentID;
    }

    async function sendAlertDataToServer(alertData) {
        logAlertDebug("Attempting to send data to local server.");
        if (!CONFIG_ALERTS.LOCAL_SERVER_SAVE_URL) {
            logAlertError("LOCAL_SERVER_SAVE_URL is not configured.");
            return false;
        }

        const isFromAutoAlertModal = document.getElementById('custom-alert-modal-overlay') && !document.getElementById('report-selection-modal-overlay');
        const isFromManualReportModal = document.getElementById('report-selection-modal-overlay');

        let notifiedPersonName, notifiedPersonTelExt, readBack, reportingUserId;

        if (isFromAutoAlertModal) {
            logAlertDebug("sendAlertDataToServer: Data sourced from Auto Alert Modal fields.");
            const notifiedPersonNameInput = document.getElementById('notifiedPersonNameInput');
            const notifiedPersonTelExtInput = document.getElementById('notifiedPersonTelExtInput');
            const readBackCheckbox = document.getElementById('readBackCheckbox');
            const userIdInput = document.getElementById('userIdInput');

            notifiedPersonName = notifiedPersonNameInput ? notifiedPersonNameInput.value : '';
            notifiedPersonTelExt = notifiedPersonTelExtInput ? notifiedPersonTelExtInput.value : '';
            readBack = readBackCheckbox ? readBackCheckbox.checked : false;
            reportingUserId = userIdInput ? userIdInput.value : (alertData.userId || 'N/A');
        } else if (isFromManualReportModal) {
            logAlertDebug("sendAlertDataToServer: Data sourced from Manual Report Modal payload fields.");
            notifiedPersonName = alertData.notifiedPersonName || '';
            notifiedPersonTelExt = alertData.notifiedPersonTelExt || '';
            readBack = alertData.readBack || false;
            reportingUserId = alertData.userName || 'N/A';
        } else {
            logAlertError("sendAlertDataToServer: Unknown modal source. Using direct alertData fields if available.");
            notifiedPersonName = alertData.notifiedPersonName || '';
            notifiedPersonTelExt = alertData.notifiedPersonTelExt || '';
            readBack = alertData.readBack || false;
            reportingUserId = alertData.userName || alertData.userId || 'N/A';
        }


        const now = new Date();
        const date = `${String(now.getDate()).padStart(2, '0')}/${String(now.getMonth() + 1).padStart(2, '0')}/${now.getFullYear()}`;
        const hours = now.getHours();
        const minutes = String(now.getMinutes()).padStart(2, '0');
        const ampm = hours >= 12 ? 'pm' : 'am';
        const formattedHours = hours % 12 || 12;
        const time = `${formattedHours}:${minutes} ${ampm}`;
        const entryID = alertData.entryID || getNextEntryID();

        const dataToSend = {
            entryID: entryID,
            date: date,
            time: time,
            patientName: alertData.patientName || 'N/A',
            patientMRN: alertData.patientMRN || alertData.patientId || 'N/A',
            patientLocation: alertData.patientLocation || 'N/A',
            sampleBarcode: alertData.sampleBarcode || 'N/A',
            userName: reportingUserId,
            notifiedPersonName: notifiedPersonName,
            notifiedPersonTelExt: notifiedPersonTelExt,
            readBack: readBack,
            alerts: alertData.alerts ? alertData.alerts.map(alert => ({
                testName: alert.testName,
                result: alert.result,
                uom: alert.uom || '',
                flag: alert.flag,
                type: alert.type,
                comment: alert.comment || ''
            })) : (alertData.alertsToList ? alertData.alertsToList.map(alert => ({
                testName: alert.testName,
                result: alert.result,
                uom: alert.uom || '',
                flag: alert.flag,
                type: alert.type,
                comment: alert.comment || ''
            })) : [])
        };
        logAlertDebug("Data prepared for server:", JSON.stringify(dataToSend, null, 2));


        try {
            const response = await fetch(CONFIG_ALERTS.LOCAL_SERVER_SAVE_URL, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(dataToSend)
            });
            if (response.ok) {
                logAlertDebug("Data successfully sent to local server.");
                return true;
            } else {
                const errorText = await response.text();
                logAlertError(`Failed to send data to local server: ${response.status} ${response.statusText} - ${errorText}`);
                return false;
            }
        } catch (error) {
            logAlertError("Error sending data to local server:", error);
            return false;
        }
    }


    function closeAlertModalAction() {
        logAlertDebug("closeAlertModalAction triggered.");
        const overlay = document.getElementById('custom-alert-modal-overlay');
        if (overlay) {
            const modalContent = overlay.querySelector('#custom-alert-modal-content');
            if (modalContent && modalContent.dataset.alerts) {
                try {
                    const alertsToMark = JSON.parse(modalContent.dataset.alerts);
                    alertsToMark.forEach(alert => {
                        if (alert.type && alert.rowId) {
                            const parts = alert.rowId.split('_');
                            const type = parts[0];
                            const baseIdentifier = parts.slice(1).join('_');
                            setNotificationFlag(type, baseIdentifier);
                            logAlertDebug(`Marked alert as notified: Type=${type}, Identifier=${baseIdentifier} (from full key ${alert.rowId})`);
                        }
                    });
                } catch (e) {
                    console.error("Error parsing alerts data from modal dataset:", e);
                }
            }
            overlay.style.opacity = '0';
            if (modalContent) {
                modalContent.style.opacity = '0';
                modalContent.style.transform = 'translateY(-30px) scale(0.95)';
            }
            overlay.addEventListener('transitionend', () => {
                if (overlay.parentNode) {
                    overlay.parentNode.removeChild(overlay);
                }
                isAlertModalOpen = false;
                document.body.style.overflow = '';
                logAlertDebug("Alert modal overlay removed, isAlertModalOpen = false");
            }, { once: true });
            setTimeout(() => {
                if (overlay && overlay.parentNode) {
                    overlay.parentNode.removeChild(overlay);
                }
                if (isAlertModalOpen) {
                    isAlertModalOpen = false;
                    document.body.style.overflow = '';
                    logAlertDebug("Alert modal overlay removed by fallback, isAlertModalOpen = false");
                }
            }, 400);
        } else {
            isAlertModalOpen = false;
            document.body.style.overflow = '';
            logAlertDebug("closeAlertModalAction called but overlay not found, isAlertModalOpen = false");
        }
    }

    function createCustomAlert(alertData, alertsDisplayedInModal) {
        logAlertDebug(`Attempting to create alert modal. isAlertModalOpen: ${isAlertModalOpen}, Existing overlay: ${document.getElementById('custom-alert-modal-overlay')}`);
        if (document.getElementById('custom-alert-modal-overlay') || isAlertModalOpen) {
            logAlertDebug("Alert modal already open or overlay element exists. Aborting creation.");
            return;
        }
        isAlertModalOpen = true;
        logDebugMain("Alert modal creation initiated. isAlertModalOpen set to true.");

        const overlay = document.createElement('div');
        overlay.id = 'custom-alert-modal-overlay';
        Object.assign(overlay.style, {
            position: 'fixed', top: '0', left: '0', width: '100%', height: '100%',
            backgroundColor: 'rgba(0, 0, 0, 0.65)', zIndex: '10001', display: 'flex',
            justifyContent: 'center', alignItems: 'center', opacity: '0',
            transition: 'opacity 0.3s ease-out', padding: '20px'
        });
        document.body.style.overflow = 'hidden';

        const modalBox = document.createElement('div');
        modalBox.id = 'custom-alert-modal-content';
        Object.assign(modalBox.style, {
            backgroundColor: '#ffffff', borderRadius: '12px',
            boxShadow: '0 16px 32px rgba(0, 0, 0, 0.1), 0 8px 16px rgba(0, 0, 0, 0.08)',
            width: 'calc(100% - 40px)', maxWidth: '1100px', maxHeight: '90vh',
            overflowY: 'auto', padding: '32px', position: 'relative',
            opacity: '0', transform: 'translateY(-20px) scale(0.98)',
            transition: 'opacity 0.3s ease-out, transform 0.3s ease-out',
            fontFamily: "'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif",
            color: '#343a40', display: 'flex', flexDirection: 'column', gap: '16px'
        });

        const closeButtonX = document.createElement('button');
        closeButtonX.innerHTML = '&times;';
        Object.assign(closeButtonX.style, {
            position: 'absolute', top: '18px', right: '18px', fontSize: '30px',
            lineHeight: '1', cursor: 'pointer', color: '#adb5bd', background: 'transparent',
            border: 'none', padding: '0', width: '30px', height: '30px',
            display: 'flex', alignItems: 'center', justifyContent: 'center'
        });
        closeButtonX.onmouseover = () => closeButtonX.style.color = '#495057';
        closeButtonX.onmouseout = () => closeButtonX.style.color = '#adb5bd';
        closeButtonX.onclick = closeAlertModalAction;
        modalBox.appendChild(closeButtonX);

        const headerDiv = document.createElement('div');
        Object.assign(headerDiv.style, {
            display: 'flex', alignItems: 'center', gap: '12px',
            paddingBottom: '18px', borderBottom: '1px solid #dee2e6', marginBottom: '16px'
        });
        const alertIcon = document.createElement('i');
        alertIcon.className = 'fas fa-exclamation-triangle';
        let iconColor = '#17a2b8';
        let alertTitleText = 'Lab Alert Detected';

        if (alertData.overallSeverity === 'critical') {
            alertTitleText = 'Critical Lab Alert!'; iconColor = '#d9534f';
        } else if (alertData.overallSeverity === 'noresult') {
            alertTitleText = 'No Result Detected'; iconColor = '#ffc107';
        } else if (alertData.overallSeverity === 'greaterThan') {
            alertTitleText = 'Dilution Required'; iconColor = '#ffc107';
        }

        alertIcon.style.fontSize = '26px';
        alertIcon.style.color = iconColor;
        headerDiv.appendChild(alertIcon);
        const title = document.createElement('h2');
        title.textContent = alertTitleText;
        Object.assign(title.style, { fontSize: '26px', fontWeight: '600', color: iconColor, margin: '0' });
        headerDiv.appendChild(title);
        const dateTime = document.createElement('p');
        dateTime.id = 'currentDateTime';
        dateTime.textContent = new Date().toLocaleString([], { dateStyle: 'medium', timeStyle: 'short' });
        Object.assign(dateTime.style, { fontSize: '14px', color: '#6c757d', margin: '0', marginLeft: 'auto' });
        headerDiv.appendChild(dateTime);
        modalBox.appendChild(headerDiv);

        const createInfoItem = (label, value, iconClass) => {
            if (!value) value = 'N/A';
            const itemDiv = document.createElement('div');
            Object.assign(itemDiv.style, {
                backgroundColor: '#f8f9fa', borderRadius: '8px', padding: '16px',
                border: '1px solid #e9ecef', boxShadow: '0 3px 6px rgba(0,0,0,0.06)',
                display: 'flex', flexDirection: 'column', gap: '10px'
            });
            const header = document.createElement('div');
            Object.assign(header.style, { display: 'flex', alignItems: 'center', gap: '12px', color: '#495057' });
            if (iconClass) {
                const iconElem = document.createElement('i');
                iconElem.className = `fas ${iconClass}`;
                Object.assign(iconElem.style, { fontSize: '1.4em', color: '#007bff' });
                header.appendChild(iconElem);
            }
            const labelElem = document.createElement('strong');
            labelElem.textContent = `${label}:`;
            labelElem.style.fontSize = '15px'; labelElem.style.fontWeight = '600';
            header.appendChild(labelElem);
            itemDiv.appendChild(header);
            const valueElem = document.createElement('span');
            valueElem.textContent = value;
            Object.assign(valueElem.style, {
                fontSize: '16px', color: '#212529', wordBreak: 'break-word',
                paddingLeft: iconClass ? '32px' : '0'
            });
            itemDiv.appendChild(valueElem);
            return itemDiv;
        };

        const allPatientInfoContainer = document.createElement('div');
        Object.assign(allPatientInfoContainer.style, {
            display: 'flex', flexDirection: 'column', gap: '18px',
            paddingBottom: '18px', borderBottom: '1px solid #dee2e6', marginBottom: '16px'
        });
        const pNameItem = createInfoItem('Patient Name', alertData.patientName, 'fa-user');
        if (pNameItem) allPatientInfoContainer.appendChild(pNameItem);
        const otherPatientInfoRow = document.createElement('div');
        Object.assign(otherPatientInfoRow.style, {
            display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: '18px',
        });
        const pIdElem = createInfoItem('MRN', alertData.patientId, 'fa-id-card');
        if (pIdElem) otherPatientInfoRow.appendChild(pIdElem);
        const pLocElem = createInfoItem('Location', alertData.patientLocation, 'fa-hospital-alt');
        if (pLocElem) otherPatientInfoRow.appendChild(pLocElem);
        const pBarcodeElem = createInfoItem('Sample Barcode', alertData.sampleBarcode, 'fa-barcode');
        if (pBarcodeElem) otherPatientInfoRow.appendChild(pBarcodeElem);
        if (otherPatientInfoRow.hasChildNodes()) allPatientInfoContainer.appendChild(otherPatientInfoRow);
        if (allPatientInfoContainer.hasChildNodes()) modalBox.appendChild(allPatientInfoContainer);


        if (alertData.alertsToList && alertData.alertsToList.length > 0) {
            const alertsListTitle = document.createElement('h3');
            alertsListTitle.textContent = 'Alert Details:';
            Object.assign(alertsListTitle.style, { fontSize: '19px', fontWeight: '600', color: '#343a40', margin: '0 0 12px 0' });
            modalBox.appendChild(alertsListTitle);
            const alertsContainer = document.createElement('div');
            Object.assign(alertsContainer.style, {
                display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(280px, 1fr))',
                gap: '18px', padding: '5px 0'
            });
            alertData.alertsToList.forEach(alert => {
                const alertCard = document.createElement('div');
                let borderColorCard = '#6c757d', bgColorCard = '#f8f9fa';
                if (alert.type === 'critical') {
                    borderColorCard = alert.flag === 'CL' ? '#007bff' : (alert.flag === 'CH' ? '#dc3545' : '#d9534f');
                    bgColorCard = alert.flag === 'CL' ? '#e7f3ff' : (alert.flag === 'CH' ? '#f8d7da' : '#fdf7f7');
                } else if (alert.type === 'greaterThan') {
                    borderColorCard = '#ffc107'; bgColorCard = '#fff9e6';
                } else if (alert.type === 'noresult') {
                    borderColorCard = '#6c757d'; bgColorCard = '#f8f9fa';
                }
                Object.assign(alertCard.style, {
                    borderLeft: `6px solid ${borderColorCard}`, padding: '18px', borderRadius: '10px',
                    backgroundColor: bgColorCard, color: '#343a40', boxShadow: '0 5px 10px rgba(0,0,0,0.08)',
                    display: 'flex', flexDirection: 'column', justifyContent: 'space-between', minHeight: '130px'
                });
                const testNameElem = document.createElement('p');
                testNameElem.innerHTML = `<strong style="font-size: 17px; color: #212529;">${alert.testName}</strong>`;
                testNameElem.style.margin = '0 0 10px 0';
                alertCard.appendChild(testNameElem);
                const resultElem = document.createElement('p');
                resultElem.textContent = `Result: ${alert.result || 'N/A'}${alert.uom ? ` ${alert.uom}` : ''}`;
                resultElem.style.margin = '0 0 10px 0'; resultElem.style.fontSize = '15px';
                alertCard.appendChild(resultElem);
                if (alert.flag) {
                    const flagElem = document.createElement('p');
                    let flagDescription = `Flag: ${alert.flag}`;
                    if (alert.flag === 'CL') flagDescription = 'Flag: CL (Critical Low)';
                    else if (alert.flag === 'CH') flagDescription = 'Flag: CH (Critical High)';
                    else if (alert.flag === 'BG_CRITICAL') flagDescription = 'Flag: Critical (Red Background)';
                    flagElem.textContent = flagDescription;
                    Object.assign(flagElem.style, { margin: '0', fontSize: '15px', fontWeight: '600', color: borderColorCard });
                    alertCard.appendChild(flagElem);
                }
                if (alert.comment) {
                    const commentElem = document.createElement('p');
                    commentElem.textContent = alert.comment;
                    Object.assign(commentElem.style, {
                        fontSize: '13px', fontStyle: 'italic', color: '#555',
                        marginTop: '8px', paddingTop: '8px', borderTop: '1px dashed #ccc'
                    });
                    alertCard.appendChild(commentElem);
                }
                alertsContainer.appendChild(alertCard);
            });
            modalBox.appendChild(alertsContainer);
        } else if (alertData.primaryMessage) {
            const primaryMessageElem = document.createElement('p');
            primaryMessageElem.textContent = alertData.primaryMessage;
            Object.assign(primaryMessageElem.style, { fontSize: '16px', fontWeight: '500', margin: '12px 0', color: '#555' });
            modalBox.appendChild(primaryMessageElem);
        }

        if (alertData.overallSeverity === 'critical') {
            const notifiedDetailsDiv = document.createElement('div');
            Object.assign(notifiedDetailsDiv.style, { marginTop: '24px', paddingTop: '20px', borderTop: '1px solid #dee2e6' });
            const h3 = document.createElement('h3');
            h3.textContent = 'Notification Details (Critical)';
            Object.assign(h3.style, { fontSize: '17px', fontWeight: '600', marginBottom: '16px', color: '#343a40' });
            notifiedDetailsDiv.appendChild(h3);
            const formGrid = document.createElement('div');
            Object.assign(formGrid.style, { display: 'grid', gridTemplateColumns: '1fr', gap: '14px' });

            const userIdGroup = createFormGroup('User ID', 'userIdInput', 'Enter your User ID');
            formGrid.appendChild(userIdGroup);
            const userIdInputElem = userIdGroup.querySelector('#userIdInput');
            if (userIdInputElem && alertData.userId && alertData.userId !== 'N/A') userIdInputElem.value = alertData.userId;

            formGrid.appendChild(createFormGroup('Notified Person Name', 'notifiedPersonNameInput', 'Name of person notified'));
            formGrid.appendChild(createFormGroup('Extension / Contact', 'notifiedPersonTelExtInput', 'Phone or extension'));

            const readBackGroup = document.createElement('div');
            Object.assign(readBackGroup.style, { display: 'flex', alignItems: 'center', marginTop: '10px' });
            const readBackCheckbox = document.createElement('input');
            readBackCheckbox.type = 'checkbox'; readBackCheckbox.id = 'readBackCheckbox';
            Object.assign(readBackCheckbox.style, { marginRight: '10px', height: '18px', width: '18px', cursor: 'pointer', accentColor: '#007bff' });
            const readBackLabel = document.createElement('label');
            readBackLabel.textContent = 'Read-Back Confirmed'; readBackLabel.htmlFor = 'readBackCheckbox';
            Object.assign(readBackLabel.style, { fontSize: '14px', fontWeight: '500', color: '#495057', cursor: 'pointer' });
            readBackGroup.appendChild(readBackCheckbox); readBackGroup.appendChild(readBackLabel);
            formGrid.appendChild(readBackGroup);
            notifiedDetailsDiv.appendChild(formGrid);
            modalBox.appendChild(notifiedDetailsDiv);
        }

        const buttonContainer = document.createElement('div');
        Object.assign(buttonContainer.style, {
            display: 'flex', justifyContent: 'flex-end', paddingTop: '24px',
            marginTop: 'auto',
            gap: '12px', borderTop: '1px solid #dee2e6'
        });

        if (alertData.overallSeverity === 'critical') {
            const sendErrorMsg = document.createElement('p');
            sendErrorMsg.id = 'autoAlertSendErrorMsg';
            Object.assign(sendErrorMsg.style, {
                color: 'red', fontSize: '13px', margin: '0 auto 0 0',
                flexGrow: 1, alignSelf: 'center'
            });
            buttonContainer.appendChild(sendErrorMsg);

            const submitReportButton = createModalButton('Submit Report', 'success');
            submitReportButton.onclick = async () => {
                logAlertDebug("Submit Report button clicked for auto-alert modal.");
                sendErrorMsg.textContent = '';
                const success = await sendAlertDataToServer(alertData);
                if (success) {
                    logAlertDebug("Auto-alert data sent successfully. Closing modal.");
                    closeAlertModalAction();
                } else {
                    logAlertDebug("Auto-alert data send failed. Modal remains open.");
                    sendErrorMsg.textContent = 'Failed to save. Check server or try again.';
                }
            };
            buttonContainer.appendChild(submitReportButton);

            const cancelButton = createModalButton('Cancel', 'secondary');
            cancelButton.onclick = closeAlertModalAction;
            buttonContainer.appendChild(cancelButton);

        } else {
            const okButton = createModalButton('OK', 'primary');
            okButton.onclick = closeAlertModalAction;
            buttonContainer.appendChild(okButton);
        }
        modalBox.appendChild(buttonContainer);
        modalBox.dataset.alerts = JSON.stringify(alertsDisplayedInModal.map(a => ({ type: a.type, rowId: a.rowId })));


        overlay.appendChild(modalBox);
        document.body.appendChild(overlay);

        setTimeout(() => {
            overlay.style.opacity = '1';
            modalBox.style.opacity = '1';
            modalBox.style.transform = 'translateY(0) scale(1)';
            logAlertDebug("Alert modal fade-in and animation triggered.");
        }, 10);

        overlay.addEventListener('click', (event) => {
            if (event.target === overlay) closeAlertModalAction();
        });
        const escapeKeyListener = (event) => {
            if (event.key === 'Escape' && document.body.contains(overlay)) {
                closeAlertModalAction();
                document.removeEventListener('keydown', escapeKeyListener);
            }
        };
        document.addEventListener('keydown', escapeKeyListener);
    }

    function scrollToRowNearest(row) {
        if (!row) return false;
        let rowToScroll = row;
        if (row.closest('.ag-center-cols-container')) {
            const rowIndex = row.getAttribute('row-index');
            if (rowIndex) {
                const pinnedRow = document.querySelector(`.ag-pinned-left-cols-container .ag-row[row-index="${rowIndex}"]`);
                if (pinnedRow) rowToScroll = pinnedRow;
            }
        }
        document.documentElement.style.scrollBehavior = 'smooth';
        rowToScroll.scrollIntoView({ behavior: 'auto', block: 'center' });
        setTimeout(() => document.documentElement.style.scrollBehavior = 'auto', 500);
        return true;
    }

    async function getPatientDataWithRetry(selectors, maxWaitTime = 2500, checkInterval = 100) {
        logAlertDebug(`getPatientDataWithRetry CALLED. Max wait: ${maxWaitTime}ms. Selectors: ${JSON.stringify(selectors)}`);
        const startTime = performance.now();
        let elapsedTime = 0;
        let patientData = { patientName: 'N/A', patientId: 'N/A', patientLocation: 'N/A', sampleBarcode: 'N/A' };
        let attempt = 0;

        while (elapsedTime < maxWaitTime) {
            attempt++;
            const nameEl = document.querySelector(selectors.name);
            const barcodeEl = document.querySelector(selectors.barcode);

            logAlertDebug(`[Attempt ${attempt}] Name Element (${selectors.name}): ${nameEl ? 'Found' : 'NOT Found'}`);
            if (nameEl) {
                patientData.patientName = nameEl.textContent.trim().replace(/\s+/g, ' ') || 'N/A (empty)';
            } else {
                patientData.patientName = 'N/A (selector failed)';
            }

            let mrnValue = 'N/A (MRN not found)';
            let mrnFoundByNewLogic = false;
            const potentialMrnContainers = document.querySelectorAll('div.mid');
            potentialMrnContainers.forEach(container => {
                if (mrnFoundByNewLogic) return;
                const h6Elements = container.querySelectorAll('h6');
                h6Elements.forEach(h6 => {
                    if (mrnFoundByNewLogic) return;
                    const h6Text = h6.textContent.trim().toUpperCase();
                    if (h6Text.includes('C.MRN') || h6Text.includes('H.MRN')) {
                        const mrnSpanElement = container.querySelector('span');
                        if (mrnSpanElement && mrnSpanElement.textContent.trim()) {
                            const currentMrn = mrnSpanElement.textContent.trim();
                            if (h6Text.includes('C.MRN')) {
                                mrnValue = currentMrn; mrnFoundByNewLogic = true;
                            } else if (h6Text.includes('H.MRN') && mrnValue === 'N/A (MRN not found)') {
                                mrnValue = currentMrn; mrnFoundByNewLogic = true;
                            }
                        }
                    }
                });
            });
            if (!mrnFoundByNewLogic) {
                const mrnElOriginal = document.querySelector(selectors.mrn);
                if (mrnElOriginal && mrnElOriginal.textContent.trim()) {
                    mrnValue = mrnElOriginal.textContent.trim();
                } else {
                    mrnValue = mrnElOriginal ? 'N/A (original empty)' : 'N/A (original selector failed)';
                }
            }
            patientData.patientId = mrnValue;


            let locElement = document.querySelector('div.patient-info span[title*="UNIT/"]');
            if (!locElement) {
                locElement = document.querySelector(selectors.location);
            }

            if (locElement) {
                const titleAttr = locElement.getAttribute('title');
                if (titleAttr && titleAttr.includes('UNIT/') && titleAttr.trim() !== '') {
                    patientData.patientLocation = titleAttr.trim().replace(/\s+/g, ' ');
                } else if (titleAttr && titleAttr.trim() !== '') {
                     patientData.patientLocation = titleAttr.trim().replace(/\s+/g, ' ');
                } else {
                    const clone = locElement.cloneNode(true);
                    const h6InLoc = clone.querySelector('h6');
                    if (h6InLoc) h6InLoc.remove();
                    let cleanedText = clone.textContent.trim().replace(/\s+/g, ' ');
                    cleanedText = cleanedText.replace(/^Bed\s*/i, '').trim();
                    patientData.patientLocation = cleanedText || 'N/A (empty after cleaning)';
                }
                 if (patientData.patientLocation === '') patientData.patientLocation = 'N/A (empty string after processing)';
            } else {
                patientData.patientLocation = 'N/A (selector failed)';
            }


            if (barcodeEl) {
                patientData.sampleBarcode = barcodeEl.textContent.trim() || 'N/A (empty)';
            } else {
                patientData.sampleBarcode = 'N/A (selector failed)';
            }
            if (patientData.sampleBarcode === '') patientData.sampleBarcode = 'N/A (empty string)';


            const essentialPopulated = !patientData.patientName.startsWith('N/A') &&
                                     !patientData.patientId.startsWith('N/A') &&
                                     !patientData.patientLocation.startsWith('N/A');

            if (essentialPopulated) break;

            await new Promise(resolve => setTimeout(resolve, checkInterval));
            elapsedTime += checkInterval;
        }

        const allEssentialDataRetrieved = !patientData.patientName.startsWith('N/A') &&
                                          !patientData.patientId.startsWith('N/A') &&
                                          !patientData.patientLocation.startsWith('N/A');

        if (!allEssentialDataRetrieved) {
            logAlertError(`Essential patient data content NOT FULLY RETRIEVED after ${maxWaitTime}ms. Final state: ${JSON.stringify(patientData)}`);
        }

        const endTime = performance.now();
        logAlertDebug(`getPatientDataWithRetry finished in ${(endTime - startTime).toFixed(2)}ms. All essential: ${allEssentialDataRetrieved}. Final Data: ${JSON.stringify(patientData)}`);
        return { data: patientData, allEssentialDataRetrieved: allEssentialDataRetrieved };
    }


    async function checkForIssues() {
        const totalCheckStartTime = performance.now();
        logAlertDebug("checkForIssues started.");
        if (!isScanningActive || isAlertModalOpen || isReportModalOpen) {
            logAlertDebug(`checkForIssues aborted. isScanningActive: ${isScanningActive}, isAlertModalOpen: ${isAlertModalOpen}, isReportModalOpen: ${isReportModalOpen}`);
            return false;
        }

        const patientDataSelectors = {
            name: CONFIG_ALERTS.PATIENT_NAME_SELECTOR,
            mrn: CONFIG_ALERTS.PATIENT_MRN_SELECTOR,
            location: CONFIG_ALERTS.PATIENT_LOCATION_SELECTOR,
            barcode: CONFIG_ALERTS.SAMPLE_BARCODE_SELECTOR
        };
        const patientDataResult = await getPatientDataWithRetry(patientDataSelectors);
        const patientDataSource = patientDataResult.data;
        const allEssentialPatientDataAvailable = patientDataResult.allEssentialDataRetrieved;

        const patientName = patientDataSource.patientName;
        const patientId = patientDataSource.patientId;
        const patientLocation = patientDataSource.patientLocation;
        const sampleBarcode = patientDataSource.sampleBarcode;
        const userIdElement = document.querySelector(CONFIG_ALERTS.USER_NAME_SELECTOR);
        const currentUserId = userIdElement ? userIdElement.textContent.trim() : 'N/A';

        const centerRows = document.querySelectorAll('.ag-center-cols-container .ag-row');
        const pinnedRows = document.querySelectorAll('.ag-pinned-left-cols-container .ag-row');
        const potentialAlertsForAutoModal = [];

        centerRows.forEach((centerRow, index) => {
            const pinnedRow = pinnedRows[index];
            if (!centerRow || !pinnedRow || centerRow.offsetParent === null) return;

            const testDescElement = pinnedRow.querySelector('div[col-id="TestDesc"]');
            const testDesc = testDescElement?.textContent?.trim() || 'Unknown Test';
            const resultDiv = centerRow.querySelector(CONFIG_ALERTS.RESULT_CELL_SELECTOR);
            const flagSpan = centerRow.querySelector(CONFIG_ALERTS.CRITICAL_FLAG_SELECTOR);
            const uomCell = centerRow.querySelector(CONFIG_ALERTS.UOM_CELL_SELECTOR);
            const baseRowIdentifier = centerRow.getAttribute('row-id') || centerRow.getAttribute('row-index') || `scan_row_${index}`;
            const resultText = resultDiv?.textContent?.trim() || '';
            const uomText = uomCell?.textContent?.trim() || '';
            const normalizedResultText = resultText.toLowerCase().replace(/[- ]/g, '');
            const flagTextByIndicator = flagSpan?.textContent?.trim()?.toUpperCase() || '';

            let isCriticalByBackground = false;
            let effectiveFlagText = flagTextByIndicator;
            const resultCellElement = resultDiv ? resultDiv.closest('div[role="gridcell"][col-id="TestResult"]') : null;
            if (resultCellElement) {
                const bgColor = window.getComputedStyle(resultCellElement).backgroundColor;
                if (CONFIG_ALERTS.CRITICAL_BACKGROUND_COLORS.includes(bgColor.toLowerCase())) {
                    isCriticalByBackground = true;
                    if (!effectiveFlagText) effectiveFlagText = 'BG_CRITICAL';
                }
            }
            const isCriticalByFlag = (flagSpan && (flagTextByIndicator === "CL" || flagTextByIndicator === "CH"));
            const isCritical = isCriticalByFlag || isCriticalByBackground;
            const isNoResult = ["noresult", "noxresult", "x-noresult"].includes(normalizedResultText);
            const isDilution = resultText.includes(">");
            let alertType = null, alertMessage = "", alertComment = null;

            if (isCritical) {
                alertType = "critical";
                alertMessage = isCriticalByFlag ? `CRITICAL ${flagTextByIndicator === "CL" ? "LOW" : "HIGH"} RESULT!` : "CRITICAL RESULT (Visual Indicator)!";
            } else if (isNoResult) {
                alertType = "noresult"; alertMessage = CONFIG_ALERTS.NO_RESULT_MESSAGE;
            } else if (isDilution) {
                alertType = "greaterThan"; alertMessage = CONFIG_ALERTS.DILUTION_MESSAGE; alertComment = "Sample needs dilution";
            }

            if (alertType) {
                potentialAlertsForAutoModal.push({
                    rowElement: centerRow, type: alertType,
                    rowId: `${alertType}_${baseRowIdentifier}`,
                    baseIdentifier: baseRowIdentifier,
                    message: alertMessage, comment: alertComment, testName: testDesc,
                    result: resultText, uom: uomText, flag: effectiveFlagText,
                    alreadyNotified: hasAlreadyNotified(alertType, baseRowIdentifier)
                });
                applyFlashingEffect(centerRow); applyFlashingEffect(pinnedRow);
            } else {
                stopFlashingEffect(centerRow); stopFlashingEffect(pinnedRow);
            }
        });

        const newPotentialAlertsForAutoModalDisplay = potentialAlertsForAutoModal.filter(alert => !alert.alreadyNotified);

        if (newPotentialAlertsForAutoModalDisplay.length > 0 && !isAlertModalOpen && !document.getElementById('custom-alert-modal-overlay')) {
            if (!allEssentialPatientDataAvailable) {
                logAlertDebug("Potential new auto-alerts found, but essential patient data is incomplete. Deferring auto-alert modal display.");
            } else {
                const firstSignificantAlert = newPotentialAlertsForAutoModalDisplay.find(a => a.type === 'critical' || a.type === 'noresult' || a.type === 'greaterThan') ||
                                              newPotentialAlertsForAutoModalDisplay[0];
                scrollToRowNearest(firstSignificantAlert.rowElement);
                const modalData = {
                    alertsToList: newPotentialAlertsForAutoModalDisplay.map(a => ({
                        testName: a.testName, result: a.result, uom: a.uom, flag: a.flag,
                        type: a.type, rowId: a.rowId, comment: a.comment
                    })),
                    overallSeverity: firstSignificantAlert.type,
                    primaryMessage: firstSignificantAlert.message,
                    patientName, patientId, patientLocation, sampleBarcode, userId: currentUserId
                };
                createCustomAlert(modalData, newPotentialAlertsForAutoModalDisplay);
                logAlertDebug("Auto-alerts shown for patient. Pausing scanner if configured.");
                if (window.stopAlertsScanner) window.stopAlertsScanner();
            }
        } else if (potentialAlertsForAutoModal.length === 0) {
            document.querySelectorAll('.ag-center-cols-container .ag-row[data-flashing="true"]').forEach(stopFlashingEffect);
            document.querySelectorAll('.ag-pinned-left-cols-container .ag-row[data-flashing="true"]').forEach(stopFlashingEffect);
        }

        return (newPotentialAlertsForAutoModalDisplay.length > 0 && !isAlertModalOpen && !document.getElementById('custom-alert-modal-overlay') && allEssentialPatientDataAvailable);
    }


    function collectAllTestsWithResults() {
        logDebugMain("Collecting all tests with results for reporting...");
        const collectedTests = [];
        const centerRows = document.querySelectorAll(CONFIG_MAIN.SELECTORS.ALL_TEST_ROWS_CENTER);
        const pinnedRows = document.querySelectorAll(CONFIG_MAIN.SELECTORS.ALL_TEST_ROWS_PINNED);

        centerRows.forEach((centerRow, index) => {
            const pinnedRow = pinnedRows[index];
            if (!centerRow || !pinnedRow || centerRow.offsetParent === null) return;

            const testDescElement = pinnedRow.querySelector(CONFIG_MAIN.SELECTORS.TEST_DESC_CELL);
            const testName = testDescElement?.textContent?.trim() || 'Unknown Test';

            const resultDiv = centerRow.querySelector(CONFIG_MAIN.SELECTORS.TEST_RESULT_CELL_GENERAL);
            const result = resultDiv?.textContent?.trim() || 'N/A';

            const uomCell = centerRow.querySelector(CONFIG_MAIN.SELECTORS.TEST_UOM_CELL_GENERAL);
            const uom = uomCell?.textContent?.trim() || '';

            const flagSpan = centerRow.querySelector(CONFIG_MAIN.SELECTORS.TEST_FLAG_CELL_GENERAL);
            const flag = flagSpan?.textContent?.trim()?.toUpperCase() || '';

            const rowId = centerRow.getAttribute('row-id') || centerRow.getAttribute('row-index') || `test_report_row_${index}`;

            collectedTests.push({
                id: rowId,
                testName,
                result,
                uom,
                flag,
                selected: false
            });
        });
        logDebugMain(`Collected ${collectedTests.length} tests for reporting.`);
        return collectedTests;
    }

    function createReportSelectionModal(testsToDisplay, patientData, currentUserId) {
        logDebugMain(`--- createReportSelectionModal CALLED ---. isReportModalOpen: ${isReportModalOpen}. tests: ${testsToDisplay.length}.`);
        if (document.getElementById('report-selection-modal-overlay') || isReportModalOpen) {
            logDebugMain("Report selection modal already open or overlay element exists. Aborting."); return;
        }
        isReportModalOpen = true;
        logDebugMain("Report selection modal is now being created. isReportModalOpen = true.");

        const overlay = document.createElement('div');
        overlay.id = 'report-selection-modal-overlay';
        Object.assign(overlay.style, {
            position: 'fixed', top: '0', left: '0', width: '100%', height: '100%',
            backgroundColor: 'rgba(0, 0, 0, 0.65)', zIndex: '10002', display: 'flex',
            justifyContent: 'center', alignItems: 'center', opacity: '0',
            transition: 'opacity 0.3s ease-out', padding: '20px'
        });
        document.body.style.overflow = 'hidden';

        const modalBox = document.createElement('div');
        modalBox.id = 'report-selection-modal-content';
        Object.assign(modalBox.style, {
            backgroundColor: '#ffffff', borderRadius: '12px',
            boxShadow: '0 16px 32px rgba(0,0,0,0.1), 0 8px 16px rgba(0,0,0,0.08)',
            width: 'calc(100% - 40px)', maxWidth: '1000px', maxHeight: '90vh',
            overflowY: 'auto', padding: '32px', position: 'relative', opacity: '0',
            transform: 'translateY(-20px) scale(0.98)',
            transition: 'opacity 0.3s ease-out, transform 0.3s ease-out',
            fontFamily: "'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif",
            color: '#343a40', display: 'flex', flexDirection: 'column', gap: '16px'
        });

        const closeButtonX = document.createElement('button');
        closeButtonX.innerHTML = '&times;';
        Object.assign(closeButtonX.style, {
            position: 'absolute', top: '18px', right: '18px', fontSize: '30px', lineHeight: '1',
            cursor: 'pointer', color: '#adb5bd', background: 'transparent', border: 'none',
            padding: '0', width: '30px', height: '30px', display: 'flex',
            alignItems: 'center', justifyContent: 'center'
        });
        closeButtonX.onmouseover = () => closeButtonX.style.color = '#495057';
        closeButtonX.onmouseout = () => closeButtonX.style.color = '#adb5bd';
        closeButtonX.onclick = closeReportSelectionModalAction;
        modalBox.appendChild(closeButtonX);

        const headerDiv = document.createElement('div');
        Object.assign(headerDiv.style, {
            display: 'flex', alignItems: 'center', gap: '12px', paddingBottom: '18px',
            borderBottom: '1px solid #dee2e6', marginBottom: '16px'
        });
        const reportIcon = document.createElement('i');
        reportIcon.className = 'fas fa-file-signature';
        reportIcon.style.fontSize = '26px'; reportIcon.style.color = '#17a2b8';
        headerDiv.appendChild(reportIcon);
        const title = document.createElement('h2');
        title.textContent = 'Report Critical Test Results';
        Object.assign(title.style, { fontSize: '26px', fontWeight: '600', color: '#17a2b8', margin: '0' });
        headerDiv.appendChild(title);
        modalBox.appendChild(headerDiv);

        const createInfoItemLocal = (label, value, iconClass) => {
            if (!value) value = 'N/A';
            const itemDiv = document.createElement('div');
            Object.assign(itemDiv.style, {
                backgroundColor: '#f8f9fa', borderRadius: '8px', padding: '12px 16px',
                border: '1px solid #e9ecef', boxShadow: '0 2px 4px rgba(0,0,0,0.05)',
                display: 'flex', flexDirection: 'column', gap: '8px'
            });
            const header = document.createElement('div');
            Object.assign(header.style, { display: 'flex', alignItems: 'center', gap: '10px', color: '#495057' });
            if (iconClass) {
                const iconElem = document.createElement('i');
                iconElem.className = `fas ${iconClass}`;
                Object.assign(iconElem.style, { fontSize: '1.2em', color: '#007bff', width: '20px', textAlign: 'center' });
                header.appendChild(iconElem);
            }
            const labelElem = document.createElement('strong');
            labelElem.textContent = `${label}:`;
            labelElem.style.fontSize = '14px'; labelElem.style.fontWeight = '600';
            header.appendChild(labelElem);
            itemDiv.appendChild(header);
            const valueElem = document.createElement('span');
            valueElem.textContent = value;
            Object.assign(valueElem.style, {
                fontSize: '15px', color: '#212529', wordBreak: 'break-word',
                paddingLeft: iconClass ? '30px' : '0'
            });
            itemDiv.appendChild(valueElem);
            return itemDiv;
        };

        const pDataForModal = patientData || {};
        const patientInfoContainer = document.createElement('div');
        Object.assign(patientInfoContainer.style, {
            display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))',
            gap: '12px', paddingBottom: '18px', borderBottom: '1px solid #dee2e6', marginBottom: '16px'
        });
        patientInfoContainer.appendChild(createInfoItemLocal('Patient Name', pDataForModal.patientName, 'fa-user'));
        patientInfoContainer.appendChild(createInfoItemLocal('MRN', pDataForModal.patientId, 'fa-id-card'));
        patientInfoContainer.appendChild(createInfoItemLocal('Location', pDataForModal.patientLocation, 'fa-hospital-alt'));
        patientInfoContainer.appendChild(createInfoItemLocal('Sample Barcode', pDataForModal.sampleBarcode, 'fa-barcode'));
        modalBox.appendChild(patientInfoContainer);


        const testsListTitle = document.createElement('h3');
        testsListTitle.textContent = 'Select Tests to Include in Report:';
        Object.assign(testsListTitle.style, { fontSize: '19px', fontWeight: '600', color: '#343a40', margin: '0 0 12px 0' });
        modalBox.appendChild(testsListTitle);

        const testsContainer = document.createElement('div');
        testsContainer.id = 'report-tests-selection-container';
        Object.assign(testsContainer.style, {
            maxHeight: '300px', overflowY: 'auto', border: '1px solid #dee2e6',
            borderRadius: '8px', padding: '10px', marginBottom: '16px'
        });

        testsToDisplay.forEach(test => {
            const testItemDiv = document.createElement('div');
            testItemDiv.style.cssText = 'display: flex; align-items: center; padding: 10px 8px; border-bottom: 1px solid #e9ecef; gap: 10px; transition: background-color 0.2s;';
            const isCriticalTest = test.flag && (test.flag === 'CH' || test.flag === 'CL' || test.flag.includes('CRITICAL'));
            testItemDiv.onmouseover = () => testItemDiv.style.backgroundColor = '#f8f9fa';
            testItemDiv.onmouseout = () => testItemDiv.style.backgroundColor = isCriticalTest ? 'rgba(255, 0, 0, 0.05)' : 'transparent';
            if (isCriticalTest) {
                 testItemDiv.style.backgroundColor = 'rgba(255, 0, 0, 0.05)';
            }


            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox'; checkbox.id = `report_cb_${test.id}`;
            checkbox.checked = test.selected;
            checkbox.onchange = () => { test.selected = checkbox.checked; };
            Object.assign(checkbox.style, { marginRight: '5px', transform: 'scale(1.2)', cursor: 'pointer', accentColor: '#007bff' });

            const label = document.createElement('label');
            label.htmlFor = `report_cb_${test.id}`;
            label.style.cursor = 'pointer'; label.style.flexGrow = '1'; label.style.fontSize = '14px';
            let labelText = `<strong style="color: #333;">${test.testName}</strong>: ${test.result || 'N/A'}`;
            if (test.uom) labelText += ` ${test.uom}`;
            if (test.flag) labelText += ` <span style="color: ${test.flag === 'CL' ? '#007bff' : (test.flag === 'CH' ? '#dc3545' : '#d9534f')}; font-weight: bold;">(${test.flag})</span>`;
            label.innerHTML = labelText;

            testItemDiv.appendChild(checkbox);
            testItemDiv.appendChild(label);
            testsContainer.appendChild(testItemDiv);
        });
        modalBox.appendChild(testsContainer);

        const reportDetailsDiv = document.createElement('div');
        Object.assign(reportDetailsDiv.style, { marginTop: '10px', paddingTop: '16px', borderTop: '1px solid #dee2e6' });
        const detailsTitle = document.createElement('h4');
        detailsTitle.textContent = 'Reporting Details (If Applicable)';
        Object.assign(detailsTitle.style, { fontSize: '16px', fontWeight: '600', marginBottom: '12px', color: '#343a40' });
        reportDetailsDiv.appendChild(detailsTitle);

        const formGrid = document.createElement('div');
        Object.assign(formGrid.style, { display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '14px' });
        const userIdGroup = createFormGroup('Your User ID', 'reportUserIdInput', 'Your system User ID');
        const userIdInputElem = userIdGroup.querySelector('#reportUserIdInput');
        if (userIdInputElem && currentUserId && currentUserId !== 'N/A') userIdInputElem.value = currentUserId;
        formGrid.appendChild(userIdGroup);
        formGrid.appendChild(createFormGroup('Notified Person (Name)', 'reportNotifiedPersonNameInput', 'Person contacted'));
        formGrid.appendChild(createFormGroup('Extension / Contact Info', 'reportNotifiedPersonTelExtInput', 'Phone or extension'));
        const readBackGroup = document.createElement('div');
        Object.assign(readBackGroup.style, { display: 'flex', alignItems: 'center', marginTop: '10px', gridColumn: '1 / -1' });
        const readBackCheckbox = document.createElement('input');
        readBackCheckbox.type = 'checkbox'; readBackCheckbox.id = 'reportReadBackCheckbox';
        Object.assign(readBackCheckbox.style, { marginRight: '10px', height: '18px', width: '18px', cursor: 'pointer', accentColor: '#007bff'});
        const readBackLabel = document.createElement('label');
        readBackLabel.textContent = 'Read-Back Confirmed'; readBackLabel.htmlFor = 'reportReadBackCheckbox';
        Object.assign(readBackLabel.style, { fontSize: '14px', fontWeight: '500', color: '#495057', cursor: 'pointer' });
        readBackGroup.appendChild(readBackCheckbox); readBackGroup.appendChild(readBackLabel);
        formGrid.appendChild(readBackGroup);
        reportDetailsDiv.appendChild(formGrid);
        modalBox.appendChild(reportDetailsDiv);

        const buttonContainer = document.createElement('div');
        Object.assign(buttonContainer.style, {
            display: 'flex', justifyContent: 'flex-end', paddingTop: '24px',
            marginTop: 'auto', gap: '12px', borderTop: '1px solid #dee2e6'
        });
        const submitReportButton = createModalButton('Submit Report', 'success');
        submitReportButton.onclick = async () => {
            const selectedTests = testsToDisplay.filter(t => t.selected);
            if (selectedTests.length === 0) {
                alert("Please select at least one test to report."); return;
            }
            const reportedUserId = document.getElementById('reportUserIdInput')?.value || currentUserId;
            const notifiedPerson = document.getElementById('reportNotifiedPersonNameInput')?.value || '';
            const notifiedContact = document.getElementById('reportNotifiedPersonTelExtInput')?.value || '';
            const readBackConfirmed = document.getElementById('reportReadBackCheckbox')?.checked || false;
            const pDataForPayload = patientData || {};

            const reportDataPayload = {
                entryID: getNextEntryID(),
                date: new Date().toLocaleDateString('en-GB'),
                time: new Date().toLocaleTimeString('en-US', { hour: '2-digit', minute: '2-digit', hour12: true }),
                patientName: pDataForPayload.patientName || 'N/A',
                patientMRN: pDataForPayload.patientId || 'N/A',
                patientLocation: pDataForPayload.patientLocation || 'N/A',
                sampleBarcode: pDataForPayload.sampleBarcode || 'N/A',
                userName: reportedUserId,
                notifiedPersonName: notifiedPerson,
                notifiedPersonTelExt: notifiedContact,
                readBack: readBackConfirmed,
                alerts: selectedTests.map(st => ({
                    testName: st.testName,
                    result: st.result,
                    uom: st.uom,
                    flag: st.flag,
                    type: 'user_reported_critical',
                    comment: 'Manually selected by user for critical reporting.'
                })),
            };
            logDebugMain("Manual Report Payload:", JSON.stringify(reportDataPayload, null, 2));
            const serverSuccess = await sendAlertDataToServer(reportDataPayload);
            if (serverSuccess) {
                alert("Critical results reported successfully and saved to server.");
                closeReportSelectionModalAction();
            } else {
                 alert("Critical results logged to console. FAILED to save to server. Please ensure the local server is running or check console for errors.");
            }
        };
        buttonContainer.appendChild(submitReportButton);
        const cancelButton = createModalButton('Cancel', 'secondary');
        cancelButton.onclick = closeReportSelectionModalAction;
        buttonContainer.appendChild(cancelButton);
        modalBox.appendChild(buttonContainer);

        overlay.appendChild(modalBox); document.body.appendChild(overlay);
        setTimeout(() => {
            overlay.style.opacity = '1';
            modalBox.style.opacity = '1'; modalBox.style.transform = 'translateY(0) scale(1)';
        }, 10);
        overlay.addEventListener('click', (event) => { if (event.target === overlay) closeReportSelectionModalAction(); });
        const escapeKeyListenerReport = (event) => {
            if (event.key === 'Escape' && document.body.contains(overlay)) {
                closeReportSelectionModalAction(); document.removeEventListener('keydown', escapeKeyListenerReport);
            }
        };
        document.addEventListener('keydown', escapeKeyListenerReport);
    }

    function closeReportSelectionModalAction() {
        logDebugMain("closeReportSelectionModalAction triggered.");
        const overlay = document.getElementById('report-selection-modal-overlay');
        if (overlay) {
            overlay.style.opacity = '0';
            const modalContent = overlay.querySelector('#report-selection-modal-content');
            if (modalContent) { modalContent.style.opacity = '0'; modalContent.style.transform = 'translateY(-30px) scale(0.95)'; }
            overlay.addEventListener('transitionend', () => {
                if (overlay.parentNode) {
                    overlay.parentNode.removeChild(overlay);
                }
                isReportModalOpen = false;
                document.body.style.overflow = ''; logDebugMain("Report selection modal overlay removed.");
            }, { once: true });
             setTimeout(() => {
                if (overlay && overlay.parentNode) {
                    overlay.parentNode.removeChild(overlay);
                }
                if(isReportModalOpen) {
                    isReportModalOpen = false; document.body.style.overflow = '';
                }
            }, 400);
        } else {
            isReportModalOpen = false;
            document.body.style.overflow = '';
        }
    }


    function startAlertsScannerInternal() {
        logAlertDebug("startAlertsScannerInternal called.");
        if (isScanningActive && issueScanIntervalId === null) {
            logAlertDebug("Alert Scanner starting/resuming...");
            checkForIssues();
            issueScanIntervalId = setInterval(checkForIssues, CONFIG_ALERTS.SCAN_INTERVAL);
        } else if (!isScanningActive && issueScanIntervalId === null) {
             logAlertDebug("Alert Scanner starting fresh (isScanningActive was false)...");
             isScanningActive = true;
             checkForIssues();
             issueScanIntervalId = setInterval(checkForIssues, CONFIG_ALERTS.SCAN_INTERVAL);
        }
    }

    function stopAlertsScannerInternal() {
        logAlertDebug("stopAlertsScannerInternal called (pause behavior).");
        if (issueScanIntervalId !== null) {
            clearInterval(issueScanIntervalId);
            issueScanIntervalId = null;
        }
    }

    window.startAlertsScanner = startAlertsScannerInternal;
    window.stopAlertsScanner = stopAlertsScannerInternal;

    let previousObservedUrl = window.location.href;
    const pageUrlObserver = new MutationObserver(() => {
        const newObservedUrl = window.location.href;
        if (newObservedUrl !== previousObservedUrl) {
            logDebugMain(`URL changed from: ${previousObservedUrl} to: ${newObservedUrl}.`);
            const wasOnEditPage = previousObservedUrl.startsWith(CONFIG_MAIN.URLS.EDIT_PAGE_PREFIX);
            const nowOnEditPage = newObservedUrl.startsWith(CONFIG_MAIN.URLS.EDIT_PAGE_PREFIX);

            if (wasOnEditPage && !nowOnEditPage) {
                logDebugMain("Navigated AWAY from edit page. Stopping scanner, clearing flags, removing UI.");
                isScanningActive = false;
                if (window.stopAlertsScanner) window.stopAlertsScanner();
                try {
                    const oldUrlObject = new URL(previousObservedUrl, window.location.origin);
                    const oldPageKeyPrefix = `labAlertNotified_${oldUrlObject.pathname}${oldUrlObject.hash}_`;
                    Object.keys(sessionStorage)
                        .filter(key => key.startsWith(oldPageKeyPrefix))
                        .forEach(key => {
                            logAlertDebug(`Removing sessionStorage key: ${key}`);
                            sessionStorage.removeItem(key);
                        });
                } catch (e) { logAlertError(`Error processing old URL for flag clearing: ${e}`);}
                const customButtons = document.getElementById('custom-script-buttons'); if (customButtons) customButtons.remove();
                const alertOverlay = document.getElementById('custom-alert-modal-overlay'); if (alertOverlay) alertOverlay.remove(); isAlertModalOpen = false;
                const reportOverlay = document.getElementById('report-selection-modal-overlay'); if (reportOverlay) reportOverlay.remove(); isReportModalOpen = false;
                document.body.style.overflow = '';
            }

            if (nowOnEditPage) {
                logDebugMain("Navigated TO an edit page. Resetting states, (re)starting scanner, adding UI.");
                hasScrolledToOrderedRow = false;
                isAlertModalOpen = false; isReportModalOpen = false;
                const existingAlertOverlay = document.getElementById('custom-alert-modal-overlay'); if (existingAlertOverlay) existingAlertOverlay.remove();
                const existingReportOverlay = document.getElementById('report-selection-modal-overlay'); if (existingReportOverlay) existingReportOverlay.remove();
                document.body.style.overflow = '';

                if (!isScanningActive) { isScanningActive = true; }
                setTimeout(() => {
                    if (window.startAlertsScanner) window.startAlertsScanner();
                    addButtons();
                    addFontAwesome();
                    monitorOrderedStatus(); // Initial check on new page
                }, 700);
            } else {
                const customButtons = document.getElementById('custom-script-buttons'); if (customButtons) customButtons.remove();
                if (isScanningActive) {
                    isScanningActive = false;
                    if (window.stopAlertsScanner) window.stopAlertsScanner();
                }
            }
            previousObservedUrl = newObservedUrl;
        } else { // URL hasn't changed, but mutations occurred.
            const stillOnEditPage = newObservedUrl.startsWith(CONFIG_MAIN.URLS.EDIT_PAGE_PREFIX);
            if (stillOnEditPage) {
                if (!document.getElementById('custom-script-buttons')) {
                    addButtons(); // Re-add buttons if missing
                }
                addFontAwesome(); // Ensure FontAwesome is still there

                // Call debounced monitorOrderedStatus to update button based on current grid state
                debouncedMonitorOrderedStatus(); // MODIFIED: Call debounced version

                if (isScanningActive && issueScanIntervalId === null && window.startAlertsScanner) {
                    window.startAlertsScanner();
                }
                else if (!isScanningActive && window.startAlertsScanner) {
                    isScanningActive = true; window.startAlertsScanner();
                }
            }
        }
    });
    pageUrlObserver.observe(document.body, { childList: true, subtree: true });

    if (isCorrectPage()) {
        isScanningActive = true;
        setTimeout(() => {
            if (window.startAlertsScanner) window.startAlertsScanner();
            addFontAwesome();
            addButtons();
            monitorOrderedStatus(); // Initial check
        }, 700);
    } else {
        isScanningActive = false;
    }

    setInterval(checkUrlAndTriggerClickForUndefined, CONFIG_MAIN.CHECK_INTERVALS.UNDEFINED_URL);
    setInterval(checkForDisabledButtons, CONFIG_MAIN.CHECK_INTERVALS.DISABLED_BTN_CHECK);

})();

// User's SAMPLES COUNT Logic (IIFE)
(function () {
    'use strict';
    const SCRIPT_PREFIX_SAMPLES = "[SAMPLES COUNT 통합]";
    const logSampleCountDebug = msg => console.debug(`${SCRIPT_PREFIX_SAMPLES} ${msg}`);

    function createCounterElementSamples(id) {
        const wrapper = document.createElement('span');
        wrapper.id = id;
        Object.assign(wrapper.style, {
            display: 'inline-flex', alignItems: 'center', padding: '6px 12px',
            backgroundColor: '#e9ecef', borderRadius: '20px',
            boxShadow: '0 2px 5px rgba(0,0,0,0.1)', marginRight: 'auto',
            marginLeft: '10px', fontSize: '14px', fontWeight: '500',
            color: '#495057', verticalAlign: 'middle'
        });
        const label = document.createElement('span');
        label.textContent = 'SAMPLES COUNT: ';
        label.style.marginRight = '8px';
        const badge = document.createElement('span');
        badge.className = 'sample-count-badge'; badge.textContent = '0';
        Object.assign(badge.style, {
            backgroundColor: '#6c757d', color: '#ffffff', padding: '4px 10px',
            borderRadius: '12px', fontSize: '14px', fontWeight: 'bold',
            minWidth: '26px', textAlign: 'center', lineHeight: '1'
        });
        wrapper.appendChild(label); wrapper.appendChild(badge);
        return wrapper;
    }

    function updateSpecificCounterSamples(modalElementForInputs, counterElement, inputSelector) {
        const badge = counterElement.querySelector('.sample-count-badge');
        if (!badge || !modalElementForInputs || !document.body.contains(modalElementForInputs) || !counterElement.isConnected) return;

        const inputs = modalElementForInputs.querySelectorAll(inputSelector);
        const count = inputs.length;
        badge.textContent = count;
        badge.style.backgroundColor = count > 0 ? '#28a745' : '#6c757d';
    }

    function setupModalCounterSamples(modalConfig) {
        const { modalKeyElement, targetFooter, counterId, inputSelector, activeIntervalsMap, buttonIdForLog } = modalConfig;
        if (targetFooter.querySelector('#' + counterId)) {
            return false;
        }

        const counter = createCounterElementSamples(counterId);
        targetFooter.insertBefore(counter, targetFooter.firstChild);

        const modalElementForInputs = modalKeyElement.querySelector('.modal-body') || modalKeyElement.querySelector('.modal-content') || modalKeyElement;

        const interval = setInterval(() => {
            const modalStillTracked = document.body.contains(modalKeyElement);
            const counterStillPresent = counter.isConnected;

            let modalVisible = false;
            if (modalStillTracked && modalKeyElement instanceof Element) {
                modalVisible = modalKeyElement.classList.contains('show') || modalKeyElement.classList.contains('modal-open') ||
                               (modalKeyElement.style && modalKeyElement.style.display && modalKeyElement.style.display !== 'none') ||
                               (modalKeyElement.style && !modalKeyElement.style.display && modalKeyElement.offsetParent !== null);
            }

            if (!modalStillTracked || !counterStillPresent || !modalVisible) {
                clearInterval(interval);
                activeIntervalsMap.delete(modalKeyElement);
                if (counter.isConnected) counter.remove();
                return;
            }
            updateSpecificCounterSamples(modalElementForInputs, counter, inputSelector);
        }, 500);

        activeIntervalsMap.set(modalKeyElement, { interval, counterId });
        return true;
    }


    function observeModalsSamples() {
        const activeModalIntervals = new Map();

        const getModalKeyDetails = (el) => {
            if (!el || !(el instanceof Element)) return "non-element";
            const tagName = el.tagName || "UNKNOWN_TAG";
            let className = "";
            if (el.className && typeof el.className === 'string') {
                className = el.className.trim().replace(/\s+/g, '.');
            } else if (el.className && typeof el.className.baseVal === 'string') {
                className = el.className.baseVal.trim().replace(/\s+/g, '.');
            }
            return `${tagName}${className ? '.' + className : ''}`;
        };


        const observer = new MutationObserver(() => {
            const modalConfigs = [
                {
                    buttonSelector: 'button#btnclose-smplcollection',
                    logId: 'btnclose-smplcollection',
                    counterIdSuffix: 'smplcollection',
                    inputSelector: 'tbody[formarrayname="TubeTypeList"] input[formcontrolname="PatientID"]'
                },
                {
                    buttonSelector: 'button#closebtn-smplrecieve',
                    logId: 'closebtn-smplrecieve',
                    counterIdSuffix: 'smplrecieve',
                    inputSelector: 'td input[formcontrolname="PatientID"]'
                }
            ];

            modalConfigs.forEach(config => {
                const button = document.querySelector(config.buttonSelector);
                if (button) {
                    const footer = button.closest('.modal-footer');
                    if (footer) {
                        const modalKeyElement = footer.closest('.modal.show, .modal-dialog, modal-container.show');
                        if (modalKeyElement && !activeModalIntervals.has(modalKeyElement)) {
                            setupModalCounterSamples({
                                ...config,
                                modalKeyElement: modalKeyElement,
                                targetFooter: footer,
                                activeIntervalsMap: activeModalIntervals
                            });
                        }
                    }
                }
            });

            activeModalIntervals.forEach((data, modalElemKey) => {
                if (!(modalElemKey instanceof Element)) {
                    clearInterval(data.interval);
                    const counterElem = document.getElementById(data.counterId);
                    if (counterElem && counterElem.isConnected) counterElem.remove();
                    activeModalIntervals.delete(modalElemKey);
                    return;
                }

                const modalStillPresent = document.body.contains(modalElemKey);
                const counterElem = document.getElementById(data.counterId);

                let modalStillVisible = false;
                if (modalStillPresent) {
                     modalStillVisible = modalElemKey.classList.contains('show') || modalElemKey.classList.contains('modal-open') ||
                                       (modalElemKey.style.display && modalElemKey.style.display !== 'none') ||
                                       (!modalElemKey.style.display && modalElemKey.offsetParent !== null);
                }


                if (!modalStillPresent || !modalStillVisible) {
                    clearInterval(data.interval);
                    if (counterElem && counterElem.isConnected) counterElem.remove();
                    activeModalIntervals.delete(modalElemKey);
                } else if (counterElem && !counterElem.isConnected) {
                    clearInterval(data.interval);
                    activeModalIntervals.delete(modalElemKey);
                }
            });
        });

        observer.observe(document.body, { childList: true, subtree: true });
    }

    window.addEventListener('load', () => {
        try {
            observeModalsSamples();
        } catch (e) {
            console.error(`${SCRIPT_PREFIX_SAMPLES} Error initializing modal observer: ${e.message} \n${e.stack}`);
        }
    });

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址