Unified Lab Assistant (Enhanced Grid & Auto-Verify)

Merges "Enhanced AG Grid" and "Conditional Auto & Manual VERIFY2" functionalities. Adds a unified summary table, auto-verification, improved UI styling, and QoL features, all optimized for performance in a Single-Page Application (SPA) environment.

As of 2025-07-05. See the latest version.

// ==UserScript==
// @name         Unified Lab Assistant (Enhanced Grid & Auto-Verify)
// @version      14.0.1
// @description  Merges "Enhanced AG Grid" and "Conditional Auto & Manual VERIFY2" functionalities. Adds a unified summary table, auto-verification, improved UI styling, and QoL features, all optimized for performance in a Single-Page Application (SPA) environment.
// @match        https://his.kaauh.org/lab/*
// @author       Hamad AlShegifi (Merged and Optimized by Gemini)
// @grant        GM_addStyle
// @namespace    http://tampermonkey.net/
// ==/UserScript==


(function() {
    'use strict';

    // Create a global namespace for inter-IIFE communication
    window.enhancedGrid = window.enhancedGrid || {};

    // --- Feature: Enhanced AG Grid ---

    // --- Global Constants (AG Grid) ---
    const GRID_WIDTH = '54vw'; // Target width for main content areas
    const RESIZED_FLAG = 'data-ag-resized'; // Custom attribute to mark AG-Grids
    const INTERVAL = 300; // Interval for periodic scanning
    const CLICKED_ROW_EXPIRY_PREFIX = 'clicked_row_expiry_';
    const CLICK_DURATION_MS = 60 * 1000; // 1 minute for row highlight

    // --- Utility Functions ---
    const debounce = (func, wait) => {
        let timeout;
        return function executedFunction(...args) {
            const later = () => {
                clearTimeout(timeout);
                func(...args);
            };
            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    };

    // --- Inject CSS Styles (AG Grid) ---
    GM_addStyle(`
        @import url('https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css');

        /* --- General Layout & Resizing --- */
        .results .ag-theme-balham,
        .accd-details,
        .accd-details-table-static,
        .card-header {
            width: ${GRID_WIDTH} !important;
            margin-left: auto !important;
            margin-right: 0 !important;
            box-sizing: border-box;
        }
        .accd-details table,
        .accd-details-table-static table {
            width: 100% !important;
            table-layout: fixed !important;
            border-collapse: collapse !important;
        }
        .accd-details table th, .accd-details table td,
        .accd-details-table-static table th, .accd-details-table-static table td {
            padding: 8px !important;
            word-wrap: break-word !important;
        }
        .results .ag-theme-balham {
            height: auto;
        }

        /* --- AG-Grid Row and Cell Styles --- */
        .ag-row {
            transition: background-color 0.3s ease;
        }
        .ag-row.clicked-row-green .ag-cell {
            background-color: #A0ECA0 !important;
        }
    `);

    // --- AG-Grid Column Definitions ---
    const columnsToUncheck = [
        'Lab Order No', 'Hospital MRN', 'DOB', 'Test ID', 'National/Iqama Id', 'Department',
        'Doctor', 'Analyzer', 'Reference Lab', 'Accession No', 'Sequence No', 'Age',
        'Container Type', 'Storage Condition'
    ];
    let hasRunOnce = false;

    // --- AG-Grid Row Highlight Logic ---
    function handleRowClickForPersistentGreen(event) {
        const cellElement = event.target.closest('.ag-cell');
        if (!cellElement) return;
        const rowElement = cellElement.closest('.ag-row[role="row"]');
        if (!rowElement) return;
        const barcodeCell = rowElement.querySelector('div[col-id="barcode"]');
        if (!barcodeCell || !barcodeCell.textContent) return;
        const barcode = barcodeCell.textContent.trim();
        if (!barcode) return;
        const expiryTimestamp = Date.now() + CLICK_DURATION_MS;
        try {
            localStorage.setItem(CLICKED_ROW_EXPIRY_PREFIX + barcode, expiryTimestamp.toString());
        } catch (e) {
            console.error("Error saving to localStorage:", e);
        }
        applyPersistentRowStyles();
    }

    function applyPersistentRowStyles() {
        const rows = document.querySelectorAll('.ag-center-cols-container div[role="row"], .ag-pinned-left-cols-container div[role="row"], .ag-pinned-right-cols-container div[role="row"]');
        const now = Date.now();
        rows.forEach(row => {
            const barcodeCell = row.querySelector('div[col-id="barcode"]');
            let rowBarcode = barcodeCell?.textContent?.trim();
            if (rowBarcode) {
                const expiryKey = CLICKED_ROW_EXPIRY_PREFIX + rowBarcode;
                const expiryTimestampStr = localStorage.getItem(expiryKey);
                if (expiryTimestampStr) {
                    if (now < parseInt(expiryTimestampStr, 10)) row.classList.add('clicked-row-green');
                    else {
                        localStorage.removeItem(expiryKey);
                        row.classList.remove('clicked-row-green');
                    }
                } else row.classList.remove('clicked-row-green');
            } else row.classList.remove('clicked-row-green');
        });
        try {
            for (let i = 0; i < localStorage.length; i++) {
                const key = localStorage.key(i);
                if (key?.startsWith(CLICKED_ROW_EXPIRY_PREFIX)) {
                    if (now >= parseInt(localStorage.getItem(key), 10)) localStorage.removeItem(key);
                }
            }
        } catch (e) {
            console.error("Error during localStorage cleanup:", e);
        }
    }

    function setupPersistentRowStylesListener() {
        const gridRoot = document.querySelector('.ag-root-wrapper');
        const listenerTarget = gridRoot || document.querySelector('.ag-body-viewport') || document.body;
        if (listenerTarget && !listenerTarget.dataset.persistentClickListenerAttached) {
            listenerTarget.addEventListener('click', handleRowClickForPersistentGreen, true);
            listenerTarget.dataset.persistentClickListenerAttached = 'true';
        }
    }

    // --- AG-Grid Column Visibility Logic ---
    function isSpecificPageForColumns() {
        return window.location.href.endsWith('/#/lab-orders/lab-test-analyzer');
    }

    function areColumnsChecked() {
        return columnsToUncheck.some(column => isColumnChecked(column));
    }

    function isColumnChecked(labelText) {
        for (const label of document.querySelectorAll('.ag-column-tool-panel-column-label')) {
            if (label.textContent.trim() === labelText && label.parentElement.querySelector('.ag-icon-checkbox-checked')) return true;
        }
        return false;
    }

    function ensureColumnsUnchecked() {
        if (hasRunOnce || !isSpecificPageForColumns() || !areColumnsChecked()) return;
        hasRunOnce = true;
        setTimeout(() => columnsToUncheck.forEach(clickColumnLabel), 1000);
    }

    function ensureOtherColumnsChecked() {
        if (!isSpecificPageForColumns()) return;
        document.querySelectorAll('.ag-column-tool-panel-column-label').forEach(label => {
            if (!columnsToUncheck.includes(label.textContent.trim()) && label.parentElement.querySelector('.ag-icon-checkbox-unchecked')) label.click();
        });
    }

    function clickColumnLabel(labelText) {
        if (!isSpecificPageForColumns()) return;
        document.querySelectorAll('.ag-column-tool-panel-column-label').forEach(label => {
            if (label.textContent.trim() === labelText && label.parentElement.querySelector('.ag-icon-checkbox-checked')) label.click();
        });
    }

    function initColumnToggle() {
        if (!isSpecificPageForColumns()) return;
        let attempts = 0;
        const interval = setInterval(() => {
            if (document.querySelector('.ag-side-buttons') || ++attempts > 10) {
                if (document.querySelector('.ag-side-buttons')) {
                    ensureColumnsUnchecked();
                    ensureOtherColumnsChecked();
                }
                clearInterval(interval);
            }
        }, 500);
    }

    // --- Layout and Main Update Orchestration ---
    const performLayoutAdjustments = () => {
        const actionButtonContainer = document.querySelector('div.lo-act-btn');
        if (actionButtonContainer && actionButtonContainer.parentElement) {
            actionButtonContainer.parentElement.removeAttribute('style');
        }

        document.querySelectorAll('ag-grid-angular').forEach(grid => {
            if (grid.getAttribute(RESIZED_FLAG)) return;
            const api = grid.agGrid?.api || grid.__agGridComp?.api;
            if (api && typeof api.sizeColumnsToFit === 'function') {
                grid.style.width = GRID_WIDTH;
                grid.style.marginLeft = 'auto';
                grid.style.marginRight = '0';
                api.sizeColumnsToFit();
                grid.setAttribute(RESIZED_FLAG, 'true');
            }
        });
        document.querySelectorAll('div.accd-details-table-static.test-open, .card-header').forEach(el => {
            el.style.width = GRID_WIDTH;
            el.style.marginLeft = 'auto';
            el.style.marginRight = '0';
        });
        document.querySelectorAll('h6[translateid="test-results.Results"]').forEach(el => el.remove());
    };

    const fullPageUpdate = debounce(() => {
        performLayoutAdjustments();
        applyPersistentRowStyles();
        setupPersistentRowStylesListener();
        if (window.enhancedGrid && typeof window.enhancedGrid.triggerSummaryUpdate === 'function') {
            window.enhancedGrid.triggerSummaryUpdate();
        }
        if (isSpecificPageForColumns()) {
            hasRunOnce = false;
            initColumnToggle();
        }
    }, 100);


    // --- Feature: Barcode Display Box ---
    (function() {
        const BARCODE_KEY = 'selectedBarcode';
        let currentUrl = location.href;

        function loadJsBarcode(callback) {
            if (window.JsBarcode) {
                callback();
                return;
            }
            const script = document.createElement('script');
            script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/JsBarcode.all.min.js';
            script.onload = callback;
            document.head.appendChild(script);
        }

        function insertBarcodeBox(barcode) {
            let insertionTarget = document.querySelector('.btn-area.stickey-btnset') || document.querySelector('.test-open.mt-2');
            if (!barcode || !insertionTarget || document.getElementById('barcode-display-box')) return;
            const box = document.createElement('div');
            box.id = 'barcode-display-box';
            box.style.cssText = 'padding:8px 12px;background:#f7f7f7;border-radius:8px;display:flex;align-items:center;gap:10px;border:1px solid #ccc;';
            const label = document.createElement('div');
            label.textContent = 'Sample Barcode:';
            label.style.cssText = 'font-weight:bold;font-size:14px;color:#333;';
            const text = document.createElement('div');
            text.textContent = barcode;
            text.style.cssText = 'font-size: 20px; color: #444; font-weight: bold;';
            const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
            svg.id = "barcode-svg";
            svg.style.cssText = 'height:40px;width:120px;border:1px solid #ccc;border-radius:4px;padding:2px;';
            box.append(label, text, svg);
            insertionTarget.insertAdjacentElement('afterend', box);
            try {
                const buttonBarStyles = window.getComputedStyle(insertionTarget);
                if (buttonBarStyles.position === 'sticky' || buttonBarStyles.position === 'fixed') {
                    const buttonBarHeight = insertionTarget.offsetHeight;
                    const buttonBarTop = parseInt(buttonBarStyles.top, 10) || 0;
                    const desiredTopForBarcode = buttonBarTop + buttonBarHeight + 5;
                    Object.assign(box.style, {
                        position: 'sticky',
                        top: `${desiredTopForBarcode}px`,
                        zIndex: '99',
                        boxShadow: '0 3px 5px rgba(0,0,0,0.08)',
                    });
                } else box.style.marginTop = '10px';
            } catch (e) {
                console.error("Enhanced AG Grid: Error applying sticky style to barcode box.", e);
                box.style.marginTop = '10px';
            }
            loadJsBarcode(() => {
                try {
                    JsBarcode(svg, barcode, {
                        format: "CODE128",
                        displayValue: false,
                        height: 40,
                        width: 2,
                        margin: 0
                    });
                } catch (err) {
                    console.warn('Barcode render error:', err);
                    svg.outerHTML = "<span>Invalid Barcode</span>";
                }
            });
        }

        function watchGridClicksForBarcodeBox() {
            document.body.addEventListener('click', e => {
                const cell = e.target.closest('.ag-row')?.querySelector('[col-id="barcode"]');
                if (cell?.textContent.trim()) localStorage.setItem(BARCODE_KEY, cell.textContent.trim());
            });
        }

        function waitAndShowBarcode() {
            const barcode = localStorage.getItem(BARCODE_KEY);
            const urlPattern = /\/0\/.*\/undefined$/;
            if (!barcode || !urlPattern.test(location.href)) return;
            const interval = setInterval(() => {
                const ready = document.querySelector('.btn-area.stickey-btnset') || document.querySelector('.test-open.mt-2');
                if (ready) {
                    clearInterval(interval);
                    insertBarcodeBox(barcode);
                }
            }, 300);
        }

        function observeSPA() {
            const bodyObserver = new MutationObserver(() => {
                if (location.href !== currentUrl) {
                    currentUrl = location.href;
                    waitAndShowBarcode();
                }
            });
            bodyObserver.observe(document.body, {
                childList: true,
                subtree: true
            });
        }
        watchGridClicksForBarcodeBox();
        observeSPA();
        waitAndShowBarcode();
    })();


    // --- Feature: Dropdown Pagination ---
    (function() {
        const setDropdownValue = () => {
            const dropdown = document.getElementById("dropdownPaginationPageSize");
            if (dropdown && dropdown.value !== "100") {
                dropdown.value = "100";
                dropdown.dispatchEvent(new Event('change', {
                    bubbles: true
                }));
            }
        };
        new MutationObserver(setDropdownValue).observe(document.body, {
            childList: true,
            subtree: true
        });
        window.addEventListener('load', setDropdownValue);
    })();


    // --- Feature: Unified Test Summary Table ---
    (function() {
        GM_addStyle(`
            #test-summary-container {
                width: 40%; float: left; margin: 25px 10px 10px 0;
                background-color: #fff; border: 1px solid #ddd; border-radius: 6px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.08); display: flex; flex-direction: column;
            }
           .card-body::after { content: ""; display: table; clear: both; }
            #test-summary-container .summary-content { padding: 0; position: relative; flex-grow: 1; }
            .summary-header {
                font-weight: 500; font-size: 12px; padding: 8px 10px;
                border-bottom: 1px solid #e0e0e0; display: flex; align-items: center; gap: 10px;
                color: #000000; cursor: pointer; user-select: none; flex-shrink: 0;
            }
            .summary-header > span {
               flex-grow: 1;
            }
            .summary-status-icon {
                margin-left: auto;
                margin-right: 5px;
                font-size: 1.2em;
            }
            .summary-header i.vicon.fa-check-circle { color: #28a745; }
            .summary-header i.vicon.fa-star { color: #6c757d; }
            .summary-header i.vicon.fa-arrow-circle-up.ord { color: #17a2b8; }
            .summary-header i.vicon.fa-arrow-circle-up:not(.ord) { color: #007bff; }

            .collapse-icon {
                transition: color 0.2s ease-in-out;
                color: #28a745;
            }
            .collapse-icon.collapsed {
                color: #dc3545;
            }
            .no-tests { padding: 20px; color: #6c757d; text-align: center; }
            .hidden-note { color: #dc3545; font-style: italic; }
            .test-list-container { display: contents; }
            .hidden-note-container { display: none; }
            #test-summary-container .summary-content.collapsed { display: none; }
            #test-summary-container .summary-content.collapsed .test-list-container { display: none; }
            #test-summary-container .summary-content.collapsed .hidden-note-container { display: block; }
            .summary-grid-container {
                display: grid;
                grid-template-columns: 1fr minmax(80px, auto) minmax(80px, auto) min-content min-content;
                align-items: start;
            }
            .summary-grid-header { display: contents; font-weight: bold; }
            .summary-grid-header > div {
                background-color: #f0f0f0; padding: 6px 15px; border-bottom: 1px solid #e0e0e0;
                white-space: nowrap; color: #555; font-size: 12px;
                position: sticky; top: 0; z-index: 1;
            }
            .summary-grid-header > div.test-name-header { text-align: left; }
            .summary-grid-header > div.test-value-header { text-align: right; }
            .summary-grid-header > div.range-header { text-align: left; }
            .summary-grid-header > div.uom-header { text-align: left; }
            .summary-grid-header > div.flag-header { text-align: center; }
            .test-item { display: contents; }
            .grid-cell {
                padding: 4px 15px; border-bottom: 1px solid #f0f0f0; font-size: 13px;
                display: flex; align-items: center; min-height: 28px;
                overflow: hidden; text-overflow: ellipsis;
            }
            .test-item:last-of-type > .grid-cell { border-bottom: none; }
            .grid-cell.test-details { gap: 8px; }
            .grid-cell.pending-value { justify-content: right; color: #999; }
            .test-name { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
            .test-icon { color: #28a745; }
            .test-bullet { color: #dc3545; }
            .test-value {
                font-weight: bold; color: #000000; border-radius: 4px;
                font-size: 13px; text-align: right; padding: 2px 4px;
                justify-content: flex-end; width: 100%;
            }
            .test-value.highlight-H { background-color: #ffe0e0 !important; }
            .test-value.highlight-L { background-color: #e0f2f7 !important; }
            .test-uom { font-size: 12px; color: #555; }
            .grid-cell.flag-cell { justify-content: center; }
            .flag {
                font-weight: bold; border-radius: 50%; width: 16px; height: 16px;
                display: inline-flex; align-items: center; justify-content: center;
                font-size: 11px; color: white; flex-shrink: 0;
            }
            .flag-placeholder { width: 16px; height: 16px; visibility: hidden; flex-shrink: 0; }
            .flag-H { background-color: #d32f2f !important; }
            .flag-L { background-color: #1976d2 !important; }
            .summary-footer {
                display: flex; justify-content: space-between; align-items: center; background: #f8f9fa;
                border-top: 1px solid #e0e0e0; padding: 10px 15px; font-size: 12px; color: #6c757d;
                flex-shrink: 0;
            }
        `);

        const CONFIG = {
            COLUMN_PATTERNS: {
                TEST_DESC: ['testdesc', 'testdescription', 'name'],
                STATUS: ['resultstatus', 'teststatus', 'status', 'state'],
                RESULT_VALUE: ['testresult'],
                UOM: ['uom', 'uomvalue'],
                REFERENCE_RANGE: ['referencerange', 'range']
            },
            STATUS_PROPERTIES: {
                resulted: {
                    color: '#ffca77',
                    className: 'fa fa-check-circle vicon'
                },
                ordered: {
                    color: '#E0E0E0',
                    className: 'fa fa-star vicon'
                },
                verifiedlevel1: {
                    color: '#90EE90',
                    className: 'fa fa-arrow-circle-up ord vicon'
                },
                verifiedlevel2: {
                    color: '#28a745',
                    className: 'fa fa-arrow-circle-up vicon'
                },
                default: {
                    color: '#E0E0E0',
                    className: null
                }
            }
        };
        const collapseState = {};

        const testSortOrder = [
            'sodium (na)', 'potassium', 'chloride', 'urea (bun)', 'creatinine', 'calcium',
            'phosphate (phos)', 'magnesium (mg)', 'alkaline phosphatase (alpi)',
            'Alanine Amino Transferase (ALTI)', 'Aspartate Amino Transferase(AST)',
            'total protein (tp)', 'albumin (alb)', 'Bilirubin - Total (TBIL)',
            'Bilirubin - Direct (DBIL)', 'cholesterol', 'triglycerides',
            'high density lipoprotein - hdl', 'low density lipoprotein - ldl',
            'creatine kinase (ck)', 'lactate dehydrogenase (ldh)', 'troponin -i (ctn-1)',
            'haemoglobin a1c (hba1c)', 'tsh (thyroid stimulating hormone)-tft', 'uric acid',
            'mid stream urine'
        ];

        function getSortIndex(testName) {
            const lowerTestName = testName.toLowerCase();
            const index = testSortOrder.findIndex(sortedName => lowerTestName.includes(sortedName.toLowerCase()));
            return index === -1 ? Infinity : index;
        }

        const findCellByPatterns = (row, patterns) => {
            for (const cell of row.querySelectorAll('[col-id]')) {
                const colId = cell.getAttribute('col-id')?.toLowerCase();
                if (colId && patterns.includes(colId)) return cell;
            }
            return null;
        };
        const parseRangeAndCompare = (rangeStr, value) => {
            if (!rangeStr || value === null || isNaN(parseFloat(value))) return null;
            const numVal = parseFloat(value);
            const stdRange = rangeStr.match(/(\d+\.?\d*)\s*-\s*(\d+\.?\d*)/);
            if (stdRange) {
                const lower = parseFloat(stdRange[1]);
                const upper = parseFloat(stdRange[2]);
                if (numVal < lower) return 'L';
                if (numVal > upper) return 'H';
            }
            const ltRange = rangeStr.match(/(?:<|Less than)\s*(\d+\.?\d*)/i);
            if (ltRange) {
                if (numVal >= parseFloat(ltRange[1])) return 'H';
            }
            const gtRange = rangeStr.match(/(?:>|Greater than)\s*(\d+\.?\d*)/i);
            if (gtRange) {
                if (numVal <= parseFloat(gtRange[1])) return 'L';
            }
            return null;
        };
        const capitalize = (s) => {
            if (typeof s !== 'string' || s.length === 0) return '';
            const spaced = s.replace(/([A-Z])|([0-9]+)/g, ' $1$2').trim();
            return spaced.charAt(0).toUpperCase() + spaced.slice(1);
        };
        const getNormalizedStatusKey = (status) => {
            const normalized = status.toLowerCase().replace(/\s+/g, '');
            if (normalized.includes('verified') && normalized.includes('1')) return 'verifiedlevel1';
            if (normalized.includes('verified') && normalized.includes('2')) return 'verifiedlevel2';
            if (normalized === 'resulted') return 'resulted';
            if (normalized === 'ordered') return 'ordered';
            return 'default';
        };

        function getAllTests() {
            const testsByStatus = {};
            const leftRows = document.querySelectorAll('.ag-pinned-left-cols-container .ag-row');
            const centerRows = document.querySelectorAll('.ag-center-cols-container .ag-row');
            const rightRows = document.querySelectorAll('.ag-pinned-right-cols-container .ag-row');
            const combinedRows = [];
            for (let i = 0; i < centerRows.length; i++) {
                const combined = document.createElement('div');
                [leftRows[i], centerRows[i], rightRows[i]].forEach(p => {
                    if (p) p.querySelectorAll('[col-id]').forEach(c => combined.appendChild(c.cloneNode(true)));
                });
                combinedRows.push(combined);
            }
            const uniqueTests = new Map();
            for (const [index, combined] of combinedRows.entries()) {
                const nameCell = findCellByPatterns(combined, CONFIG.COLUMN_PATTERNS.TEST_DESC);
                const testName = nameCell?.textContent?.trim();
                if (!testName) continue;
                const statusCell = findCellByPatterns(combined, CONFIG.COLUMN_PATTERNS.STATUS);
                const status = statusCell?.textContent?.trim().toLowerCase() || 'unknown';
                let data = {
                    name: testName,
                    status: status,
                    value: null,
                    uom: null,
                    range: null,
                    flag: null,
                    originalIndex: index
                };
                const valCell = findCellByPatterns(combined, CONFIG.COLUMN_PATTERNS.RESULT_VALUE);
                const rangeCell = findCellByPatterns(combined, CONFIG.COLUMN_PATTERNS.REFERENCE_RANGE);
                const uomCell = findCellByPatterns(combined, CONFIG.COLUMN_PATTERNS.UOM);
                data.value = valCell?.textContent?.trim() || null;
                data.range = rangeCell?.textContent?.trim() || null;
                data.uom = uomCell?.textContent?.trim() || null;
                data.flag = parseRangeAndCompare(data.range, data.value);
                uniqueTests.set(testName, data);
            }
            uniqueTests.forEach(data => {
                if (!testsByStatus[data.status]) testsByStatus[data.status] = [];
                testsByStatus[data.status].push(data);
            });
            return testsByStatus;
        }

        const renderList = (list) => {
            if (list.length === 0) return `<div class="no-tests" style="grid-column: 1 / -1;">No tests in this category.</div>`;
            const headerHtml = `
                <div class="summary-grid-header">
                    <div class="test-name-header">Test Name</div>
                    <div class="test-value-header">Result</div>
                    <div class="range-header">Ref Range</div>
                    <div class="uom-header">UOM</div>
                    <div class="flag-header">H/L</div>
                </div>`;
            const itemsHtml = list.map(t => {
                const iconHtml = t.status.includes('result') ? `<span class="test-icon">✓</span>` : `<span class="test-bullet">●</span>`;
                const resultCellHtml = (t.value !== null && t.value !== undefined) ? `<div class="grid-cell test-value ${t.flag ? 'highlight-' + t.flag : ''}">${t.value}</div>` : `<div class="grid-cell pending-value">${capitalize(t.status)}</div>`;
                return `
                    <div class="test-item" title="${t.name} (${capitalize(t.status)})">
                        <div class="grid-cell test-details">${iconHtml}<span class="test-name">${t.name}</span></div>
                        ${resultCellHtml}
                        <div class="grid-cell test-range">${t.range || '-'}</div>
                        <div class="grid-cell test-uom">${t.uom || '-'}</div>
                        <div class="grid-cell flag-cell"><span class="flag ${t.flag ? 'flag-' + t.flag : 'flag-placeholder'}">${t.flag || ''}</span></div>
                    </div>`;
            }).join('');
            return headerHtml + itemsHtml;
        };

        function updateSummaryContent(containerEl) {
            if (!containerEl) return;
            const testsByStatus = getAllTests();
            const statusOrder = ['resulted', 'ordered', 'verifiedlevel1', 'verifiedlevel2'];
            const sortedStatuses = Object.keys(testsByStatus).sort((a, b) => {
                const keyA = getNormalizedStatusKey(a);
                const keyB = getNormalizedStatusKey(b);
                const indexA = statusOrder.indexOf(keyA);
                const indexB = statusOrder.indexOf(keyB);
                if (indexA === -1 && indexB === -1) return a.localeCompare(b);
                if (indexA === -1) return 1;
                if (indexB === -1) return -1;
                return indexA - indexB;
            });

            let contentHtml = '';
            let totalTests = 0;
            if (sortedStatuses.length === 0) {
                contentHtml = `<div class="no-tests">No tests found on this page.</div>`;
            } else {
                sortedStatuses.forEach(status => {
                    const testList = testsByStatus[status];
                    if (testList.length === 0) return;

                    testList.sort((a, b) => {
                        const indexA = getSortIndex(a.name);
                        const indexB = getSortIndex(b.name);
                        if (indexA === indexB) {
                            return a.originalIndex - b.originalIndex;
                        }
                        return indexA - indexB;
                    });

                    totalTests += testList.length;
                    collapseState[status] = collapseState[status] ?? false;
                    const isCollapsed = collapseState[status];
                    const collapseIconClass = isCollapsed ? 'fa-arrow-circle-right' : 'fa-arrow-circle-down';
                    const statusDisplayName = capitalize(status);
                    const normalizedKey = getNormalizedStatusKey(status);
                    const properties = CONFIG.STATUS_PROPERTIES[normalizedKey] || CONFIG.STATUS_PROPERTIES.default;
                    const headerColor = properties.color;
                    const statusIconHtml = properties.className ? `<i class="${properties.className} summary-status-icon"></i>` : '';
                    contentHtml += `
                        <div class="summary-header" data-section="${status}" style="background-color: ${headerColor};">
                            <i class="fas ${collapseIconClass} collapse-icon ${isCollapsed ? 'collapsed' : ''}"></i>
                            <span>${statusDisplayName} (${testList.length})</span>
                            ${statusIconHtml}
                        </div>
                        <div id="${status.replace(/\s+/g, '-')}-tests-content" class="summary-content ${isCollapsed ? 'collapsed' : ''}">
                             <div class="summary-grid-container test-list-container">${renderList(testList)}</div>
                             <div class="hidden-note-container">
                                 ${testList.length > 0 ? `<div class="no-tests hidden-note">${testList.length} ${statusDisplayName} tests hidden</div>` : ''}
                             </div>
                        </div>`;
                });
            }
            const now = new Date();
            containerEl.innerHTML = contentHtml + `
                <div class="summary-footer">
                    <span>Total Tests: ${totalTests}</span>
                    <span>Updated: ${now.toLocaleDateString([], {month: 'short', day: 'numeric'})} ${now.toLocaleTimeString([], { hour: '2-digit', minute:'2-digit' })}</span>
                </div>`;
        }

        const summaryContainer = document.createElement('div');
        summaryContainer.id = 'test-summary-container';
        summaryContainer.addEventListener('click', e => {
            const header = e.target.closest('.summary-header');
            if (!header) return;
            const section = header.dataset.section;
            if (section) {
                collapseState[section] = !collapseState[section];
                const content = document.getElementById(`${section.replace(/\s+/g, '-')}-tests-content`);
                const icon = header.querySelector('.collapse-icon');
                if (content && icon) {
                    content.classList.toggle('collapsed', collapseState[section]);
                    icon.classList.toggle('collapsed', collapseState[section]);
                    icon.classList.toggle('fa-arrow-circle-down', !collapseState[section]);
                    icon.classList.toggle('fa-arrow-circle-right', collapseState[section]);
                }
            }
        });

        let insertionIntervalId = null;
        const isTargetPageForSummary = () => /\/0\/.*\/undefined$/.test(window.location.href);
        const removeSummaryContainer = () => {
            const container = document.getElementById(summaryContainer.id);
            if (container) {
                Object.assign(container.style, {
                    position: '',
                    top: '',
                    zIndex: ''
                });
                container.remove();
            }
        };
        const attemptInsertion = () => {
            let targetElement = document.getElementById('barcode-display-box') || document.querySelector('.test-open.mt-2');
            if (!targetElement || document.getElementById(summaryContainer.id)) return false;
            targetElement.insertAdjacentElement('afterend', summaryContainer);
            try {
                const barcodeBox = document.getElementById('barcode-display-box');
                if (barcodeBox) {
                    const barcodeBoxStyles = window.getComputedStyle(barcodeBox);
                    if (barcodeBoxStyles.position === 'sticky') {
                        const barcodeBoxHeight = barcodeBox.offsetHeight;
                        const barcodeBoxTop = parseInt(barcodeBoxStyles.top, 10) || 0;
                        const summaryTopPosition = barcodeBoxTop + barcodeBoxHeight + 10;
                        Object.assign(summaryContainer.style, {
                            position: 'sticky',
                            top: `${summaryTopPosition}px`,
                            zIndex: '98'
                        });
                    }
                }
            } catch (e) {
                console.error("Enhanced AG Grid: Error applying sticky style to summary container.", e);
            }
            return true;
        };
        const startInsertionPolling = () => {
            if (insertionIntervalId !== null) return;
            insertionIntervalId = setInterval(() => {
                if (attemptInsertion()) {
                    clearInterval(insertionIntervalId);
                    insertionIntervalId = null;
                    if (window.enhancedGrid && window.enhancedGrid.triggerSummaryUpdate) window.enhancedGrid.triggerSummaryUpdate();
                }
            }, 500);
        };
        const stopInsertionPolling = () => {
            if (insertionIntervalId !== null) {
                clearInterval(insertionIntervalId);
                insertionIntervalId = null;
            }
        };
        const manageSummaryTableLifecycle = () => {
            if (isTargetPageForSummary()) startInsertionPolling();
            else {
                stopInsertionPolling();
                removeSummaryContainer();
            }
        };
        window.enhancedGrid.triggerSummaryUpdate = () => {
            const container = document.getElementById(summaryContainer.id);
            if (container && isTargetPageForSummary()) updateSummaryContent(container);
        };
        const observeSpaUrlChangesForSummary = () => {
            let lastHandledUrl = location.href;
            const checkUrlChange = () => {
                if (location.href !== lastHandledUrl) {
                    lastHandledUrl = location.href;
                    manageSummaryTableLifecycle();
                }
            };
            const bodyObserver = new MutationObserver(checkUrlChange);
            bodyObserver.observe(document.body, {
                childList: true,
                subtree: true
            });
        };
        observeSpaUrlChangesForSummary();
        manageSummaryTableLifecycle();
    })();


    // --- Feature: Conditional Auto & Manual VERIFY2 ---

    // --- Configuration (Auto Verify) ---
    const VERIFIED1_STATUS_TEXT = 'Verified 1';
    const RESULTED_STATUS_TEXT = 'Resulted';
    const STATUS_CELL_SELECTOR = 'div[col-id="ResultStatus"]';
    const VERIFY1_BUTTON_SELECTOR = 'button.verify1-btn';
    const VERIFY2_BUTTON_SELECTOR = 'button.verify2-btn';
    const HISTORY_BUTTON_SELECTOR = 'button.backBtn[translateid="edit-lab-order.HistoryResults"]';
    const VERIFICATION_MODAL_SELECTOR = '.modal-content';
    const CHECK_INTERVAL_MS = 2000;

    // --- State Management (Auto Verify) ---
    let isAutoVerifyEnabled = true;
    let isVerificationProcessStarted = false;
    let hasAutoClicked = false;
    let autoVerifyInterval;

    // --- Core Logic (Auto Verify) ---
    function clickVerifyButton() {
        const verifyButton = document.querySelector(VERIFY2_BUTTON_SELECTOR);
        if (verifyButton) {
            console.log('Script Action: "VERIFY2" button found. Clicking it.');
            verifyButton.click();
        } else {
            console.log('Script Action: "VERIFY2" button not found on the page.');
        }
    }

    function hasResultedStatus() {
        const statusCells = document.querySelectorAll(STATUS_CELL_SELECTOR);
        for (const cell of statusCells) {
            if (cell.textContent && cell.textContent.trim().includes(RESULTED_STATUS_TEXT)) {
                return true;
            }
        }
        return false;
    }

    function hasVerified1Status() {
        const statusCells = document.querySelectorAll(STATUS_CELL_SELECTOR);
        for (const cell of statusCells) {
            if (cell.textContent && cell.textContent.trim().includes(VERIFIED1_STATUS_TEXT)) {
                return true;
            }
        }
        return false;
    }

    function isModalVisible() {
        const modal = document.querySelector(VERIFICATION_MODAL_SELECTOR);
        if (modal) {
            const modalTitle = modal.querySelector('h4.modal-title');
            if (modalTitle && modalTitle.textContent.trim() === 'Primary Verification') {
                return true;
            }
        }
        return false;
    }

    function runSafetyChecks() {
        if (isModalVisible()) {
            console.log('Safety Check: Blocked by modal.');
            return false;
        }
        if (hasResultedStatus()) {
            console.log(`Safety Check: Blocked by "${RESULTED_STATUS_TEXT}" status.`);
            return false;
        }
        return true;
    }

    function checkAndAutoClick() {
        if (!isAutoVerifyEnabled || !isVerificationProcessStarted || hasAutoClicked) return;
        if (!runSafetyChecks()) return;
        if (hasVerified1Status()) {
            console.log(`Auto-Verify: Found "${VERIFIED1_STATUS_TEXT}". Clicking VERIFY2.`);
            clickVerifyButton();
            hasAutoClicked = true;
        }
    }

    // --- UI Redesign and Injection (Auto Verify) ---
    function injectAutoVerifyStyles() {
        const styleId = 'auto-verify-modern-styles';
        if (document.getElementById(styleId)) return;

        const styleSheet = document.createElement("style");
        styleSheet.id = styleId;
        styleSheet.innerText = `
            .auto-verify-toggle {
                display: inline-flex;
                align-items: center;
                gap: 12px;
                padding: 6px 10px;
                border: 1px solid #ccc;
                border-radius: 20px;
                background-color: #f8f9fa;
                cursor: pointer;
                transition: background-color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
                user-select: none;
            }
            .auto-verify-toggle.is-active {
                border-color: #7ab5ff;
                background-color: #e7f1ff;
                animation: pulse-glow 2s infinite;
            }
            .toggle-label {
                font-size: 12px;
                font-weight: 600;
                color: #333;
                display: flex;
                align-items: center;
                gap: 6px;
            }
            .toggle-switch {
                position: relative;
                width: 40px;
                height: 22px;
                background-color: #ccc;
                border-radius: 11px;
                transition: background-color 0.3s ease;
            }
            .auto-verify-toggle.is-active .toggle-switch {
                background-color: #007bff;
            }
            .toggle-thumb {
                position: absolute;
                top: 2px;
                left: 2px;
                width: 18px;
                height: 18px;
                background-color: white;
                border-radius: 50%;
                box-shadow: 0 1px 3px rgba(0,0,0,0.2);
                transition: transform 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
            }
            .auto-verify-toggle.is-active .toggle-thumb {
                transform: translateX(18px);
            }

            @keyframes pulse-glow {
                0% { box-shadow: 0 0 0 0px rgba(0, 123, 255, 0.3); }
                70% { box-shadow: 0 0 0 8px rgba(0, 123, 255, 0); }
                100% { box-shadow: 0 0 0 0px rgba(0, 123, 255, 0); }
            }
        `;
        document.head.appendChild(styleSheet);
    }

    function updateVerifyUI() {
        const toggle = document.getElementById('autoVerifyToggleContainer');
        if (toggle) {
            if (isAutoVerifyEnabled) {
                toggle.classList.add('is-active');
            } else {
                toggle.classList.remove('is-active');
            }
        }

        const verify2Button = document.querySelector(VERIFY2_BUTTON_SELECTOR);
        if (verify2Button) {
            if (!verify2Button.dataset.redesigned) {
                verify2Button.textContent = 'VERIFY2 (F8)';
                Object.assign(verify2Button.style, {
                    display: 'inline-flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    fontWeight: '500',
                    transition: 'border-color 0.3s ease'
                });
                verify2Button.dataset.redesigned = 'true';
            }
            verify2Button.style.borderColor = isAutoVerifyEnabled ? '#007bff' : '';
        }
    }

    function redesignHistoryButton() {
        const historyButton = document.querySelector(HISTORY_BUTTON_SELECTOR);
        if (!historyButton || historyButton.dataset.redesigned) return;

        historyButton.innerHTML = `<span style="margin-right: 6px;">🕒</span> View History`;
        historyButton.title = "Click to view patient's full lab history";
        Object.assign(historyButton.style, {
            display: 'inline-flex',
            alignItems: 'center',
            fontWeight: '500'
        });
        historyButton.dataset.redesigned = 'true';
    }

    function injectModernToggle() {
        const historyButton = document.querySelector(HISTORY_BUTTON_SELECTOR);
        if (!historyButton || document.getElementById('autoVerifyToggleContainer')) return;

        const buttonParent = historyButton.parentElement;
        const toggleContainer = document.createElement('div');
        toggleContainer.id = 'autoVerifyToggleContainer';
        toggleContainer.className = 'auto-verify-toggle';

        toggleContainer.innerHTML = `
            <span class="toggle-label">
                <span style="font-size: 14px;">🤖</span>
                <span>AUTO VERIFY 2</span>
            </span>
            <div class="toggle-switch">
                <div class="toggle-thumb"></div>
            </div>
        `;

        toggleContainer.addEventListener('click', () => {
            isAutoVerifyEnabled = !isAutoVerifyEnabled;
            console.log(`Auto-Verify: ${isAutoVerifyEnabled ? 'ENABLED' : 'DISABLED'}.`);
            updateVerifyUI();
        });

        Object.assign(toggleContainer.style, {
            marginRight: '15px',
            verticalAlign: 'middle'
        });

        buttonParent.insertBefore(toggleContainer, historyButton);
    }

    // --- Event Listeners and Initialization (Auto Verify) ---
    function handleKeyPress(event) {
        if (event.key === 'F8') {
            event.preventDefault();
            console.log('Hotkey: F8 pressed.');
            if (runSafetyChecks()) {
                clickVerifyButton();
            }
        }
    }

    function handlePageClick(event) {
        if (event.target.closest(VERIFY1_BUTTON_SELECTOR)) {
            isVerificationProcessStarted = true;
            hasAutoClicked = false;
            console.log('Auto-Verify: VERIFY1 clicked. Process activated.');
        }
    }

    // --- Combined Initialization and SPA Handling ---
    let debounceTimer;

    function runAllUpdates() {
        // From "Enhanced AG Grid"
        fullPageUpdate();

        // From "Conditional Auto Verify"
        injectModernToggle();
        redesignHistoryButton();
        updateVerifyUI();
    }

    console.log('Combined Lab Enhancement script loaded.');

    // Initial style injections
    injectAutoVerifyStyles();

    // Set up event listeners
    document.addEventListener('keydown', handleKeyPress);
    document.addEventListener('click', handlePageClick);

    // Set up intervals
    autoVerifyInterval = setInterval(checkAndAutoClick, CHECK_INTERVAL_MS);
    setInterval(fullPageUpdate, INTERVAL); // From Enhanced AG Grid

    // Combined MutationObserver for SPA navigation
    let lastUrl = location.href;
    const spaObserver = new MutationObserver(() => {
        if (location.href !== lastUrl) {
            lastUrl = location.href;
            document.querySelectorAll('ag-grid-angular').forEach(grid => grid.removeAttribute(RESIZED_FLAG));
        }
        clearTimeout(debounceTimer);
        debounceTimer = setTimeout(runAllUpdates, 200); // Debounce all updates
    });

    spaObserver.observe(document.body, {
        childList: true,
        subtree: true
    });
    console.log('Combined SPA-aware observer started.');

    // Initial run to place all elements
    setTimeout(runAllUpdates, 500);

})();