{% extends "base.html" %}

{% block content %}
<style>
    /* General Button Styles */
    .btn-outline-dark-blue { border-color: #0a3d62; color: #0a3d62; }
    .btn-outline-dark-blue:hover { background-color: #0a3d62; color: white; }
    .btn-dark-blue { background-color: #0a3d62; border-color: #0a3d62; color: white; }
    .btn-dark-blue.active { background-color: #083152; border-color: #083152; } /* Keep active style */
    .btn-outline-success { border-color: #28a745; color: #28a745; }
    .btn-outline-success:hover { background-color: #28a745; color: white; }
    .btn-success { background-color: #28a745; border-color: #28a745; color: white; }
    .btn-success.active { background-color: #1e7e34; border-color: #1e7e34; } /* Keep active style */

    /* --- Rest of the styles remain unchanged --- */

    /* Attempt to fix font rendering glitch in example format select */
    .opblock-section.responses-section .example-media-type-select { font-family: Arial, Helvetica, sans-serif !important; }

    /* Operation Block */
    .opblock { margin-bottom: 10px; border: 1px solid #dee2e6; border-radius: 4px; background: #fff; }
    .opblock-summary { display: flex; align-items: center; padding: 10px; cursor: pointer; background: #f8f9fa; border-bottom: 1px solid #dee2e6; }
    .opblock-summary:hover { background: #e9ecef; }
    .opblock-summary-method { width: 80px; text-align: center; color: white; padding: 5px; border-radius: 12px; font-size: 0.9em; margin-right: 10px; }
    .opblock-summary-method.get { background: #61affe; }
    .opblock-summary-method.post { background: #49cc90; }
    .opblock-summary-method.put { background: #fca130; }
    .opblock-summary-method.delete { background: #f93e3e; }
    .opblock-summary-method.patch { background: #50e3c2; }
    .opblock-summary-path { flex-grow: 1; font-family: monospace; font-size: 1em; margin-right: 10px; word-break: break-all; }
    .opblock-summary-description { flex-grow: 2; font-size: 0.9em; color: #333; margin-right: 10px; }
    .opblock-body { padding: 15px; display: none; border-top: 1px solid #dee2e6; }
    .opblock.is-open .opblock-body { display: block; }
    .opblock-section { margin-bottom: 20px; }
    .opblock-section:last-child { margin-bottom: 0; }
    .opblock-section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; border-bottom: 1px solid #eee; padding-bottom: 5px; }
    .opblock-title { font-size: 1.1em; font-weight: bold; margin: 0; }
    .arrow { width: 20px; height: 20px; transition: transform 0.2s; margin-left: auto; }
    .opblock.is-open .arrow { transform: rotate(180deg); }

    /* Try it out / Execute */
    .try-out__btn { background-color: #007bff; color: white; border: none; padding: 5px 10px; border-radius: 4px; cursor: pointer; }
    .try-out__btn.cancel { background-color: #dc3545; }
    .execute__btn { background-color: #28a745; color: white; border: none; padding: 8px 15px; border-radius: 4px; cursor: pointer; margin-top: 15px; display: none; font-weight: bold; }
    .execute__btn:disabled { background-color: #6c757d; cursor: not-allowed; }

    /* Parameters */
    .parameters-container { margin-bottom: 15px; }
    .parameters-table { width: 100%; border-collapse: collapse; }
    .parameters-table th, .parameters-table td { border: 1px solid #dee2e6; padding: 8px; text-align: left; vertical-align: top; }
    .parameters-col_name { width: 20%; font-weight: bold; }
    .parameters-col_description { width: 80%; }
    .parameters-col_description input[type="text"],
    .parameters-col_description input[type="number"] {
        width: 100%; padding: 5px; border: 1px solid #ced4da; border-radius: 4px; box-sizing: border-box;
    }
    .parameters-col_description input.is-invalid { border-color: #dc3545; }
    .parameter__name.required span { color: red; margin-left: 2px; font-weight: bold; }
    .parameter__type { font-size: 0.9em; color: #6c757d; }
    .parameter__in { font-size: 0.8em; color: #6c757d; }
    .renderedMarkdown p { margin-bottom: 0.5rem; }
    .renderedMarkdown p:last-child { margin-bottom: 0; }

    /* Request Body */
    .request-body-textarea { width: 100%; min-height: 100px; padding: 10px; border: 1px solid #ced4da; border-radius: 4px; font-family: monospace; box-sizing: border-box; margin-bottom: 10px; }
    .content-type-wrapper label.visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }
    .content-type-wrapper select { padding: 0.3rem 0.6rem; font-size: 0.9em; border-radius: 4px; border: 1px solid #ced4da; }

    /* Responses */
    .responses-table { width: 100%; border-collapse: collapse; margin-top: 10px; }
    .responses-table th, .responses-table td { border: 1px solid #dee2e6; padding: 8px; text-align: left; }
    .response-col_status { width: 100px; font-weight: bold; }
    .response-control-media-type { margin: 10px 0; padding: 5px; background-color: #f8f9fa; border-radius: 4px; }
    .response-control-media-type__title { font-weight: bold; margin-right: 5px; }
    .response-control-media-type__accept-message { font-size: 0.85em; color: #6c757d; margin-left: 10px; }
    .model-example { margin-top: 10px; }
    .tab { display: flex; gap: 5px; margin-bottom: 10px; }
    .tablinks.badge { background: #dee2e6; color: #333; padding: 5px 10px; border-radius: 12px; cursor: pointer; font-size: 0.9em; border: none; }
    .tablinks.badge.active { background: #0a3d62; color: white; }
    .example-panel, .schema-panel { border: 1px solid #eee; border-radius: 4px; margin-top: -1px; }

    /* Code Highlighting */
    /*
    .highlight-code { background: #333; color: #f8f8f2; padding: 10px; border-radius: 4px; overflow-x: auto; font-family: monospace; margin: 0; }
    */
    /* Keep the .highlight-code pre rule below it if desired, although the theme styles should handle it */
    .highlight-code pre { margin: 0; padding: 0; background: transparent; border: none; font-family: inherit; font-size: inherit; color: inherit; }

    /* Execution Response */
    .execute-wrapper { margin-top: 20px; padding-top: 15px; border-top: 1px dashed #ccc; }
    .execute-wrapper .opblock-section-header { border-bottom: none; margin-bottom: 5px; padding-bottom: 0; }
    .execute-wrapper .response-format-select { padding: 0.3rem 0.6rem; font-size: 0.9em; border-radius: 4px; border: 1px solid #ced4da; }
    .execute-wrapper pre.response-output-content { background: #f8f9fa; color: #212529; border: 1px solid #dee2e6; padding: 10px; border-radius: 4px; max-height: 400px; overflow: auto; font-family: monospace; white-space: pre-wrap; word-break: break-all; margin-top: 5px; }
    .execute-wrapper div.response-output-narrative { display: none; border: 1px solid #dee2e6; padding: 15px; border-radius: 4px; margin-top: 5px; max-height: 400px; overflow: auto; background: #ffffff; color: #212529; line-height: 1.5; }
    .execute-wrapper .response-status { margin-top: 8px; font-weight: bold; }

    /* Request URL, Curl, Controls */
    .request-url-section, .curl-section { margin-bottom: 15px; padding-bottom: 10px; border-bottom: 1px solid #eee; }
    .request-url-section:last-of-type, .curl-section:last-of-type { border-bottom: none; }
    .request-url-output, .curl-output { background: #e9ecef; color: #212529; padding: 10px 15px; border: 1px solid #dee2e6; border-radius: 4px; font-family: monospace; font-size: 0.9em; white-space: pre-wrap; word-break: break-all; margin-top: 5px; }
    .request-url-output code, .curl-output code { font-family: inherit; }
    .curl-section .opblock-section-header { display: flex; justify-content: space-between; align-items: center; border-bottom: none; padding-bottom: 0; margin-bottom: 5px; }
    .copy-curl-btn, .copy-response-btn, .download-response-btn { padding: 0.25rem 0.5rem; font-size: 0.8em; line-height: 1.5; border-radius: 0.2rem; }
    .copy-curl-btn i, .copy-response-btn i, .download-response-btn i { margin-right: 4px; vertical-align: text-bottom; }
    .execute-wrapper .response-controls { display: flex; align-items: center; gap: 5px; margin-left: auto; }
    .execute-wrapper .opblock-section-header h4 { margin-right: 10px; }
    .opblock-section h5.opblock-title { font-weight: bold; margin: 0; font-size: 1rem; }
</style>

<div class="px-4 py-5 my-5 text-center">
    <img class="d-block mx-auto mb-4" src="{{ url_for('static', filename='FHIRFLARE.png') }}" alt="FHIRFLARE IG Toolkit" width="192" height="192">
    <h1 class="display-5 fw-bold text-body-emphasis">FHIR UI Operations</h1>
    <div class="col-lg-6 mx-auto">
        <p class="lead mb-4">
            Explore FHIR server operations by selecting resource types or system operations. Toggle between local HAPI or a custom server to interact with FHIR metadata, resources, and server-wide operations.
        </p>
        <!-----------------------------------------------------------------remove the buttons-----------------------------------------------------
        <div class="d-grid gap-2 d-sm-flex justify-content-sm-center">
            <a href="{{ url_for('index') }}" class="btn btn-primary btn-lg px-4 gap-3">Back to Home</a>
            <a href="{{ url_for('fhir_ui') }}" class="btn btn-outline-secondary btn-lg px-4">FHIR API Explorer</a>
            <a href="{{ url_for('validate_sample') }}" class="btn btn-outline-secondary btn-lg px-4">Validate FHIR Sample</a>
        </div>
        ------------------------------------------------------------------------------------------------------------------------------------------>
    </div>
</div>

<div class="container mt-4">
    <div class="card">
        <div class="card-header"><i class="bi bi-gear me-2"></i>FHIR Operations Configuration</div>
        <div class="card-body">
            <form id="fhirOperationsForm">
                {{ form.hidden_tag() }}
                <div class="mb-3">
                    <label class="form-label fw-bold">FHIR Server</label>
                    <div class="input-group">
                        <button type="button" class="btn btn-outline-primary" id="toggleServer">
                            <span id="toggleLabel">Use Local HAPI</span>
                        </button>
                        <input type="text" class="form-control" id="fhirServerUrl" name="fhir_server_url" placeholder="Enter FHIR Base URL e.g., https://hapi.fhir.org/baseR4" style="display: none;" aria-describedby="fhirServerHelp">
                    </div>
                    <small id="fhirServerHelp" class="form-text text-muted">Toggle to use local HAPI (/fhir proxy) or enter a custom FHIR server URL.</small>
                </div>
                <div class="mb-3" id="authSection" style="display: none;">
                    <label class="form-label fw-bold">Authentication</label>
                    <div class="row g-3 align-items-end">
                        <div class="col-md-5">
                            <select class="form-select" id="authType" name="auth_type">
                                <option value="none" selected>None</option>
                                <option value="bearer">Bearer Token</option>
                                <option value="basic">Basic Authentication</option>
                            </select>
                        </div>
                        <div class="col-md-7" id="authInputsGroup" style="display: none;">
                            <div id="bearerTokenInput" style="display: none;">
                                <label for="bearerToken" class="form-label">Bearer Token</label>
                                <input type="password" class="form-control" id="bearerToken" name="bearer_token" placeholder="Enter Bearer Token">
                            </div>
                            <div id="basicAuthInputs" style="display: none;">
                                <label for="username" class="form-label">Username</label>
                                <input type="text" class="form-control mb-2" id="username" name="username" placeholder="Enter Username">
                                <label for="password" class="form-label">Password</label>
                                <input type="password" class="form-control" id="password" name="password" placeholder="Enter Password">
                            </div>
                        </div>
                    </div>
                    <small class="form-text text-muted">Select authentication method for the custom FHIR server.</small>
                </div>
                <button type="button" class="btn btn-primary mb-3" id="fetchMetadata">Fetch Metadata</button>
            </form>

            <div class="banner3 mt-3" id="resourceTypes" style="display: none;">
                <h5>Resource Types and Operations</h5>
                <div class="d-flex flex-wrap gap-2" id="resourceButtons"></div>
            </div>

            <div id="swagger-ui" class="mt-4" style="display: none;">
                <h5>Queries for <span id="selectedResource" class="fw-bold">Selected Resource</span></h5>
                <div id="queryList"></div>
            </div>
        </div>
    </div>
</div>

<script>
// --- Utility Functions (Unchanged) ---
function escapeXml(unsafe) {
    if (typeof unsafe !== 'string') return String(unsafe);
    // Corrected escape map
    return unsafe.replace(/[<>&'"]/g, c => ({ '<': '&lt;', '>': '&gt;', '&': '&amp;', "'": '&apos;', '"': '&quot;' })[c] || c);
}

function jsonToFhirXml(json, indentLevel = 0) {
    const PADDING = '  ';
    const currentIndent = PADDING.repeat(indentLevel);
    const nextIndent = PADDING.repeat(indentLevel + 1);

    try {
        const obj = typeof json === 'string' ? JSON.parse(json) : json;
        if (!obj || typeof obj !== 'object') return `${currentIndent}<error>Invalid input: Not an object</error>`;
        if (!Object.keys(obj).length) return `${currentIndent}<OperationOutcome xmlns="http://hl7.org/fhir">\n${nextIndent}<issue>\n${PADDING}${nextIndent}<severity value="information"/>\n${PADDING}${nextIndent}<code value="informational"/>\n${PADDING}${nextIndent}<diagnostics value="Successful operation with no content"/>\n${nextIndent}</issue>\n${currentIndent}</OperationOutcome>`;
        if (!obj.resourceType) {
            obj.resourceType = (obj.type && obj.entry) ? 'Bundle' : null;
            if (!obj.resourceType) return `${currentIndent}<error>Invalid FHIR resource: Missing resourceType</error>`;
        }

        let xml = `${currentIndent}<${obj.resourceType} xmlns="http://hl7.org/fhir">\n`;
        function buildXmlRecursive(currentObj, level) {
            let innerXml = '';
            const itemIndent = PADDING.repeat(level);
            const childLevel = level + 1;
            for (const key in currentObj) {
                if (key === 'xmlns' || key === 'resourceType') continue;
                const value = currentObj[key];
                if (value === null || value === undefined) continue;
                if (Array.isArray(value)) {
                    value.forEach(item => {
                        if (typeof item === 'object' && item !== null) {
                            innerXml += `${itemIndent}<${key}>\n${buildXmlRecursive(item, childLevel)}${itemIndent}</${key}>\n`;
                        } else {
                            innerXml += `${itemIndent}<${key} value="${escapeXml(item)}"/>\n`;
                        }
                    });
                } else if (typeof value === 'object') {
                    innerXml += `${itemIndent}<${key}>\n${buildXmlRecursive(value, childLevel)}${itemIndent}</${key}>\n`;
                } else {
                    if (key === 'div' && typeof value === 'string' && value.trim().startsWith('<div')) {
                        innerXml += `${itemIndent}<${key} xmlns="http://www.w3.org/1999/xhtml">${value}</${key}>\n`;
                    } else {
                        innerXml += `${itemIndent}<${key} value="${escapeXml(value)}"/>\n`;
                    }
                }
            }
            return innerXml;
        }
        xml += buildXmlRecursive(obj, indentLevel + 1);
        xml += `${currentIndent}</${obj.resourceType}>`;
        return xml;
    } catch (e) {
        console.error("JSON to XML conversion error:", e);
        return `${currentIndent}<error xmlns="http://local/error">\n${nextIndent}<message>Failed to convert to XML</message>\n${nextIndent}<detail>${escapeXml(e.message)}</detail>\n${currentIndent}</error>`;
    }
}

function xmlToFhirJson(xmlString) {
    try {
        const parser = new DOMParser();
        const xmlDoc = parser.parseFromString(xmlString, "application/xml");
        const parseError = xmlDoc.querySelector("parsererror");
        if (parseError) {
            console.error("XML Parsing Error:", parseError.textContent);
            return JSON.stringify({ error: "Failed to parse XML", details: parseError.textContent }, null, 2);
        }
        const root = xmlDoc.documentElement;
        if (!root) return JSON.stringify({ error: "No root element found in XML" }, null, 2);

        const jsonResult = { resourceType: root.tagName };
        function buildJsonFromNode(node) {
            const nodeObj = {};
            let textContent = "";
            for (const child of node.childNodes) {
                if (child.nodeType === Node.ELEMENT_NODE) {
                    const tag = child.tagName;
                    const childValue = buildJsonFromNode(child);
                    if (nodeObj.hasOwnProperty(tag)) {
                        if (!Array.isArray(nodeObj[tag])) nodeObj[tag] = [nodeObj[tag]];
                        nodeObj[tag].push(childValue);
                    } else {
                        nodeObj[tag] = childValue;
                    }
                } else if (child.nodeType === Node.TEXT_NODE) {
                    textContent += child.nodeValue.trim();
                }
            }
            if (Object.keys(nodeObj).length) return nodeObj;
            if (node.hasAttribute('value')) return node.getAttribute('value');
            if (textContent) return textContent;
            if (node.nodeType === Node.ELEMENT_NODE && !node.childNodes.length && !node.attributes.length) return null;
            return {};
        }

        const rootContent = buildJsonFromNode(root);
        if (typeof rootContent === 'object' && rootContent !== null) Object.assign(jsonResult, rootContent);
        else jsonResult._value = rootContent;

        const idNode = root.querySelector(':scope > id[value]');
        if (idNode) jsonResult.id = idNode.getAttribute('value');
        const textNode = root.querySelector(':scope > text');
        if (textNode) {
            jsonResult.text = {};
            const statusNode = textNode.querySelector(':scope > status[value]');
            if (statusNode) jsonResult.text.status = statusNode.getAttribute('value');
            const divNode = textNode.querySelector(':scope > div[xmlns="http://www.w3.org/1999/xhtml"]');
            if (divNode) jsonResult.text.div = divNode.innerHTML;
        }
        return JSON.stringify(jsonResult, null, 2);
    } catch (e) {
        console.error("XML to JSON conversion error:", e);
        return JSON.stringify({ error: `Failed to convert XML to JSON: ${e.message}` }, null, 2);
    }
}

async function copyToClipboard(text, buttonElement) {
    if (!navigator.clipboard) {
        alert('Clipboard API not available.');
        return;
    }
    try {
        await navigator.clipboard.writeText(text);
        const originalHtml = buttonElement.innerHTML;
        buttonElement.innerHTML = `<i class="bi bi-check-lg"></i> Copied!`;
        buttonElement.disabled = true;
        setTimeout(() => {
            buttonElement.innerHTML = originalHtml;
            buttonElement.disabled = false;
        }, 1500);
    } catch (err) {
        alert(`Failed to copy text: ${err}`);
    }
}

function downloadFile(content, filename, mimeType = 'application/octet-stream') {
    try {
        const blob = new Blob([content], { type: mimeType });
        const url = URL.createObjectURL(blob);
        const anchor = document.createElement('a');
        anchor.href = url;
        anchor.download = filename;
        document.body.appendChild(anchor);
        anchor.click();
        document.body.removeChild(anchor);
        URL.revokeObjectURL(url);
    } catch (error) {
        alert(`Failed to initiate download: ${error}`);
    }
}

function generateCurlCommand(method, url, headers, body) {
    let curl = `curl -X ${method.toUpperCase()} '${url}'`;
    for (const key in headers) {
        const lowerKey = key.toLowerCase();
        if (['user-agent', 'connection', 'host', 'origin', 'referer', 'x-csrftoken'].includes(lowerKey)) continue;
        const value = (headers[key] || '').replace(/'/g, "'\\''");
        curl += ` \\\n  -H '${key}: ${value}'`;
    }
    if (body !== undefined && body !== null && body !== '') {
        const escapedBody = body.replace(/'/g, "'\\''");
        const contentType = headers['Content-Type'] || '';
        const dataFlag = contentType.includes('application/x-www-form-urlencoded') ? '-d' : '--data-binary';
        curl += ` \\\n  ${dataFlag} '${escapedBody}'`;
    }
    return curl;
}

// --- Main Application Logic ---
document.addEventListener('DOMContentLoaded', () => {
    // --- DOM Element References ---
    const fhirOperationsForm = document.getElementById('fhirOperationsForm');
    const fetchMetadataButton = document.getElementById('fetchMetadata');
    const toggleServerButton = document.getElementById('toggleServer');
    const toggleLabel = document.getElementById('toggleLabel');
    const fhirServerUrlInput = document.getElementById('fhirServerUrl');
    const resourceTypesDisplayDiv = document.getElementById('resourceTypes');
    const resourceButtonsContainer = document.getElementById('resourceButtons');
    const swaggerUiContainer = document.getElementById('swagger-ui');
    const selectedResourceSpan = document.getElementById('selectedResource');
    const queryListContainer = document.getElementById('queryList');
    const authSection = document.getElementById('authSection');
    const authTypeSelect = document.getElementById('authType');
    const authInputsGroup = document.getElementById('authInputsGroup');
    const bearerTokenInput = document.getElementById('bearerToken');
    const usernameInput = document.getElementById('username');
    const passwordInput = document.getElementById('password');
    if (!toggleServerButton || !toggleLabel || !fhirServerUrlInput || !authSection || !authTypeSelect) {
        console.error("Crucial elements missing, stopping script.");
        return;
    }

    // --- State Variables ---
    let isUsingLocalHapi = true; // Default state
    let currentSelectedResource = '';
    let availableSystemOperations = [];
    let fetchedMetadataCache = null;
    let operationDefinitionCache = {}; // <<< ADD THIS LINE: Cache for fetched OperationDefinitions

    // <<< ADD THIS SECTION: Get App Mode >>>
    const appMode = '{{ app_mode | default("standalone") | lower }}'; // Get mode from Flask
    console.log(`App Mode (Operations): ${appMode}`);
    // <<< END ADD >>>

    // --- Helper Functions ---
    function updateAuthInputsUI() {
        console.log(`[updateAuthInputsUI] Running, authType: ${authTypeSelect.value}`);
        if (!authTypeSelect || !authInputsGroup || !bearerTokenInput || !basicAuthInputs) {
            console.error("[updateAuthInputsUI] Missing auth elements");
            return;
        }
        const authType = authTypeSelect.value;
        authInputsGroup.style.display = (authType === 'bearer' || authType === 'basic') ? 'block' : 'none';
        bearerTokenInput.style.display = authType === 'bearer' ? 'block' : 'none';
        basicAuthInputs.style.display = authType === 'basic' ? 'block' : 'none';
        if (authType !== 'bearer' && bearerTokenInput) bearerTokenInput.value = '';
        if (authType !== 'basic' && usernameInput) usernameInput.value = '';
        if (authType !== 'basic' && passwordInput) passwordInput.value = '';
        console.log(`[updateAuthInputsUI] authInputsGroup display: ${authInputsGroup.style.display}, bearer: ${bearerTokenInput.style.display}, basic: ${basicAuthInputs.style.display}`);
    }

        // --- Helper Function to Update Toggle Button/Input UI (MODIFY THIS FUNCTION) ---
    function updateServerToggleUI() {
        if (!toggleLabel || !fhirServerUrlInput || !toggleServerButton || !authSection) {
            console.error("[updateServerToggleUI] Required elements missing!");
            return;
        }
        console.log(`[updateServerToggleUI] appMode=${appMode}, isUsingLocalHapi=${isUsingLocalHapi}`);
        if (appMode === 'lite') {
            console.log("[updateServerToggleUI] Applying Lite mode UI settings");
            isUsingLocalHapi = false;
            toggleServerButton.disabled = true;
            toggleServerButton.classList.add('disabled');
            toggleServerButton.style.pointerEvents = 'none !important';
            toggleServerButton.setAttribute('aria-disabled', 'true');
            toggleServerButton.title = "Local HAPI is not available in Lite mode";
            toggleLabel.textContent = 'Use Custom URL';
            fhirServerUrlInput.style.display = 'block';
            fhirServerUrlInput.placeholder = "Enter FHIR Base URL (Local HAPI unavailable)";
            authSection.style.display = 'block';
        } else {
            console.log("[updateServerToggleUI] Applying Standalone mode UI settings");
            toggleServerButton.disabled = false;
            toggleServerButton.classList.remove('disabled');
            toggleServerButton.style.pointerEvents = 'auto';
            toggleServerButton.removeAttribute('aria-disabled');
            toggleServerButton.title = "";
            toggleLabel.textContent = isUsingLocalHapi ? 'Use Local HAPI' : 'Use Custom URL';
            fhirServerUrlInput.style.display = isUsingLocalHapi ? 'none' : 'block';
            fhirServerUrlInput.placeholder = "Enter FHIR Base URL e.g., https://hapi.fhir.org/baseR4";
            authSection.style.display = isUsingLocalHapi ? 'none' : 'block';
        }
        fhirServerUrlInput.classList.remove('is-invalid');
        updateAuthInputsUI();
        console.log(`[updateServerToggleUI] Finished. Button disabled: ${toggleServerButton.disabled}, authSection display: ${authSection.style.display}`);
    }  

// <<< REFINED fetchOperationDefinition >>>
    // <<< REFINED fetchOperationDefinition (v3 - Handles Local Proxy Target Correctly) >>>
    async function fetchOperationDefinition(definitionUrl) {
        if (!definitionUrl) return null;

        if (operationDefinitionCache.hasOwnProperty(definitionUrl)) {
            return operationDefinitionCache[definitionUrl];
        }

        let fetchUrl;
        const currentBaseUrl = isUsingLocalHapi ? '/fhir' : (fhirServerUrlInput.value.trim().replace(/\/+$/, '') || '/fhir');
        const expectedHapiBase = 'http://localhost:8080/fhir/'; // Define the expected proxied server base

        try {
            // Check if definitionUrl is an absolute HTTP/S URL
            if (definitionUrl.startsWith('http://') || definitionUrl.startsWith('https://')) {
                // --- Logic when using Local HAPI Proxy ---
                if (isUsingLocalHapi) {
                    // If the absolute URL starts with the expected HAPI base, rewrite it for the proxy
                    if (definitionUrl.startsWith(expectedHapiBase)) {
                        const relativePath = definitionUrl.substring(expectedHapiBase.length);
                        fetchUrl = `${currentBaseUrl}/${relativePath}`; // Use '/fhir/...' proxy path
                        console.log(`Fetching same-origin absolute OpDef via proxy: ${fetchUrl} (Original: ${definitionUrl})`);
                    } else {
                        // Absolute URL, using proxy, but NOT pointing to expected HAPI base -> Skip (likely external)
                        console.warn(`Skipping fetch for external absolute URL while using proxy: ${definitionUrl}`);
                        operationDefinitionCache[definitionUrl] = null; return null;
                    }
                }
                // --- Logic when using Custom URL ---
                else {
                    let currentOrigin = '';
                    try { currentOrigin = new URL(currentBaseUrl).origin; } catch(e) { currentOrigin = window.location.origin; } // Determine custom server origin
                    const definitionOrigin = new URL(definitionUrl).origin;

                    if (definitionOrigin === currentOrigin) {
                        // Same origin as custom URL - fetch directly
                        fetchUrl = definitionUrl;
                        console.log(`Fetching same-origin absolute OpDef directly: ${fetchUrl}`);
                    } else {
                        // Different origin than custom URL - skip
                        console.warn(`Skipping fetch for external absolute URL (different origin): ${definitionUrl}`);
                        operationDefinitionCache[definitionUrl] = null; return null;
                    }
                }
            }
            // --- Logic for Relative URLs ---
            else {
                // Not an absolute HTTP/S URL - treat as relative to currentBaseUrl
                fetchUrl = `${currentBaseUrl}/${definitionUrl.startsWith('/') ? definitionUrl.substring(1) : definitionUrl}`;
                console.log(`Fetching relative OperationDefinition: ${fetchUrl} (Original: ${definitionUrl})`);
            }
        } catch (e) { // Catch errors during URL parsing/logic above
             console.error(`Error determining fetch URL for ${definitionUrl}: ${e}. Treating as relative.`);
             fetchUrl = `${currentBaseUrl}/${definitionUrl.startsWith('/') ? definitionUrl.substring(1) : definitionUrl}`;
             console.log(`Fetching relative OperationDefinition (fallback): ${fetchUrl} (Original: ${definitionUrl})`);
        }
        // --- End URL Determination ---

        if (!fetchUrl) {
             console.error(`Could not determine a valid fetchUrl for OperationDefinition: ${definitionUrl}`);
             operationDefinitionCache[definitionUrl] = null; return null;
        }

        console.log(`Attempting to fetch OperationDefinition from final URL: ${fetchUrl}`);
        try {
            const response = await fetch(fetchUrl, {
                method: 'GET',
                headers: { 'Accept': 'application/fhir+json' }
            });
            if (!response.ok) { console.error(`HTTP ${response.status} fetching OpDef ${fetchUrl}`); operationDefinitionCache[definitionUrl] = null; return null; }
            const definition = await response.json();
            if (definition.resourceType !== 'OperationDefinition') { console.error(`Expected OpDef, got ${definition.resourceType} from ${fetchUrl}`); operationDefinitionCache[definitionUrl] = null; return null; }
            console.log(`Successfully fetched and parsed OperationDefinition: ${fetchUrl}`);
            operationDefinitionCache[definitionUrl] = definition;
            return definition;
        } catch (error) {
            console.error(`Failed to fetch or parse OperationDefinition ${fetchUrl}:`, error);
            operationDefinitionCache[definitionUrl] = null; return null;
        }
    }
    // <<< END REFINED fetchOperationDefinition (v3) >>>

    // function updateServerToggleUI() {
    //     // Keep checks for elements
    //     if (!toggleLabel || !fhirServerUrlInput || !toggleServerButton) {
    //          console.error("updateServerToggleUI: Required elements missing!");
    //          return;
    //     }
    //     console.log(`updateServerToggleUI: appMode=<span class="math-inline">\{appMode\}, current isUsingLocalHapi\=</span>{isUsingLocalHapi}`); // Debug

    //     if (appMode === 'lite') {
    //         console.log("-> Applying Lite mode UI settings.");
    //         isUsingLocalHapi = false; // Force state
    //         toggleServerButton.disabled = true; // Set disabled attribute
    //         toggleServerButton.classList.add('disabled'); // Add Bootstrap disabled class
    //         // --- ADD !important to pointerEvents ---
    //         toggleServerButton.style.pointerEvents = 'none !important';
    //         // --- END ADD ---
    //         toggleServerButton.setAttribute('aria-disabled', 'true'); // Accessibility
    //         toggleServerButton.title = "Local HAPI is not available in Lite mode"; // Tooltip
    //         toggleLabel.textContent = 'Use Custom URL'; // Set label text
    //         fhirServerUrlInput.style.display = 'block'; // Show custom URL input
    //         fhirServerUrlInput.placeholder = "Enter FHIR Base URL (Local HAPI unavailable)";
    //     } else {
    //         // Standalone mode
    //         console.log("-> Applying Standalone mode UI settings.");
    //         toggleServerButton.disabled = false; // Ensure enabled
    //         toggleServerButton.classList.remove('disabled'); // Remove Bootstrap disabled class
    //         // --- Ensure pointerEvents is auto in standalone ---
    //         toggleServerButton.style.pointerEvents = 'auto';
    //         // --- END ---
    //         toggleServerButton.removeAttribute('aria-disabled'); // Accessibility
    //         toggleServerButton.title = ""; // Clear tooltip

    //         // Set text/display based on current standalone state
    //         toggleLabel.textContent = isUsingLocalHapi ? 'Use Local HAPI' : 'Use Custom URL';
    //         fhirServerUrlInput.style.display = isUsingLocalHapi ? 'none' : 'block';
    //         fhirServerUrlInput.placeholder = "Enter FHIR Base URL e.g., https://hapi.fhir.org/baseR4";
    //     }
    //     // Clear potential validation errors regardless of mode
    //     if(fhirServerUrlInput) fhirServerUrlInput.classList.remove('is-invalid'); // Add check for element existence
    //     console.log(`-> updateServerToggleUI finished. Button disabled: ${toggleServerButton.disabled}, pointer-events: ${toggleServerButton.style.pointerEvents}`); // Log pointer-events
    // }

    // --- Server Toggle Functionality (REVISED - simplified) ---
    function toggleServerSelection() {
        console.log(`toggleServerSelection called. appMode: ${appMode}`); // Debug
        // This check prevents state change and subsequent UI update call in Lite mode
        if (appMode === 'lite') {
            console.log("Server toggle ignored in Lite mode.");
            return; // Explicitly do nothing if Lite
        }

        // Only flip state and update UI if in standalone mode
        isUsingLocalHapi = !isUsingLocalHapi;
        updateServerToggleUI(); // Update the UI based on the new state

        // Clear custom URL input value only when switching TO local
        // Ensure fhirServerUrlInput exists before trying to access it
        if (isUsingLocalHapi && fhirServerUrlInput) {
            fhirServerUrlInput.value = '';
        }

        // Reset dependent state
        if (resourceTypesDisplayDiv) resourceTypesDisplayDiv.style.display = 'none';
        if (swaggerUiContainer) swaggerUiContainer.style.display = 'none';
        fetchedMetadataCache = null;
        availableSystemOperations = [];
        operationDefinitionCache = {}; // Clear OpDef cache too
        console.log(`Server toggled (Standalone): Now using ${isUsingLocalHapi ? 'Local HAPI' : 'Custom URL'}`);
    }

    // Add event listener to the toggle button
    if (toggleServerButton) {
        toggleServerButton.addEventListener('click', toggleServerSelection);
    } else {
        console.error("Toggle server button (#toggleServer) not found!");
    }

// --- Generate Query Examples (Modified for Async Operation Fetching) ---
    async function getQueryExamplesForResourceType(resourceType) { // <<< Added async
        if (!fetchedMetadataCache?.rest?.[0]) return [];
        const restSection = fetchedMetadataCache.rest[0];
        const resourceMetadata = restSection.resource?.find(r => r.type === resourceType);

        if (!resourceMetadata) {
            console.warn(`No metadata found for resource type: ${resourceType}`);
            return [];
        }

        const supportedInteractions = resourceMetadata.interaction?.map(i => i.code) || [];
        const resourceSpecificOperations = resourceMetadata.operation || [];
        const allSearchParameters = resourceMetadata.searchParam || [];
        const queries = []; // Initialize empty queries array

        // --- Define Standard Parameters ---
        const formatParam = { name: '_format', in: 'query', type: 'string', required: false, description: 'Response format (e.g., json, xml)', example: 'json' };
        const idPathParam = { name: 'id', in: 'path', type: 'string', required: true, description: 'Resource logical ID', example: 'example' };
        const versionIdPathParam = { name: 'version_id', in: 'path', type: 'string', required: true, description: 'Version ID', example: '1' };
        const countQueryParam = { name: '_count', in: 'query', type: 'integer', required: false, description: 'Results per page', example: '10' };
        const sinceParam = { name: '_since', in: 'query', type: 'instant', required: false, description: 'Only return updates after this time', example: new Date().toISOString() };

        // --- Define Common Search Parameters Separately ---
        const commonStandardParams = [
            { name: '_id', in: 'query', type: 'token', required: false, description: 'Search by resource logical ID', example: 'example' },
            { name: '_lastUpdated', in: 'query', type: 'date', required: false, description: 'Search by last updated date', example: 'ge2024-01-01' },
            { name: '_profile', in: 'query', type: 'uri', required: false, description: 'Search by profile canonical URL', example: '' },
            { name: '_tag', in: 'query', type: 'token', required: false, description: 'Search by tag (code or system|code)', example: '' },
            { name: '_security', in: 'query', type: 'token', required: false, description: 'Search by security label (system|code)', example: '' },
            { name: '_text', in: 'query', type: 'string', required: false, description: 'Search narrative content', example: '' },
            { name: '_content', in: 'query', type: 'string', required: false, description: 'Search all resource content', example: '' },
            { name: '_list', in: 'query', type: 'string', required: false, description: 'Search within a list', example: '' },
            { name: '_has', in: 'query', type: 'string', required: false, description: 'Reverse chaining search', example: '' },
            { name: '_type', in: 'query', type: 'string', required: false, description: 'Specify resource type (in compartment search)', example: resourceType },
            { name: '_source', in: 'query', type: 'uri', required: false, description: 'Search by source URI', example: '' },
            { name: '_filter', in: 'query', type: 'string', required: false, description: 'Advanced search filter', example: '' }
        ];
        const commonStandardParamNames = new Set(commonStandardParams.map(p => p.name));

        // --- Map ALL Search Parameters from Metadata ---
        const specificSearchParams = allSearchParameters
            .map(sp => ({
                name: sp.name,
                in: 'query',
                type: sp.type,
                required: false,
                description: sp.documentation || `Search by ${sp.name} (${sp.type})`,
                example: sp.type === 'reference' ? `${resourceType}/example` :
                         sp.type === 'token' ? 'system|code' :
                         sp.type === 'date' ? '2024-01-01' :
                         sp.type === 'number' ? '10' :
                         sp.type === 'quantity' ? '5|mg' :
                         sp.type === 'uri' ? 'http://example.com' :
                         ''
            }));

        // Combine common params (_count, _format), specific params from metadata, and standard _params
        const allUniqueParamsMap = new Map();
        specificSearchParams.forEach(p => allUniqueParamsMap.set(p.name, p));
        commonStandardParams.forEach(p => { if (!allUniqueParamsMap.has(p.name)) allUniqueParamsMap.set(p.name, p); });
        if (!allUniqueParamsMap.has(countQueryParam.name)) allUniqueParamsMap.set(countQueryParam.name, countQueryParam);
        if (!allUniqueParamsMap.has(formatParam.name)) allUniqueParamsMap.set(formatParam.name, formatParam);

        const searchGetParams = Array.from(allUniqueParamsMap.values()).sort((a, b) => a.name.localeCompare(b.name));
        const searchPostParams = [countQueryParam, formatParam]; // Only common params for POST search body

        // --- Define Example Schemas and Payloads ---
        const baseExample = { resourceType, id: "example", text: { status: "generated", div: `<div xmlns="http://www.w3.org/1999/xhtml">Example ${resourceType}</div>` } };
        const baseExampleString = JSON.stringify(baseExample, null, 2);
        const createExampleString = JSON.stringify({ ...baseExample, id: undefined }, null, 2);
        const baseSchema = { resourceType, id: "string", meta: { versionId: "string", lastUpdated: "instant" }, text: { status: "code", div: "xhtml" } };
        const bundleSchema = { resourceType: "Bundle", type: "code", total: "unsignedInt", link: [{ relation: "string", url: "uri" }], entry: [{ resource: baseSchema }] };
        const paramsSchema = { resourceType: "Parameters", parameter: [{ name: "string", valueString: "string" }] };
        const outcomeSchema = { resourceType: "OperationOutcome", issue: [{ severity: "code", code: "code", diagnostics: "string" }] };
        const bundleSearchExample = JSON.stringify({ resourceType: "Bundle", type: "searchset", total: 1, entry: [{ resource: baseExample }] }, null, 2);
        const bundleHistoryExample = JSON.stringify({ resourceType: "Bundle", type: "history", total: 1, entry: [{ resource: baseExample }] }, null, 2);
        const patchExample = JSON.stringify({ resourceType: "Parameters", parameter: [{ name: "operation", part: [{ name: 'type', valueCode: 'replace' }, { name: 'path', valueString: `${resourceType}.active` }, { name: 'value', valueBoolean: false }] }] }, null, 2);
        const deleteExample = JSON.stringify({ resourceType: "OperationOutcome", issue: [{ severity: "information", code: "informational", diagnostics: "Successful deletion" }] }, null, 2);
        // Example body for POST search (x-www-form-urlencoded)
        const postSearchExample = searchGetParams
            .filter(p => p.in === 'query' && p.example && !['_count', '_format'].includes(p.name))
            .map(p => `${p.name}=${encodeURIComponent(p.example)}`)
            .join('&');

        // --- Define Interaction Map ---
        const interactionMap = {
            'read': { label: `Read ${resourceType}`, method: 'GET', path: `${resourceType}/:id`, description: `Read a ${resourceType} by ID`, parameters: [idPathParam, formatParam], schema: baseSchema, example: baseExampleString },
            'vread': { label: `VRead ${resourceType}`, method: 'GET', path: `${resourceType}/:id/_history/:version_id`, description: `Read specific version`, parameters: [idPathParam, versionIdPathParam, formatParam], schema: baseSchema, example: JSON.stringify({ ...baseExample, meta: { versionId: "1" } }, null, 2) },
            'update': { label: `Update ${resourceType}`, method: 'PUT', path: `${resourceType}/:id`, description: `Update ${resourceType} with ID`, parameters: [idPathParam, formatParam], requestBody: true, schema: baseSchema, example: baseExampleString },
            'patch': { label: `Patch ${resourceType}`, method: 'PATCH', path: `${resourceType}/:id`, description: `Patch ${resourceType} by ID`, parameters: [idPathParam, formatParam], requestBody: true, schema: paramsSchema, example: patchExample },
            'delete': { label: `Delete ${resourceType}`, method: 'DELETE', path: `${resourceType}/:id`, description: `Delete ${resourceType}`, parameters: [idPathParam, formatParam], schema: outcomeSchema, example: deleteExample },
            'create': { label: `Create ${resourceType}`, method: 'POST', path: `${resourceType}`, description: `Create new ${resourceType}`, parameters: [], requestBody: true, schema: baseSchema, example: createExampleString },
            'search-type': { label: `Search ${resourceType} (GET)`, method: 'GET', path: `${resourceType}`, description: `Search ${resourceType} using GET`, parameters: searchGetParams, schema: bundleSchema, example: bundleSearchExample },
            'history-type': { label: `Type History ${resourceType}`, method: 'GET', path: `${resourceType}/_history`, description: `History for all ${resourceType}`, parameters: [countQueryParam, formatParam, sinceParam], schema: bundleSchema, example: bundleHistoryExample },
            'history-instance': { label: `Instance History ${resourceType}`, method: 'GET', path: `${resourceType}/:id/_history`, description: `History for specific ${resourceType}`, parameters: [idPathParam, countQueryParam, formatParam, sinceParam], schema: bundleSchema, example: bundleHistoryExample },
        };

        // --- Build Query List: Standard Interactions ---
        supportedInteractions.forEach(code => {
            if (interactionMap[code]) {
                queries.push(interactionMap[code]);
            }
        });
        if (supportedInteractions.includes('search-type')) {
            queries.push({
                label: `Search ${resourceType} (POST)`,
                method: 'POST',
                path: `${resourceType}/_search`,
                description: `Search ${resourceType} using POST (parameters in x-www-form-urlencoded body)`,
                parameters: searchPostParams,
                requestBody: true,
                schema: bundleSchema,
                example: postSearchExample
            });
        }

        // --- Build Query List: Resource Specific Operations (Asynchronously) ---
        const resourceOperationPromises = resourceSpecificOperations.map(async opDef => { // <<< Add async and map
            const opName = opDef.name.startsWith('$') ? opDef.name : `$${opDef.name}`;
            const opDoc = opDef.documentation || `Execute ${opName} on ${resourceType}`;

            // Basic method guess (can be refined)
            let opMethod = 'POST'; // Default to POST for operations
            // Refined guess based on common read-only operations or definition hints
            if (['$meta', '$validate', '$snapshot'].includes(opName) || opDef.definition?.toLowerCase().includes('get')) {
                 opMethod = 'GET';
            }

            const isInstanceLevel = opDef.definition?.toLowerCase().includes('/{id}/$') || opDef.instance === true;
            let operationParameters = [formatParam]; // Default params
            let operationRequestBody = opMethod !== 'GET'; // Default request body logic
            let operationSchema = paramsSchema; // Default schema
            let operationExample = JSON.stringify({ resourceType: "Parameters", parameter: [{ name: "example-param", valueString: "example-value" }] }, null, 2); // Default example

            // --- Fetch OperationDefinition ---
            const definitionUrl = opDef.definition;
            const fetchedOpDef = await fetchOperationDefinition(definitionUrl); // <<< Fetch definition

            if (fetchedOpDef && fetchedOpDef.parameter) {
                try {
                    const parsedParams = fetchedOpDef.parameter
                        .filter(p => p.use === 'in') // Only input parameters
                        .map(p => ({
                            name: p.name || 'unknown',
                            // Refined 'in' logic: Assume query for GET, body for POST unless searchType specified
                            in: (opMethod === 'GET' || p.searchType) ? 'query' : 'body (Parameters)',
                            type: p.type || 'string', // <<< Capture parameter type
                            required: (p.min || 0) > 0,
                            description: p.documentation || `Parameter ${p.name || ''}`,
                            // Basic example generation, could be improved
                            example: p.example ? (p.example[0]?.valueString || p.example[0]?.valueCode || p.example[0]?.valueBoolean) : `(${p.type || 'string'})`, // Try to extract from example[0].value[x]
                            // <<< ADD binding if present >>>
                            binding: p.binding // e.g., { strength: 'required', valueSet: 'http://...' }
                        }));

                    // Add id param if it's instance level and not already defined
                    if (isInstanceLevel && !parsedParams.some(p => p.name === 'id' && p.in === 'path')) {
                         operationParameters = [idPathParam, formatParam, ...parsedParams];
                    } else {
                         operationParameters = [formatParam, ...parsedParams];
                    }

                    operationSchema = fetchedOpDef; // Use the fetched definition as schema

                    // Generate example Parameters resource if POST/PUT/PATCH and has input parameters
                    if (operationRequestBody && parsedParams.length > 0) {
                        const bodyParams = parsedParams.filter(p => p.in === 'body (Parameters)');
                        if (bodyParams.length > 0) {
                             const exampleParamBody = {
                                 resourceType: "Parameters",
                                 parameter: bodyParams.map(p => {
                                     // Create a simple example value based on type
                                     let exampleValue;
                                     switch (p.type) {
                                         case 'boolean': exampleValue = { valueBoolean: true }; break;
                                         case 'integer': exampleValue = { valueInteger: 1 }; break;
                                         case 'code': exampleValue = { valueCode: 'example-code' }; break;
                                         case 'uri': exampleValue = { valueUri: 'http://example.org' }; break;
                                         case 'canonical': exampleValue = { valueCanonical: 'http://example.org/fhir/StructureDefinition/example' }; break;
                                         case 'date': exampleValue = { valueDate: new Date().toISOString().split('T')[0] }; break;
                                         case 'dateTime': exampleValue = { valueDateTime: new Date().toISOString() }; break;
                                         case 'instant': exampleValue = { valueInstant: new Date().toISOString() }; break;
                                         // Add more types as needed
                                         default: exampleValue = { valueString: `example-${p.type || 'value'}` };
                                     }
                                     return { name: p.name, ...exampleValue };
                                 })
                             };
                             operationExample = JSON.stringify(exampleParamBody, null, 2);
                        } else {
                             // If it's POST/PUT but no 'body' parameters defined, use empty Parameters
                             operationExample = JSON.stringify({ resourceType: "Parameters", parameter: [] }, null, 2);
                        }
                    } else if (!operationRequestBody) {
                         // Use a relevant example for GET operations (e.g., a Bundle or the base resource)
                         operationExample = bundleSearchExample; // Or potentially baseExampleString
                    }
                } catch (parseError) {
                    console.error(`Error parsing parameters for ${opName} from definition ${definitionUrl}:`, parseError);
                     // Fallback to basic params if parsing fails
                     operationParameters = [formatParam];
                     if (isInstanceLevel) operationParameters.unshift(idPathParam);
                     operationRequestBody = opMethod !== 'GET'; // Reset requestBody based on method
                     operationSchema = paramsSchema; // Reset schema
                     // Keep default example
                }
            } else {
                 // Fallback if fetch failed or no parameters defined
                 operationParameters = [formatParam];
                 if (isInstanceLevel) operationParameters.unshift(idPathParam);
                 // Keep default example, schema, requestBody
            }

            // Return the query definition object for this operation
            return {
                label: `${opName} (${isInstanceLevel ? 'Instance' : 'Type'})`,
                method: opMethod,
                path: isInstanceLevel ? `${resourceType}/:id/${opName}` : `${resourceType}/${opName}`,
                description: opDoc,
                parameters: operationParameters,
                requestBody: operationRequestBody,
                schema: operationSchema,
                example: operationExample,
                definitionUrl: definitionUrl // Store definition URL for potential later use
            };
        }); // <<< End map over resourceSpecificOperations

        // Wait for all resource operation fetches to complete
        const resourceQueries = await Promise.all(resourceOperationPromises); // <<< Wait for promises
        queries.push(...resourceQueries); // <<< Add resolved queries

        // --- Add System-Level Operations (If applicable - Type/Instance Level) ---
        // This adds system operations like $meta to resource-level lists where appropriate
        availableSystemOperations.forEach(op => {
            const opName = op.name.startsWith('$') ? op.name : `$${op.name}`;
            const opExample = JSON.stringify({ resourceType: "Parameters", parameter: [{ name: "info", valueString: `Input for ${opName}` }] }, null, 2);

            // Check if the system operation applies at the Type level for this resource type
            if (op.levels.includes('type')) {
                op.methods.forEach(method => {
                    // Fetch definition to get parameters (similar logic as above)
                    // For simplicity here, we'll use basic params, but ideally fetch definition
                    const opParams = [formatParam]; // <<< Replace with fetched params if enhancing further
                    queries.push({
                        label: `${opName} (Type)`, method: method, path: `${resourceType}/${opName}`,
                        description: op.documentation || `Type-level ${opName} on ${resourceType}`,
                        parameters: opParams, requestBody: method !== 'GET',
                        schema: paramsSchema, example: opExample // <<< Use fetched schema/example if enhancing
                    });
                });
            }
            // Check if the system operation applies at the Instance level for this resource type
            if (op.levels.includes('instance')) {
                op.methods.forEach(method => {
                    // Fetch definition to get parameters (similar logic as above)
                     const opParams = [idPathParam, formatParam]; // <<< Replace with fetched params if enhancing further
                    queries.push({
                        label: `${opName} (Instance)`, method: method, path: `${resourceType}/:id/${opName}`,
                        description: op.documentation || `Instance-level ${opName} on ${resourceType}`,
                        parameters: opParams, requestBody: method !== 'GET',
                        schema: paramsSchema, example: opExample // <<< Use fetched schema/example if enhancing
                    });
                });
            }
        });

        // Filter duplicates (ensuring path AND method match)
        const uniqueQueries = [];
        const seenQueries = new Set();
        for (const q of queries) {
             const key = `${q.method} ${q.path}`;
             if (!seenQueries.has(key)) {
                 uniqueQueries.push(q);
                 seenQueries.add(key);
             }
        }

        return uniqueQueries; // Return the consolidated list
    } // End getQueryExamplesForResourceType (async)

 // --- Generate System-Level Queries (ASYNC VERSION fetching OperationDefinitions - CORRECTED) ---
    async function getSystemLevelQueries() { // Added async keyword
        if (!fetchedMetadataCache?.rest?.[0]) return [];

        const restSection = fetchedMetadataCache.rest[0];
        const supportedInteractions = restSection.interaction?.map(i => i.code) || [];
        const queries = [];
        const addedPaths = new Set();

        // --- Define Common & Specific Parameters ---
        const formatParam = { name: '_format', in: 'query', type: 'string', required: false, description: 'Response format', example: 'json' };
        const countParam = { name: '_count', in: 'query', type: 'integer', required: false, description: 'Results per page', example: '10' };
        const sinceParam = { name: '_since', in: 'query', type: 'instant', required: false, description: 'Changes after this time', example: new Date().toISOString() };
        const contentParam = { name: '_content', in: 'query', type: 'string', required: false, description: 'Search content', example: 'example' };
        const defaultParamsSchema = { resourceType: "Parameters" }; // Default schema
        const defaultParamsExample = JSON.stringify({ resourceType: "Parameters", parameter: [] }, null, 2); // Default example

        // --- Add Metadata (Capabilities) Operation ---
        const metadataPath = 'metadata';
        const metadataKey = `GET/${metadataPath}`;
        if (!addedPaths.has(metadataKey)) {
            queries.push({ name: 'metadata', label: 'GET /metadata', method: 'GET', path: metadataPath, description: 'server-capabilities: Fetch the server FHIR CapabilityStatement', parameters: [formatParam], schema: { resourceType: "CapabilityStatement" }, example: JSON.stringify(fetchedMetadataCache || { resourceType: "CapabilityStatement" }, null, 2) });
            addedPaths.add(metadataKey);
        }

        // --- Add Other Standard System Interactions ---
        // (Keep Transaction/Batch, History, Search sections as is)
         // Transaction/Batch
         if (supportedInteractions.includes('transaction') || supportedInteractions.includes('batch')) {
              const path = ''; const key = `POST/${path}`;
              if (!addedPaths.has(key)) {
                  queries.push({ name: 'server-transaction', label: 'POST /', method: 'POST', path: path, description: 'server-transaction: Execute a FHIR Transaction (or FHIR Batch) Bundle', parameters: [formatParam], requestBody: true, schema: { resourceType: "Bundle" }, example: JSON.stringify({ resourceType: "Bundle", type: "transaction", entry: [] }, null, 2) });
                  addedPaths.add(key);
              }
         }
         // System History
         if (supportedInteractions.includes('history-system')) {
              const path = '_history'; const key = `GET/${path}`;
              if (!addedPaths.has(key)) {
                  queries.push({ name: 'server-history', label: 'GET /_history', method: 'GET', path: path, description: 'server-history: Fetch the resource change history across all resource types on the server', parameters: [formatParam, countParam, sinceParam], schema: { resourceType: "Bundle" }, example: JSON.stringify({ resourceType: "Bundle", type: "history" }, null, 2) });
                  addedPaths.add(key);
              }
         }
         // System Search
         if (supportedInteractions.includes('search-system')) {
              const path = ''; const key = `GET/${path}`;
              if (!addedPaths.has(key)) {
                  queries.push({ name: 'search-system', label: 'GET /', method: 'GET', path: path, description: 'Search across all resource types (limited support usually)', parameters: [formatParam, countParam, contentParam], schema: { resourceType: "Bundle" }, example: JSON.stringify({ resourceType: "Bundle", type: "searchset" }, null, 2) });
                  addedPaths.add(key);
              }
         }


        // --- Add System-Level Named Operations (Fetching Definitions) ---
        const operationPromises = (restSection.operation || [])
         // Apply the filter using the 'op' parameter consistently
         .filter(op => op.name && op.name !== 'metadata' && op.name !== 'capabilities') // <<< CORRECTED HERE
         .map(async op => { // Use map with async to create promises
             const opName = op.name; // Define opName *inside* map if needed later
             const opPath = opName.startsWith('$') ? opName : `$${opName}`;
             const definitionUrl = op.definition;
             const doc = op.documentation || `Execute ${opName} at system level`;

             let methods = [];
             // (Keep existing method detection logic...)
             if (['diff', 'meta', 'get-resource-counts'].includes(opName)) { methods = ['GET', 'POST']; }
             else if (['reindex', 'perform-reindexing-pass', 'mark-all-resources-for-reindexing', 'expunge', 'reindex-terminology', 'hapi.fhir.replace-references'].includes(opName)) { methods = ['POST']; }
             else { methods = ['POST']; if (op.definition?.toLowerCase().includes('get')) methods.push('GET'); }


             const operationQueries = []; // Store queries for this operation's methods

             // Attempt to fetch the definition *once* per operation
             const opDef = await fetchOperationDefinition(definitionUrl); // <<< AWAIT FETCH

             for (const method of methods) { // Now loop through methods
                 const key = `${method}/${opPath}`;
                 if (!addedPaths.has(key)) {
                     let label = `${method} /${opPath}`;
                     let description = doc;
                     let operationParameters = [formatParam]; // Default
                     let operationExample = defaultParamsExample; // Default
                     let operationSchema = defaultParamsSchema; // Default

                     if (opDef && opDef.parameter) {
                         try {
                             const parsedParams = opDef.parameter
                                 .filter(p => p.use === 'in')
                                 .map(p => ({
                                     name: p.name || 'unknown',
                                     in: (method === 'GET' || p.searchType) ? 'query' : 'body (Parameters)', // Basic guess
                                     type: p.type || 'string',
                                     required: (p.min || 0) > 0,
                                     description: p.documentation || `Parameter ${p.name || ''}`,
                                     example: `(${p.type || 'string'})`
                                 }));
                             operationParameters = [formatParam, ...parsedParams];
                             operationSchema = opDef;
                             if (method !== 'GET' && parsedParams.length > 0) {
                                 const exampleParamBody = { resourceType: "Parameters", parameter: parsedParams.map(p => ({ name: p.name, valueString: `example-${p.type}` })) };
                                 operationExample = JSON.stringify(exampleParamBody, null, 2);
                             }
                         } catch (parseError) {
                             console.error(`Error parsing parameters for ${opName} from definition ${definitionUrl}:`, parseError);
                             operationParameters = [formatParam]; // Fallback
                         }
                     } else {
                          operationParameters = [formatParam]; // Fallback if fetch failed
                     }

                      // Customize description (optional)
                     if (opName === 'diff') description = 'Compare two resources or two versions of a single resource';
                     else if (opName === 'get-resource-counts') description = 'Provides the number of resources currently stored on the server, broken down by resource type';
                     // ... etc ...

                     operationQueries.push({
                         name: opName, label: label, method: method, path: opPath,
                         description: description, parameters: operationParameters,
                         requestBody: method !== 'GET', schema: operationSchema, example: operationExample
                     });
                     addedPaths.add(key);
                 } // end if !addedPaths
             } // end for method

             return operationQueries; // Return array of queries generated for this operation
        }); // end map

        // Wait for all fetches and processing to complete
        const results = await Promise.all(operationPromises); // <<< AWAIT ALL PROMISES

        // Flatten the results
        results.forEach(opQueries => queries.push(...opQueries));

        console.log("Generated system queries:", queries);
        return queries;
    } // End getSystemLevelQueries (async)


// Updated async function to handle resource type selection and display queries
    async function updateQueryListUI(resourceType) { // Marked as async
        currentSelectedResource = resourceType;
        selectedResourceSpan.textContent = resourceType === 'System' ? 'System Operations' : resourceType;
        queryListContainer.innerHTML = '<p class="text-muted">Loading operations...</p>'; // Loading message
        swaggerUiContainer.style.display = 'block'; // Show container

        // Fetch queries asynchronously
        const queries = resourceType === 'System'
            ? await getSystemLevelQueries()
            // <<< Assumes getQueryExamplesForResourceType is now async >>>
            : await getQueryExamplesForResourceType(resourceType);

        queryListContainer.innerHTML = ''; // Clear loading message

        if (!queries || !queries.length) {
            queryListContainer.innerHTML = '<p>No operations defined or supported for this type.</p>';
            swaggerUiContainer.style.display = 'block';
            return;
        }

        // Sort queries before displaying (example sorting, adjust as needed)
        queries.sort((a, b) => {
            const pathCompare = a.path.localeCompare(b.path);
            if (pathCompare !== 0) return pathCompare;
            const methodOrder = { 'GET': 1, 'POST': 2, 'PUT': 3, 'PATCH': 4, 'DELETE': 5 };
            return (methodOrder[a.method] || 99) - (methodOrder[b.method] || 99);
        });

        // Generate HTML for each query block
        queries.forEach((query, i) => {
            const blockId = `opblock-${i}`;
            const block = document.createElement('div');
            block.id = blockId;
            block.className = `opblock opblock-${query.method.toLowerCase()}`;
            block.dataset.queryIndex = i;
            block.dataset.queryData = JSON.stringify(query); // Store full query data

            // --- Generate Parameters Table HTML with Improved Inputs ---
            const parametersHtml = query.parameters && query.parameters.length
                ? query.parameters.map(p => {
                    let inputHtml = '';
                    const inputId = `${blockId}-param-${p.name}`;
                    const commonAttrs = `id="${inputId}" aria-label="${p.name} parameter value" disabled data-example="${p.example || ''}"`;
                    const placeholder = p.example ? `${p.example}` : p.name;

                    switch (p.type) {
                        case 'boolean':
                            inputHtml = `
                                <div class="form-check form-switch mt-1">
                                    <input class="form-check-input" type="checkbox" role="switch" value="true" ${commonAttrs}>
                                    <label class="form-check-label small" for="${inputId}">(${p.required ? 'required' : 'optional'})</label>
                                </div>`;
                            break;
                        case 'code':
                             if (p.name === '_format') {
                                 inputHtml = `
                                     <select class="form-select form-select-sm" ${commonAttrs}>
                                         <option value="" ${p.example === '' || p.example === null || p.example === undefined ? 'selected' : ''}>Server Default</option>
                                         <option value="json" ${p.example === 'json' ? 'selected' : ''}>json</option>
                                         <option value="xml" ${p.example === 'xml' ? 'selected' : ''}>xml</option>
                                     </select>`;
                             } else {
                                inputHtml = `<input type="text" class="form-control form-control-sm" placeholder="${placeholder}" ${commonAttrs}>`;
                             }
                            break;
                        case 'date':
                            inputHtml = `<input type="date" class="form-control form-control-sm" ${commonAttrs}>`;
                            break;
                        case 'dateTime':
                        case 'instant':
                            inputHtml = `<input type="datetime-local" class="form-control form-control-sm" placeholder="${placeholder}" ${commonAttrs}>`;
                            break;
                        case 'integer': case 'positiveInt': case 'unsignedInt':
                            inputHtml = `<input type="number" class="form-control form-control-sm" placeholder="${placeholder}" ${commonAttrs}>`;
                            break;
                        case 'uri': case 'url': case 'canonical':
                             inputHtml = `<input type="url" class="form-control form-control-sm" placeholder="${placeholder}" ${commonAttrs}>`;
                             break;
                        default:
                            inputHtml = `<input type="text" class="form-control form-control-sm" placeholder="${placeholder}" ${commonAttrs}>`;
                    }
                    return `
                        <tr data-param-name="${p.name}" data-param-in="${p.in}">
                            <td class="parameters-col_name">
                                <div class="parameter__name ${p.required ? 'required' : ''}">${p.name}${p.required ? '<span>*</span>' : ''}</div>
                                <div class="parameter__type">${p.type}</div>
                                <div class="parameter__in">(${p.in})</div>
                            </td>
                            <td class="parameters-col_description">
                                <div class="renderedMarkdown mb-1"><p>${p.description || 'No description'}</p></div>
                                ${inputHtml}
                            </td>
                        </tr>`;
                }).join('')
                : `<tr><td colspan="2"><div class="renderedMarkdown"><p>No parameters defined.</p></div></td></tr>`;
            // --- End Parameters Table HTML Generation ---


            // --- Generate Main Block HTML ---
             block.innerHTML = `
                 <div class="opblock-summary">
                     <span class="opblock-summary-method ${query.method.toLowerCase()}">${query.method}</span>
                     <span class="opblock-summary-path">${query.path}</span>
                     <span class="opblock-summary-description">${query.description}</span>
                     <svg class="arrow" viewBox="0 0 20 20"><path fill="currentColor" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"/></svg>
                 </div>
                 <div class="opblock-body">
                     <div class="opblock-section parameters-section">
                         <div class="opblock-section-header">
                             <h4 class="opblock-title">Parameters</h4>
                             <div class="try-out"><button class="btn btn-sm btn-primary try-out__btn">Try it out</button></div>
                         </div>
                         <div class="parameters-container">
                             <table class="parameters-table">
                                 <thead><tr><th class="parameters-col_name">Name</th><th class="parameters-col_description">Description</th></tr></thead>
                                 <tbody>${parametersHtml}</tbody> {/* <<< Inject parameters HTML */}
                             </table>
                         </div>
                     </div>
                     ${query.requestBody ? `
                     <div class="opblock-section request-body-section">
                          <div class="opblock-section-header">
                              <h4 class="opblock-title">Request Body</h4>
                              <div class="content-type-wrapper">
                                  <label for="${blockId}-request-content-type" class="visually-hidden">Request Content Type</label>
                                  <select id="${blockId}-request-content-type" class="content-type request-content-type form-select form-select-sm" aria-label="Request body content type" disabled>
                                      <option value="application/fhir+json" selected>application/fhir+json</option>
                                      <option value="application/fhir+xml">application/fhir+xml</option>
                                      ${query.method === 'POST' && query.path.endsWith('_search') ? '<option value="application/x-www-form-urlencoded">application/x-www-form-urlencoded</option>' : ''}
                                      ${query.parameters.some(p => p.in === 'body (Parameters)') ? '<option value="application/fhir+json">Parameters (JSON)</option>' : ''} {/* Indicate Parameters body */}
                                  </select>
                              </div>
                          </div>
                          <textarea class="request-body-textarea form-control" placeholder="Enter request body (e.g., FHIR Resource JSON/XML, or Parameters JSON)" aria-label="Request body input" disabled>${
                              // Pre-fill textarea if example is likely JSON/XML/urlencoded, but NOT Parameters
                              (query.method === 'POST' && query.path.endsWith('_search')) || (query.example && typeof query.example === 'string' && !query.example.trim().startsWith('{"resourceType":"Parameters"'))
                              ? query.example
                              : ''
                          }</textarea>
                           <div class="model-example request-body-example" style="margin-top: 10px; ${(query.method === 'POST' && query.path.endsWith('_search')) ? 'display: none;' : ''}">
                              <ul class="tab" role="tablist"><li class="tabitem active"><button class="tablinks badge active" data-name="example">Example Body</button></li></ul>
                              <div class="example-panel" style="display: block;"><div class="highlight-code"><pre class="request-example-code"><code class="language-json">${
                                  // Show example if it's not Parameters resource or if it's specifically urlencoded
                                  query.example && typeof query.example === 'string' && (!query.example.trim().startsWith('{"resourceType":"Parameters"') || (query.method === 'POST' && query.path.endsWith('_search')))
                                  ? query.example : '{}'
                              }</code></pre></div></div>
                          </div>
                     </div>` : ''}
                     <div class="opblock-section execute-section">
                         <button class="btn btn-success execute__btn" disabled>Execute</button>
                     </div>
                     <div class="execute-wrapper" style="display: none;">
                         <div class="opblock-section request-url-section"><h5 class="opblock-title">Request URL</h5><pre class="request-url-output"><code></code></pre></div>
                         <div class="opblock-section curl-section"><div class="opblock-section-header"><h5 class="opblock-title">Curl</h5><button type="button" class="btn btn-sm btn-outline-secondary btn-copy copy-curl-btn" title="Copy Curl Command"><i class="bi bi-clipboard"></i> Copy</button></div><pre class="curl-output"><code></code></pre></div>
                         <div class="opblock-section-header"><h4 class="opblock-title">Server Response</h4> <div class="response-controls"> <select class="response-format-select form-select form-select-sm" aria-label="Response display format" style="display: none;"><option value="json">JSON</option><option value="xml">XML</option><option value="narrative">Narrative</option></select><button type="button" class="btn btn-sm btn-outline-secondary btn-copy copy-response-btn" title="Copy Response Body" style="display: none;"><i class="bi bi-clipboard"></i> Copy</button> <button type="button" class="btn btn-sm btn-outline-secondary btn-copy download-response-btn" title="Download Response Body" style="display: none;"><i class="bi bi-download"></i> Download</button></div></div><pre class="response-output-content"><code></code></pre><div class="response-output-narrative" style="display:none;"></div><div class="response-status" style="margin-top: 5px; font-weight: bold;"></div>
                     </div>
                     <div class="opblock-section responses-section">
                          <div class="opblock-section-header"><h4>Example Response / Schema</h4></div><table class="responses-table"><thead><tr class="responses-header"><td class="response-col_status">Code</td><td class="response-col_description">Description</td></tr></thead><tbody><tr class="response" data-code="200"><td class="response-col_status">200</td><td class="response-col_description"><div class="response-col_description__inner"><div class="renderedMarkdown"><p>Success</p></div></div><section class="response-controls mb-2"><div class="row g-2 align-items-center mb-1">
                          <div class="col-auto"><label for="${blockId}-example-media-type" class="response-control-media-type__title mb-0">Example Format:</label></div><div class="col-auto"><div class="content-type-wrapper"><select id="${blockId}-example-media-type" aria-label="Example Media Type" class="content-type example-media-type-select form-select form-select-sm" style="width: auto;"><option value="application/fhir+json">JSON</option><option value="application/fhir+xml">XML</option></select></div></div><div class="col"><small class="response-control-media-type__accept-message text-muted">Controls example/schema format.</small></div></div></section><div class="model-example"><ul class="tab list-unstyled ps-0 mb-2" role="tablist"><li class="tabitem active"><button class="tablinks badge active" data-name="example">Example Value</button></li><li class="tabitem"><button class="tablinks badge" data-name="schema">Schema</button></li></ul><div class="example-panel" style="display: block;"><div class="highlight-code"><pre class="example-code-display"><code class="language-json">${query.example && typeof query.example === 'string' ? query.example : '{}'}</code></pre></div></div><div class="schema-panel" style="display: none;"><div class="highlight-code"><pre class="schema-code-display"><code class="language-json">${JSON.stringify(query.schema || {}, null, 2)}</code></pre></div></div></div></td></tr><tr class="response" data-code="4xx/5xx"><td class="response-col_status">4xx/5xx</td><td class="response-col_description"><p>Error (e.g., Not Found, Server Error)</p></td></tr></tbody></table>
                     </div>
                 </div>`;
             queryListContainer.appendChild(block);
            // --- End Main Block HTML Generation ---


            // --- Get Element References (ensure paramInputs selects all relevant elements) ---
            const opblockSummary = block.querySelector('.opblock-summary');
            const opblockBody = block.querySelector('.opblock-body');
            const tryButton = block.querySelector('.try-out__btn');
            const executeButton = block.querySelector('.execute__btn');
            const paramInputs = block.querySelectorAll('.parameters-section input, .parameters-section select'); // Select inputs AND selects
            const reqBodyTextarea = block.querySelector('.request-body-textarea');
            const reqContentTypeSelect = block.querySelector('.request-content-type');
            const executeWrapper = block.querySelector('.execute-wrapper');
            const respOutputPre = executeWrapper?.querySelector('.response-output-content');
            const respOutputCode = respOutputPre?.querySelector('code');
            const respNarrativeDiv = executeWrapper?.querySelector('.response-output-narrative');
            const respStatusDiv = executeWrapper?.querySelector('.response-status');
            const respFormatSelect = executeWrapper?.querySelector('.response-format-select');
            const reqUrlOutput = executeWrapper?.querySelector('.request-url-output code');
            const curlOutput = executeWrapper?.querySelector('.curl-output code');
            const copyCurlButton = executeWrapper?.querySelector('.copy-curl-btn');
            const copyRespButton = executeWrapper?.querySelector('.copy-response-btn');
            const downloadRespButton = executeWrapper?.querySelector('.download-response-btn');
            const exampleMediaTypeSelect = block.querySelector('.example-media-type-select');
            const exampleTabs = block.querySelectorAll('.responses-section .tablinks.badge');
            const examplePanel = block.querySelector('.responses-section .example-panel');
            const schemaPanel = block.querySelector('.responses-section .schema-panel');


            // --- Attach Event Listeners ---
            // Opblock Toggle
            if (opblockSummary) {
                 opblockSummary.addEventListener('click', (e) => {
                    if (e.target.closest('button, a, input, select')) return;
                    const wasOpen = block.classList.contains('is-open');
                    block.classList.toggle('is-open', !wasOpen);
                    if(opblockBody) opblockBody.style.display = wasOpen ? 'none' : 'block';
                 });
            }

            // 'Try it out' Button
            if (tryButton && executeButton) {
                tryButton.addEventListener('click', () => {
                    const isEditing = tryButton.classList.contains('cancel');
                    const enable = !isEditing;
                    // Enable/Disable and Reset Parameter Inputs
                    paramInputs.forEach(input => {
                        input.disabled = !enable;
                        if (!enable) { // Resetting when canceling
                             input.classList.remove('is-invalid');
                             if (input.type === 'checkbox') {
                                 input.checked = false; // Reset checkbox
                             } else if (input.tagName === 'SELECT') {
                                  const exampleValue = input.dataset.example; // Reset select
                                  if (exampleValue && input.querySelector(`option[value="${exampleValue}"]`)) { input.value = exampleValue; }
                                  else if (input.options.length > 0) { input.selectedIndex = 0; }
                             } else {
                                  input.value = input.dataset.example || ''; // Reset other inputs
                             }
                        }
                    });
                    // Enable/Disable Request Body Area
                    if (reqBodyTextarea) reqBodyTextarea.disabled = !enable;
                    if (reqContentTypeSelect) reqContentTypeSelect.disabled = !enable;
                    // Reset textarea only if canceling and it's not for Parameters body
                    if (!enable && reqBodyTextarea && !query.parameters.some(p => p.in === 'body (Parameters)')) {
                         reqBodyTextarea.value = (query.method === 'POST' && query.path.endsWith('_search')) ? query.example : '';
                    }
                    // Toggle Button State
                    tryButton.textContent = enable ? 'Cancel' : 'Try it out';
                    tryButton.classList.toggle('cancel', enable);
                    tryButton.classList.toggle('btn-danger', enable);
                    tryButton.classList.toggle('btn-primary', !enable);
                    // Toggle Execute Button and Response Area
                    executeButton.style.display = enable ? 'inline-block' : 'none';
                    executeButton.disabled = !enable;
                    if (!enable && executeWrapper) {
                        executeWrapper.style.display = 'none';
                        // Clear execution results on cancel
                        if (reqUrlOutput) reqUrlOutput.textContent = '';
                        if (curlOutput) curlOutput.textContent = '';
                        if (respOutputCode) respOutputCode.textContent = '';
                        if (respNarrativeDiv) respNarrativeDiv.innerHTML = '';
                        if (respStatusDiv) respStatusDiv.textContent = '';
                        if (respFormatSelect) respFormatSelect.style.display = 'none';
                        if (copyRespButton) copyRespButton.style.display = 'none';
                        if (downloadRespButton) downloadRespButton.style.display = 'none';
                    }
                });
            }

            // Request Content Type Change
            if (reqContentTypeSelect && reqBodyTextarea && tryButton) {
                 const reqExampleCode = block.querySelector('.request-example-code code');
                 const reqExampleContainer = block.querySelector('.request-body-example');
                 reqContentTypeSelect.addEventListener('change', () => {
                     const type = reqContentTypeSelect.value;
                     const isFormUrlEncoded = type === 'application/x-www-form-urlencoded';
                     const isJsonParams = type === 'application/fhir+json' && query.parameters.some(p => p.in === 'body (Parameters)');
                     const isEditing = tryButton.classList.contains('cancel');
                     // Hide example display if body will be form data or JSON Parameters
                     if (reqExampleContainer) reqExampleContainer.style.display = (isFormUrlEncoded || isJsonParams) ? 'none' : 'block';
                     // Set placeholder and maybe reset value if not editing
                     if (reqBodyTextarea) {
                         reqBodyTextarea.placeholder = isFormUrlEncoded ? 'e.g., param1=value1&param2=value2' :
                                                        isJsonParams ? 'Enter Parameters resource JSON (or leave blank if using inputs above)...' :
                                                        'Enter FHIR resource JSON or XML...';
                         if (!isEditing) { // Only reset value if not editing
                             reqBodyTextarea.value = isFormUrlEncoded ? query.example :
                                                     isJsonParams ? query.example : // Pre-fill with example Parameters
                                                      '';
                         }
                     }
                     // Update code block example if applicable
                     if (reqExampleCode && !isFormUrlEncoded && !isJsonParams) {
                          const jsonExample = query.example && typeof query.example === 'string' && query.example.startsWith('{') ? query.example : '{}';
                          if (type === 'application/fhir+json') {
                              reqExampleCode.className = 'language-json'; reqExampleCode.textContent = jsonExample; Prism.highlightElement(reqExampleCode);
                          } else if (type === 'application/fhir+xml') {
                              reqExampleCode.className = 'language-xml'; reqExampleCode.textContent = jsonToFhirXml(jsonExample); Prism.highlightElement(reqExampleCode);
                          }
                     }
                 });
                 reqContentTypeSelect.dispatchEvent(new Event('change')); // Trigger initial state
            }

// Execute Button (Includes Enhanced Error Display)
             // <<< Execute Button Listener with Logging and Array Conversion Fix >>>
             if (executeButton && executeWrapper && respStatusDiv && reqUrlOutput && curlOutput && respFormatSelect && copyRespButton && downloadRespButton && respOutputCode && respNarrativeDiv && respOutputPre) {
                executeButton.addEventListener('click', async () => {
                    console.log("[LOG 1] Execute button clicked. Starting listener...");
                    executeButton.disabled = true;
                    executeButton.textContent = 'Executing...';
                    executeWrapper.style.display = 'block';
                    if (reqUrlOutput) reqUrlOutput.textContent = 'Building request...';
                    if (curlOutput) curlOutput.textContent = 'Building request...';
                    if (respOutputCode) respOutputCode.textContent = '';
                    if (respNarrativeDiv) respNarrativeDiv.innerHTML = '';
                    respNarrativeDiv.style.display = 'none';
                    if (respOutputPre) respOutputPre.style.display = 'block';
                    if (respStatusDiv) respStatusDiv.textContent = 'Executing request...';
                    respStatusDiv.style.color = '#6c757d';
                    if (respFormatSelect) respFormatSelect.style.display = 'none';
                    respFormatSelect.value = 'json';
                    if (copyRespButton) copyRespButton.style.display = 'none';
                    if (downloadRespButton) downloadRespButton.style.display = 'none';

                    const queryDef = JSON.parse(block.dataset.queryData);
                    const method = queryDef.method;
                    const headers = { 'Accept': 'application/fhir+json, application/fhir+xml;q=0.9, */*;q=0.8' };
                    let body;
                    let path = queryDef.path;
                    const baseUrl = isUsingLocalHapi ? '/fhir' : (fhirServerUrlInput.value.trim().replace(/\/+$/, '') || '/fhir');
                    let url = `${baseUrl}`;
                    let validParams = true;
                    const missingParams = [];
                    const bodyParamsList = [];

                    if (!isUsingLocalHapi) {
                        const authType = authTypeSelect.value;
                        const bearerToken = bearerTokenInput.value.trim();
                        const username = usernameInput.value.trim();
                        const password = passwordInput.value;
                        if (authType === 'bearer') {
                            headers['Authorization'] = `Bearer ${bearerToken}`;
                            console.log("Adding header Authorization: Bearer <truncated>");
                        } else if (authType === 'basic') {
                            headers['Authorization'] = `Basic ${btoa(`${username}:${password}`)}`;
                            console.log("Adding header Authorization: Basic <redacted>");
                        }
                    }

                    Array.from(block.querySelectorAll('.parameters-section tr[data-param-in="path"]')).forEach(row => {
                        const paramName = row.dataset.paramName;
                        const input = row.querySelector('input');
                        const paramDef = queryDef.parameters.find(p => p.name === paramName && p.in === 'path');
                        const required = paramDef?.required;
                        const value = input?.value.trim();
                        if (input) input.classList.remove('is-invalid');
                        if (!value && required) {
                            validParams = false;
                            missingParams.push(`${paramName} (path)`);
                            if (input) input.classList.add('is-invalid');
                        } else if (value) {
                            path = path.replace(`:${paramName}`, encodeURIComponent(value));
                        } else {
                            path = path.replace(`/:${paramName}`, '');
                        }
                    });
                    if (path.includes(':')) {
                        const remainingPlaceholders = path.match(/:(\w+)/g) || [];
                        const requiredRemaining = queryDef.parameters.filter(p => p.in === 'path' && remainingPlaceholders.includes(`:${p.name}`) && p.required);
                        if (requiredRemaining.length > 0) {
                            validParams = false;
                            missingParams.push(...requiredRemaining.map(p => `${p.name} (path)`));
                            requiredRemaining.forEach(p => {
                                const el = block.querySelector(`.parameters-section tr[data-param-name="${p.name}"][data-param-in="path"] input`);
                                if (el) el.classList.add('is-invalid');
                            });
                        }
                    }
                    url += path.startsWith('/') ? path : `/${path}`;

                    const searchParams = new URLSearchParams();
                    Array.from(block.querySelectorAll('.parameters-section tr[data-param-in="query"], .parameters-section tr[data-param-in="body (Parameters)"]')).forEach(row => {
                        const paramName = row.dataset.paramName;
                        const paramIn = row.dataset.paramIn;
                        const inputElement = row.querySelector('input, select');
                        const paramDef = queryDef.parameters.find(p => p.name === paramName && p.in === paramIn);
                        const required = paramDef?.required;
                        let value = '';
                        if (inputElement) inputElement.classList.remove('is-invalid');
                        if (inputElement?.type === 'checkbox') {
                            value = inputElement.checked ? (inputElement.value || 'true') : '';
                        } else if (inputElement) {
                            value = inputElement.value.trim();
                        }
                        if (value) {
                            if (paramIn === 'query') {
                                searchParams.set(paramName, value);
                            } else {
                                let paramPart = { name: paramName };
                                const paramType = paramDef?.type || 'string';
                                try {
                                    switch (paramType) {
                                        case 'boolean': paramPart.valueBoolean = (value === 'true'); break;
                                        case 'integer': case 'positiveInt': case 'unsignedInt': paramPart.valueInteger = parseInt(value, 10); break;
                                        case 'decimal': paramPart.valueDecimal = parseFloat(value); break;
                                        case 'date': paramPart.valueDate = value; break;
                                        case 'dateTime': paramPart.valueDateTime = value; break;
                                        case 'instant': try { paramPart.valueInstant = new Date(value).toISOString(); } catch (dateError) { console.warn(`Instant parse failed: ${dateError}`); paramPart.valueString = value; } break;
                                        default: paramPart[`value${paramType.charAt(0).toUpperCase() + paramType.slice(1)}`] = value;
                                    }
                                    if (Object.keys(paramPart).length > 1) { bodyParamsList.push(paramPart); }
                                } catch (typeError) {
                                    console.error(`Error processing body param ${paramName}: ${typeError}`);
                                    bodyParamsList.push({ name: paramName, valueString: value });
                                }
                            }
                        } else if (required) {
                            validParams = false;
                            missingParams.push(`${paramName} (${paramIn})`);
                            if (inputElement) inputElement.classList.add('is-invalid');
                        }
                    });

                    if (!validParams) {
                        const errorMsg = `Error: Missing required parameter(s): ${[...new Set(missingParams)].join(', ')}`;
                        console.error("[LOG 3a] Validation failed:", errorMsg);
                        if (respStatusDiv) { respStatusDiv.textContent = errorMsg; respStatusDiv.style.color = 'red'; }
                        if (reqUrlOutput) reqUrlOutput.textContent = 'Error: Invalid parameters';
                        if (curlOutput) curlOutput.textContent = 'Error: Invalid parameters';
                        executeButton.disabled = false;
                        executeButton.textContent = 'Execute';
                        return;
                    }

                    const queryString = searchParams.toString();
                    if (queryString) url += (url.includes('?') ? '&' : '?') + queryString;

                    if (queryDef.requestBody) {
                        const contentType = reqContentTypeSelect ? reqContentTypeSelect.value : 'application/fhir+json';
                        headers['Content-Type'] = contentType;
                        if (bodyParamsList.length > 0) {
                            if (contentType.includes('json')) {
                                body = JSON.stringify({ resourceType: "Parameters", parameter: bodyParamsList }, null, 2);
                            } else if (contentType.includes('xml')) {
                                try { body = jsonToFhirXml({ resourceType: "Parameters", parameter: bodyParamsList }); }
                                catch (xmlErr) {
                                    console.error("Params->XML failed:", xmlErr);
                                    body = JSON.stringify({ resourceType: "Parameters", parameter: bodyParamsList });
                                    headers['Content-Type'] = 'application/fhir+json';
                                    alert("Failed to create XML body. Sending JSON.");
                                }
                            } else {
                                console.warn(`Unsupported Content-Type ${contentType} for Parameters body. Sending JSON.`);
                                body = JSON.stringify({ resourceType: "Parameters", parameter: bodyParamsList }, null, 2);
                                headers['Content-Type'] = 'application/fhir+json';
                            }
                        } else if (reqBodyTextarea && reqBodyTextarea.value.trim() !== '') {
                            body = reqBodyTextarea.value;
                            if (contentType === 'application/fhir+xml' && body.trim().startsWith('{')) {
                                try { body = jsonToFhirXml(body); } catch (e) { console.warn("Textarea JSON->XML failed", e); }
                            } else if (contentType === 'application/fhir+json' && body.trim().startsWith('<')) {
                                try { body = xmlToFhirJson(body); } catch (e) { console.warn("Textarea XML->JSON failed", e); }
                            }
                        } else {
                            body = '';
                        }
                        if (isUsingLocalHapi && ['POST', 'PUT', 'PATCH', 'DELETE'].includes(method)) {
                            const csrfTokenInput = fhirOperationsForm.querySelector('input[name="csrf_token"]');
                            if (csrfTokenInput && csrfTokenInput.value) {
                                headers['X-CSRFToken'] = csrfTokenInput.value;
                                console.log("[LOG 4f] Added X-CSRFToken header:", headers['X-CSRFToken'] ? 'Yes' : 'No');
                            } else {
                                console.error("[LOG 4g] CSRF token input not found or has no value!");
                            }
                        }
                    } else {
                        body = undefined;
                    }

                    if (reqUrlOutput) reqUrlOutput.textContent = url;
                    if (curlOutput) curlOutput.textContent = generateCurlCommand(method, url, headers, body);
                    console.log(`Executing: ${method} ${url}`);
                    console.log("Headers:", { ...headers, Authorization: headers.Authorization ? '<redacted>' : undefined });
                    if (body !== undefined) console.log("Body:", (body || '').substring(0, 300) + ((body?.length ?? 0) > 300 ? "..." : ""));

                    let respData = { json: null, xml: null, narrative: null, text: null, status: 0, statusText: '', contentType: '' };
                    try {
                        const resp = await fetch(url, { method, headers, body: (body || undefined) });
                        respData.status = resp.status;
                        respData.statusText = resp.statusText;
                        respData.contentType = resp.headers.get('Content-Type') || '';
                        respData.text = await resp.text();
                        if (respStatusDiv) { respStatusDiv.textContent = `Status: ${resp.status} ${resp.statusText}`; respStatusDiv.style.color = resp.ok ? 'green' : 'red'; }

                        let isOperationOutcome = false;
                        let operationOutcomeIssuesHtml = '';
                        if (respData.text) {
                            if (respData.contentType.includes('json')) {
                                try {
                                    respData.json = JSON.parse(respData.text);
                                    try { respData.xml = jsonToFhirXml(respData.json); } catch (xmlConvErr) { respData.xml = `<error>XML conversion failed: ${xmlConvErr.message}</error>`; }
                                    if (respData.json.text?.div) respData.narrative = respData.json.text.div;
                                    if (respData.json.resourceType === 'OperationOutcome') {
                                        isOperationOutcome = true;
                                        operationOutcomeIssuesHtml = formatOperationOutcome(respData.json);
                                    }
                                } catch (e) {
                                    respData.json = { parsingError: e.message, rawText: respData.text };
                                    respData.xml = `<data>${escapeXml(respData.text)}</data>`;
                                }
                            } else if (respData.contentType.includes('xml')) {
                                respData.xml = respData.text;
                                try {
                                    respData.json = JSON.parse(xmlToFhirJson(respData.xml));
                                    const p = new DOMParser(), xd = p.parseFromString(respData.xml, "application/xml"), pe = xd.querySelector("parsererror");
                                    if (pe) throw new Error(pe.textContent);
                                    if (xd.documentElement && xd.documentElement.tagName === 'OperationOutcome') {
                                        isOperationOutcome = true;
                                        operationOutcomeIssuesHtml = formatOperationOutcome(respData.json);
                                    }
                                    const nn = xd.querySelector("div[xmlns='http://www.w3.org/1999/xhtml']");
                                    if (nn) respData.narrative = nn.outerHTML;
                                } catch (e) {
                                    respData.json = { parsingError: e.message, rawText: respData.text };
                                }
                            } else {
                                respData.json = { contentType: respData.contentType, content: respData.text };
                                respData.xml = `<data contentType="${escapeXml(respData.contentType)}">${escapeXml(respData.text)}</data>`;
                            }
                        } else if (resp.ok) {
                            respData.json = { message: "Success (No Content)" };
                            respData.xml = jsonToFhirXml({});
                        } else {
                            respData.json = { error: `Request failed: ${resp.status}`, detail: resp.statusText };
                            respData.xml = `<error>Request failed: ${resp.status} ${escapeXml(resp.statusText)}</error>`;
                        }

                        block.dataset.responseData = JSON.stringify(respData);
                        if (respFormatSelect) { respFormatSelect.style.display = 'inline-block'; respFormatSelect.disabled = false; }
                        if (copyRespButton) copyRespButton.style.display = 'inline-block';
                        if (downloadRespButton) downloadRespButton.style.display = 'inline-block';
                        if (!resp.ok && isOperationOutcome && respNarrativeDiv) {
                            respNarrativeDiv.innerHTML = operationOutcomeIssuesHtml;
                            respNarrativeDiv.style.display = 'block';
                            respOutputPre.style.display = 'none';
                            if (respFormatSelect) {
                                const narrativeOpt = respFormatSelect.querySelector('option[value="narrative"]');
                                if (!narrativeOpt) {
                                    const opt = document.createElement('option');
                                    opt.value = 'narrative';
                                    opt.textContent = 'Formatted Issues';
                                    respFormatSelect.insertBefore(opt, respFormatSelect.firstChild);
                                } else {
                                    narrativeOpt.textContent = 'Formatted Issues';
                                    narrativeOpt.disabled = false;
                                }
                                respFormatSelect.value = 'narrative';
                                respFormatSelect.dispatchEvent(new Event('change'));
                            }
                        } else {
                            const narrativeOption = respFormatSelect?.querySelector('option[value="narrative"]');
                            if (narrativeOption) { narrativeOption.textContent = 'Narrative'; narrativeOption.disabled = !respData.narrative; }
                            respFormatSelect.value = (respData.narrative && respFormatSelect.value === 'narrative') ? 'narrative' : 'json';
                            respFormatSelect?.dispatchEvent(new Event('change'));
                        }
                    } catch (e) {
                        console.error('[LOG 14] Error during fetch or response processing:', e);
                        if (respStatusDiv) { respStatusDiv.textContent = `Error: ${e.message}`; respStatusDiv.style.color = 'red'; }
                        if (respOutputCode) { respOutputCode.textContent = `Request failed: ${e.message}\nURL: ${url}`; respOutputCode.className = 'language-text'; }
                        if (respFormatSelect) respFormatSelect.style.display = 'none';
                        if (copyRespButton) copyRespButton.style.display = 'none';
                        if (downloadRespButton) downloadRespButton.style.display = 'none';
                        if (respNarrativeDiv) respNarrativeDiv.style.display = 'none';
                        if (respOutputPre) respOutputPre.style.display = 'block';
                    } finally {
                        console.log("[LOG 15] Executing finally block.");
                        executeButton.disabled = false;
                        executeButton.textContent = 'Execute';
                    }
                });
            } // End if (executeButton && ...)

            // Response Format Change Listener
            if (respFormatSelect && respNarrativeDiv && respOutputPre && respOutputCode) {
                 respFormatSelect.addEventListener('change', () => {
                      const format = respFormatSelect.value;
                      try {
                           const data = JSON.parse(block.dataset.responseData || '{}');
                           respNarrativeDiv.style.display = 'none'; // Hide narrative by default
                           respOutputPre.style.display = 'block'; // Show pre by default
                           let langClass = 'language-text'; // Default lang class
                           let contentToDisplay = '';
                           let whiteSpace = 'pre-wrap'; // Default whitespace

                           switch (format) {
                                case 'xml':
                                    contentToDisplay = data.xml || data.text || '<No XML>';
                                    langClass = 'language-xml';
                                    whiteSpace = 'pre'; // Use 'pre' for XML to preserve indenting
                                    break;
                                case 'narrative':
                                    if (data.narrative) {
                                        respNarrativeDiv.innerHTML = data.narrative;
                                        respNarrativeDiv.style.display = 'block'; // Show narrative div
                                        respOutputPre.style.display = 'none'; // Hide pre div
                                        contentToDisplay = ''; // Clear pre content just in case
                                    } else {
                                        contentToDisplay = '<Narrative unavailable>';
                                        langClass = 'language-text';
                                    }
                                    break;
                                case 'json':
                                default:
                                    contentToDisplay = data.json ? JSON.stringify(data.json, null, 2) : (data.text || '<No JSON>');
                                    langClass = 'language-json';
                                    break;
                           }

                           // Only update and highlight the <pre> block if it's visible
                           if (respOutputPre.style.display === 'block') {
                                respOutputCode.textContent = contentToDisplay;
                                respOutputCode.className = langClass; // Set class for Prism
                                respOutputPre.style.whiteSpace = whiteSpace;
                                // Check if Prism is loaded before calling
                                if (typeof Prism !== 'undefined') {
                                    Prism.highlightElement(respOutputCode); // Highlight after update
                                } else {
                                     console.warn("Prism.js not loaded, cannot highlight code.");
                                }
                           }
                      } catch (e) { console.error("Error updating response format view:", e); }
                 });
            }

            // Example/Schema Tabs Listener
             if (exampleTabs.length && examplePanel && schemaPanel) {
                  exampleTabs.forEach(tab => { tab.addEventListener('click', () => { exampleTabs.forEach(t => { t.classList.remove('active'); t.classList.remove('bg-primary'); t.classList.add('bg-secondary');}); tab.classList.add('active', 'bg-primary'); tab.classList.remove('bg-secondary'); const target = tab.dataset.name; examplePanel.style.display = target === 'example' ? 'block' : 'none'; schemaPanel.style.display = target === 'schema' ? 'block' : 'none'; updateStaticExampleFormat(block); }); }); // Highlight will be called by updateStaticExampleFormat
             }

            // Example Media Type Change Listener
            if (exampleMediaTypeSelect) {
                 exampleMediaTypeSelect.addEventListener('change', () => updateStaticExampleFormat(block)); // Highlight will be called by updateStaticExampleFormat
            }

            // Copy/Download Button Listeners
            if (copyCurlButton && curlOutput) { copyCurlButton.addEventListener('click', (e) => { if (curlOutput.textContent) copyToClipboard(curlOutput.textContent, e.currentTarget); }); }
            if (copyRespButton && respFormatSelect) { copyRespButton.addEventListener('click', (e) => { const format = respFormatSelect.value; let content = ''; if (format === 'narrative') { content = respNarrativeDiv ? respNarrativeDiv.innerHTML : ''; } else { content = respOutputCode ? respOutputCode.textContent : ''; } if (content) copyToClipboard(content, e.currentTarget); }); }
            if (downloadRespButton && respFormatSelect) { downloadRespButton.addEventListener('click', () => { const format = respFormatSelect.value; let content = ''; let ext = 'txt'; let mime = 'text/plain'; const data = JSON.parse(block.dataset.responseData || '{}'); const dateStamp = new Date().toISOString().replace(/[:.]/g, '-'); const filename = `response-${currentSelectedResource || 'system'}-${query.method}-${dateStamp}`; switch (format) { case 'json': content = data.json ? JSON.stringify(data.json, null, 2) : (data.text || ''); ext = 'json'; mime = 'application/json'; break; case 'xml': content = data.xml || data.text || ''; ext = 'xml'; mime = 'application/xml'; break; case 'narrative': content = respNarrativeDiv ? respNarrativeDiv.innerHTML : ''; ext = 'html'; mime = 'text/html'; break; } if (content) downloadFile(content, `${filename}.${ext}`, mime); }); }

            // Initialize static example format and highlight it
            updateStaticExampleFormat(block);

        }); // End forEach query

        swaggerUiContainer.style.display = 'block';
    } // End updateQueryListUI

    // --- Update Static Example/Schema Format Display (WITH HIGHLIGHTING) ---
    function updateStaticExampleFormat(block) {
        const data = JSON.parse(block.dataset.queryData || '{}');
        const mediaTypeSelect = block.querySelector('.example-media-type-select');
        const examplePanel = block.querySelector('.responses-section .example-panel'); // Find parent panel
        const examplePre = examplePanel?.querySelector('.example-code-display'); // Find pre within panel
        const exampleCode = examplePre?.querySelector('code'); // Find code within pre
        const schemaPanel = block.querySelector('.responses-section .schema-panel'); // Find parent panel
        const schemaPre = schemaPanel?.querySelector('.schema-code-display'); // Find pre within panel
        const schemaCode = schemaPre?.querySelector('code'); // Find code within pre

        if (!mediaTypeSelect || !exampleCode || !schemaCode || !examplePre || !schemaPre || !examplePanel || !schemaPanel) {
             console.warn("Missing elements required for updateStaticExampleFormat in block:", block.id);
             return;
        }

        const mediaType = mediaTypeSelect.value;
        const example = data.example || '';
        const isJsonLike = typeof example === 'string' && example.trim().startsWith('{');
        const exampleJson = isJsonLike ? example : '{}';
        const schemaJson = JSON.stringify(data.schema || {}, null, 2);

        // Update content and classes based on selected media type
        if (mediaType === 'application/fhir+json') {
             exampleCode.textContent = exampleJson; exampleCode.className = 'language-json';
             schemaCode.textContent = schemaJson; schemaCode.className = 'language-json';
             examplePre.style.whiteSpace = 'pre-wrap'; schemaPre.style.whiteSpace = 'pre-wrap';
        }
        else if (mediaType === 'application/fhir+xml') {
             exampleCode.textContent = isJsonLike ? jsonToFhirXml(exampleJson) : `<value>${escapeXml(example)}</value>`; exampleCode.className = 'language-xml';
             schemaCode.textContent = jsonToFhirXml(data.schema || {}); schemaCode.className = 'language-xml';
             examplePre.style.whiteSpace = 'pre'; schemaPre.style.whiteSpace = 'pre';
        }

        // Highlight the code *only if its panel is visible* and Prism exists
        if (typeof Prism !== 'undefined') {
             if (examplePanel.style.display !== 'none') {
                  Prism.highlightElement(exampleCode);
             }
             if (schemaPanel.style.display !== 'none') {
                  Prism.highlightElement(schemaCode);
             }
        } else {
             console.warn("Prism.js not loaded, cannot highlight static examples/schemas.");
        }
    }

    // --- Fetch Server Metadata (FIXED Local URL Handling) ---
    if (fetchMetadataButton) {
        fetchMetadataButton.addEventListener('click', async () => {
            console.log("[fetchMetadata] Button clicked");
            if (resourceButtonsContainer) resourceButtonsContainer.innerHTML = '<span class="text-muted">Fetching...</span>';
            if (resourceTypesDisplayDiv) resourceTypesDisplayDiv.style.display = 'block';
            if (swaggerUiContainer) swaggerUiContainer.style.display = 'none';
            fetchedMetadataCache = null;
            availableSystemOperations = [];

            const customUrl = fhirServerUrlInput.value.trim().replace(/\/+$/, '');
            const baseUrl = isUsingLocalHapi ? '/fhir' : customUrl;

            if (!isUsingLocalHapi && !baseUrl) {
                console.error("[fetchMetadata] Custom URL required");
                fhirServerUrlInput.classList.add('is-invalid');
                alert('Please enter a valid FHIR server URL.');
                if (resourceButtonsContainer) resourceButtonsContainer.innerHTML = `<span class="text-danger">Error: Custom URL required.</span>`;
                return;
            }
            if (!isUsingLocalHapi) {
                try { new URL(baseUrl); } catch (_) {
                    console.error("[fetchMetadata] Invalid custom URL format");
                    fhirServerUrlInput.classList.add('is-invalid');
                    alert('Invalid custom URL format. Please enter a valid URL (e.g., https://example.com/fhir).');
                    if (resourceButtonsContainer) resourceButtonsContainer.innerHTML = `<span class="text-danger">Error: Invalid custom URL format.</span>`;
                    return;
                }
                const authType = authTypeSelect.value;
                const bearerToken = bearerTokenInput.value.trim();
                const username = usernameInput.value.trim();
                const password = passwordInput.value;
                if (authType === 'bearer' && !bearerToken) {
                    console.error("[fetchMetadata] Bearer token required");
                    alert('Please enter a Bearer Token.');
                    bearerTokenInput.classList.add('is-invalid');
                    return;
                }
                if (authType === 'basic' && (!username || !password)) {
                    console.error("[fetchMetadata] Username and password required");
                    alert('Please enter both Username and Password for Basic Authentication.');
                    if (!username) usernameInput.classList.add('is-invalid');
                    if (!password) passwordInput.classList.add('is-invalid');
                    return;
                }
            }
            fhirServerUrlInput.classList.remove('is-invalid');

            const url = `${baseUrl}/metadata`;
            const headers = { 'Accept': 'application/fhir+json' };
            if (!isUsingLocalHapi) {
                const authType = authTypeSelect.value;
                const bearerToken = bearerTokenInput.value.trim();
                const username = usernameInput.value.trim();
                const password = passwordInput.value;
                if (authType === 'bearer') {
                    headers['Authorization'] = `Bearer ${bearerToken}`;
                    console.log("[fetchMetadata] Adding header Authorization: Bearer <truncated>");
                } else if (authType === 'basic') {
                    headers['Authorization'] = `Basic ${btoa(`${username}:${password}`)}`;
                    console.log("[fetchMetadata] Adding header Authorization: Basic <redacted>");
                }
            }

            console.log(`[fetchMetadata] Fetching from: ${url}`);
            fetchMetadataButton.disabled = true;
            fetchMetadataButton.textContent = 'Fetching...';

            try {
                const resp = await fetch(url, { method: 'GET', headers });
                if (!resp.ok) { 
                    const errText = await resp.text(); 
                    throw new Error(`HTTP ${resp.status} ${resp.statusText}: ${errText.substring(0, 500)}`); 
                }
                const data = await resp.json();
                console.log('[fetchMetadata] Metadata received:', data);
                fetchedMetadataCache = data;
                displayMetadataAndResourceButtons(data);
            } catch (e) {
                console.error('[fetchMetadata] Error:', e);
                if (resourceButtonsContainer) resourceButtonsContainer.innerHTML = `<span class="text-danger">Error fetching metadata: ${e.message}</span>`;
                if (resourceTypesDisplayDiv) resourceTypesDisplayDiv.style.display = 'block';
                if (swaggerUiContainer) swaggerUiContainer.style.display = 'none';
                alert(`Error fetching metadata: ${e.message}`);
                fetchedMetadataCache = null;
                availableSystemOperations = [];
            } finally {
                fetchMetadataButton.disabled = false;
                fetchMetadataButton.textContent = 'Fetch Metadata';
            }
        });
} else {
         console.error("Fetch Metadata button (#fetchMetadata) not found!");
    }

    // Helper function to format OperationOutcome issues into HTML
    function formatOperationOutcome(outcome) {
        if (!outcome || outcome.resourceType !== 'OperationOutcome' || !outcome.issue || outcome.issue.length === 0) {
            return '<p><em>Received error status, but no detailed OperationOutcome issues found.</em></p>';
        }

        let html = '<div class="operation-outcome-details">';
        html += '<h5>Operation Outcome Issues:</h5>';
        html += '<ul class="list-unstyled">';

        outcome.issue.forEach(issue => {
            const severity = issue.severity || 'information';
            const code = issue.code || 'unknown';
            const diagnostics = issue.diagnostics ? escapeXml(issue.diagnostics) : ''; // Escape HTML in diagnostics
            const detailsText = issue.details?.text ? escapeXml(issue.details.text) : '';
            const location = issue.location ? issue.location.join(', ') : '';

            let iconClass = 'bi-info-circle-fill text-info'; // Default icon
            let severityClass = 'text-info';
            switch (severity) {
                case 'fatal':
                case 'error':
                    iconClass = 'bi-x-octagon-fill text-danger';
                    severityClass = 'text-danger';
                    break;
                case 'warning':
                    iconClass = 'bi-exclamation-triangle-fill text-warning';
                    severityClass = 'text-warning';
                    break;
                case 'information':
                     iconClass = 'bi-info-circle-fill text-info';
                     severityClass = 'text-info';
                     break;
            }

            html += `<li class="mb-2 border-bottom pb-1">`;
            html += `<strong class="${severityClass}"><i class="bi ${iconClass} me-2"></i>${severity.toUpperCase()} (${code})</strong>`;
            if (location) {
                html += `<br><small class="text-muted">Location: ${location}</small>`;
            }
            if (detailsText) {
                html += `<p class="mb-0 mt-1 small">${detailsText}</p>`;
            }
             if (diagnostics) {
                html += `<p class="mb-0 mt-1 small"><em>Diagnostics: ${diagnostics}</em></p>`;
            }
            html += `</li>`;
        });

        html += '</ul>';
        html += '</div>';
        return html;
    }


// --- Display Metadata & Parse Operations (Applying async to listeners) ---
    function displayMetadataAndResourceButtons(data) {
        const rest = data?.rest?.[0];
        if (!rest) { resourceButtonsContainer.innerHTML = `<span class="text-danger">Error: Invalid CapabilityStatement (missing 'rest').</span>`; resourceTypesDisplayDiv.style.display = 'block'; swaggerUiContainer.style.display = 'none'; availableSystemOperations = []; return; }
        const resourceTypes = rest.resource?.map(r => r.type).filter(Boolean) || [];
        const interactions = rest.interaction?.map(i => i.code) || [];

        // --- PARSE OPERATIONS (Revised Method/Level Detection) ---
        // This part remains synchronous - parsing the already fetched metadata
        availableSystemOperations = (rest.operation || []).map(op => {
            const name = op.name || '';
            const defUrl = op.definition || '';
            let levels = new Set();
            let methods = new Set();

            // (Keep existing level detection logic...)
             if (defUrl.includes('System') || name.includes('system') || ['transaction', 'batch', 'metadata', 'history-system'].includes(name)) levels.add('system');
             if (defUrl.includes('Type') || name.includes('type') || name.startsWith('$')) levels.add('type');
             if (defUrl.includes('Instance') || name.includes('instance') || (name.startsWith('$') && !name.endsWith('-system'))) levels.add('instance');
             if (!levels.size) { if (name.startsWith('$') || ['transaction', 'batch', 'metadata', 'history-system', 'capabilities'].includes(name)) levels.add('system'); else { levels.add('type'); levels.add('instance'); } }


            // (Keep existing method detection logic...)
             if (['metadata', 'history-system', 'history-type', 'history-instance', 'capabilities'].includes(name)) { methods.add('GET'); }
             else if (name === 'transaction' || name === 'batch' || name === 'server-transaction') { methods.add('POST'); levels = new Set(['system']); }
             else if (['diff', 'meta', 'get-resource-counts'].includes(name)) { methods.add('GET'); methods.add('POST'); }
             else if (['reindex', 'perform-reindexing-pass', 'mark-all-resources-for-reindexing', 'expunge', 'reindex-terminology', 'hapi.fhir.replace-references'].includes(name)) { methods.add('POST'); }
             else { methods.add('POST'); if (op.documentation?.toLowerCase().includes(' http get') || defUrl.toLowerCase().includes('get')) { methods.add('GET'); } }

            return { name, methods: Array.from(methods), documentation: op.documentation || '', definition: defUrl, levels: Array.from(levels) };
        }).filter(op => op.name);

        console.log("Final Parsed Operations List:", availableSystemOperations);

        resourceButtonsContainer.innerHTML = ''; // Clear previous buttons
        const supportsSystemLevel = interactions.some(code => ['transaction', 'batch', 'history-system', 'search-system', 'capabilities'].includes(code)) || availableSystemOperations.some(op => op.levels.includes('system'));

        // --- Create Buttons and Attach ASYNC Listeners ---
        if (supportsSystemLevel) {
            const systemButton = document.createElement('button');
            systemButton.type = 'button'; systemButton.className = 'btn btn-outline-success btn-sm me-2 mb-2'; systemButton.textContent = 'System';
            // Make the event listener callback async and use await
            systemButton.addEventListener('click', async (event) => { // <<< Added async
                await handleResourceOrSystemButtonClick(event.target, 'System'); // <<< Added await
            });
            resourceButtonsContainer.appendChild(systemButton);
        }

        resourceTypes.sort().forEach(resType => {
            const resourceButton = document.createElement('button');
            resourceButton.type = 'button'; resourceButton.className = 'btn btn-outline-primary btn-sm me-2 mb-2'; resourceButton.textContent = resType;
             // Make the event listener callback async and use await
            resourceButton.addEventListener('click', async (event) => { // <<< Added async
                await handleResourceOrSystemButtonClick(event.target, resType); // <<< Added await
            });
            resourceButtonsContainer.appendChild(resourceButton);
        });

        resourceTypesDisplayDiv.style.display = 'block'; // Show the buttons container

        // --- Trigger Action for First Button ---
        const firstBtn = resourceButtonsContainer.querySelector('button');
        if (firstBtn) {
             // Instead of firstBtn.click(), directly call the async handler
             // Use setTimeout to allow the current rendering cycle to finish first
             setTimeout(async () => {
                 // Ensure the button isn't already active from a previous state if possible
                 if (!firstBtn.classList.contains('active')) {
                     await handleResourceOrSystemButtonClick(firstBtn, firstBtn.textContent);
                 }
             }, 0);
        } else {
            resourceButtonsContainer.innerHTML = '<span class="text-warning">No resources or system operations found in metadata.</span>';
            swaggerUiContainer.style.display = 'none';
        }
    } // End displayMetadataAndResourceButtons

    // --- Handle Resource/System Button Clicks (NOW ASYNC) ---
    async function handleResourceOrSystemButtonClick(clickedButton, resourceOrSystemName) { // <<< Added async
         // (Keep the button class manipulation logic as is)
         resourceButtonsContainer.querySelectorAll('.btn').forEach(button => {
            // ... remove/add classes ...
        });
        // Activate the clicked button
        // ... add/remove classes ...

        await updateQueryListUI(resourceOrSystemName); // <<< Use await
    }

    // --- Initial Page State Setup ---
    resourceTypesDisplayDiv.style.display = 'none';
    swaggerUiContainer.style.display = 'none';
    updateServerToggleUI(); // Set the initial UI state correctly based on default isUsingLocalHapi = true

}); // End DOMContentLoaded Listener
</script>
{% endblock %}