{% extends "base.html" %}
{% from "_form_helpers.html" import render_field %}

{% block content %}
<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">{{ title }}</h1>
    <div class="col-lg-8 mx-auto">
        <p class="lead mb-4">
            Upload FHIR test data (JSON, XML, or ZIP containing JSON/XML) to a target server. The tool will attempt to parse resources, determine dependencies based on references, and upload them in the correct order. Optionally validate resources before uploading.
        </p>
    </div>
</div>

<div class="container mt-4">
    <div class="row justify-content-center">
        <div class="col-lg-8">
            <div class="card shadow-sm mb-4">
                <div class="card-header">
                    <h4 class="my-0 fw-normal"><i class="bi bi-cloud-upload me-2"></i>Upload Configuration</h4>
                </div>
                <div class="card-body">
                    {% if form.errors %}
                        <div class="alert alert-danger">
                            <p><strong>Please correct the following errors:</strong></p>
                            <ul>
                                {% for field, errors in form.errors.items() %}
                                    <li>{{ form[field].label.text }}: {{ errors|join(', ') }}</li>
                                {% endfor %}
                            </ul>
                        </div>
                    {% endif %}

                    <form id="uploadTestDataForm" method="POST" enctype="multipart/form-data">
                        {{ form.csrf_token }}

                        {{ render_field(form.fhir_server_url, class="form-control form-control-lg") }}

                        <div class="row g-3 mb-3 align-items-end">
                            <div class="col-md-5">
                                {{ render_field(form.auth_type, class="form-select") }}
                            </div>
                            <div class="col-md-7" id="authInputsGroup" style="display: none;">
                                <div id="bearerTokenInput" style="display: none;">
                                    {{ render_field(form.auth_token, class="form-control") }}
                                </div>
                                <div id="basicAuthInputs" style="display: none;">
                                    {{ render_field(form.username, class="form-control mb-2", placeholder="Username") }}
                                    {{ render_field(form.password, class="form-control", placeholder="Password", type="password") }}
                                </div>
                            </div>
                        </div>

                        {{ render_field(form.test_data_file, class="form-control") }}
                        <small class="form-text text-muted">Select one or more .json, .xml files, or a single .zip file containing them.</small>

                        <div class="row g-3 mt-3 mb-3 align-items-center">
                            <div class="col-md-6">
                                {{ render_field(form.validate_before_upload) }}
                                <small class="form-text text-muted">It is suggested to not validate against more than 500 files</small>
                            </div>
                            <div class="col-md-6" id="validationPackageGroup" style="display: none;">
                                {{ render_field(form.validation_package_id, class="form-select") }}
                            </div>
                        </div>

                        <div class="row g-3 mb-3">
                            <div class="col-md-4">
                                {{ render_field(form.upload_mode, class="form-select") }}
                            </div>
                            <div class="col-md-4 d-flex align-items-end">
                                {{ render_field(form.use_conditional_uploads) }}
                            </div>
                            <div class="col-md-4">
                                {{ render_field(form.error_handling, class="form-select") }}
                            </div>
                        </div>

                        <button type="submit" class="btn btn-primary btn-lg w-100" id="uploadButton">
                            <span class="spinner-border spinner-border-sm" role="status" aria-hidden="true" style="display: none;"></span>
                            <i class="bi bi-arrow-up-circle me-2"></i>Upload and Process
                        </button>
                    </form>
                </div>
            </div>

            <div class="card shadow-sm">
                <div class="card-header">
                    <h4 class="my-0 fw-normal"><i class="bi bi-terminal me-2"></i>Processing Log & Results</h4>
                </div>
                <div class="card-body">
                    <div id="liveConsole" class="border p-3 rounded bg-dark text-light mb-3" style="height: 300px; overflow-y: auto; font-family: monospace; font-size: 0.85rem;">
                        <span class="text-muted">Processing output will appear here...</span>
                    </div>
                    <div id="uploadResponse" class="mt-3">
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

{% endblock %}

{% block scripts %}
{{ super() }}
<script>
document.addEventListener('DOMContentLoaded', function() {
    const form = document.getElementById('uploadTestDataForm');
    const uploadButton = document.getElementById('uploadButton');
    const spinner = uploadButton ? uploadButton.querySelector('.spinner-border') : null;
    const liveConsole = document.getElementById('liveConsole');
    const responseDiv = document.getElementById('uploadResponse');
    const authTypeSelect = document.getElementById('auth_type');
    const authInputsGroup = document.getElementById('authInputsGroup');
    const bearerTokenInput = document.getElementById('bearerTokenInput');
    const basicAuthInputs = document.getElementById('basicAuthInputs');
    const authTokenInput = document.getElementById('auth_token');
    const usernameInput = document.getElementById('username');
    const passwordInput = document.getElementById('password');
    const fileInput = document.getElementById('test_data_file');
    const validateCheckbox = document.getElementById('validate_before_upload');
    const validationPackageGroup = document.getElementById('validationPackageGroup');
    const validationPackageSelect = document.getElementById('validation_package_id');
    const uploadModeSelect = document.getElementById('upload_mode');
    const conditionalUploadCheckbox = document.getElementById('use_conditional_uploads');

    const sanitizeText = (str) => str ? String(str).replace(/</g, "&lt;").replace(/>/g, "&gt;") : "";

    if (authTypeSelect && authInputsGroup && bearerTokenInput && basicAuthInputs) {
        authTypeSelect.addEventListener('change', function() {
            authInputsGroup.style.display = (this.value === 'bearerToken' || this.value === 'basic') ? 'block' : 'none';
            bearerTokenInput.style.display = this.value === 'bearerToken' ? 'block' : 'none';
            basicAuthInputs.style.display = this.value === 'basic' ? 'block' : 'none';
            if (this.value !== 'bearerToken' && authTokenInput) authTokenInput.value = '';
            if (this.value !== 'basic' && usernameInput) usernameInput.value = '';
            if (this.value !== 'basic' && passwordInput) passwordInput.value = '';
        });
        authInputsGroup.style.display = (authTypeSelect.value === 'bearerToken' || authTypeSelect.value === 'basic') ? 'block' : 'none';
        bearerTokenInput.style.display = authTypeSelect.value === 'bearerToken' ? 'block' : 'none';
        basicAuthInputs.style.display = authTypeSelect.value === 'basic' ? 'block' : 'none';
    } else {
        console.error("Auth elements not found.");
    }

    if (validateCheckbox && validationPackageGroup) {
        const toggleValidationPackage = () => {
             validationPackageGroup.style.display = validateCheckbox.checked ? 'block' : 'none';
        };
        validateCheckbox.addEventListener('change', toggleValidationPackage);
        toggleValidationPackage();
    } else {
        console.error("Validation checkbox or package group not found.");
    }

    if (uploadModeSelect && conditionalUploadCheckbox) {
        const toggleConditionalCheckbox = () => {
            conditionalUploadCheckbox.disabled = (uploadModeSelect.value !== 'individual');
            if (conditionalUploadCheckbox.disabled) {
                conditionalUploadCheckbox.checked = false;
            }
        };
        uploadModeSelect.addEventListener('change', toggleConditionalCheckbox);
        toggleConditionalCheckbox();
    } else {
        console.error("Upload mode select or conditional upload checkbox not found.");
    }

    if (form && uploadButton && spinner && liveConsole && responseDiv && fileInput && validateCheckbox && validationPackageSelect && conditionalUploadCheckbox) {
        form.addEventListener('submit', async function(event) {
            event.preventDefault();
            console.log("Form submitted");

            if (!fileInput.files || fileInput.files.length === 0) { alert('Please select at least one file.'); return; }
            const fhirServerUrl = document.getElementById('fhir_server_url').value.trim();
            if (!fhirServerUrl) { alert('Please enter the Target FHIR Server URL.'); return; }
            if (validateCheckbox.checked && !validationPackageSelect.value) { alert('Please select a package for validation.'); return; }
            if (authTypeSelect.value === 'basic') {
                if (!usernameInput.value.trim()) { alert('Please enter a username for Basic Authentication.'); return; }
                if (!passwordInput.value) { alert('Please enter a password for Basic Authentication.'); return; }
            }

            uploadButton.disabled = true;
            if(spinner) spinner.style.display = 'inline-block';
            const uploadIcon = uploadButton.querySelector('i');
            if (uploadIcon) uploadIcon.style.display = 'none';
            liveConsole.innerHTML = `<div>${new Date().toLocaleTimeString()} [INFO] Starting upload process...</div>`;
            responseDiv.innerHTML = '';

            const formData = new FormData();
            formData.append('fhir_server_url', fhirServerUrl);
            formData.append('auth_type', authTypeSelect.value);
            if (authTypeSelect.value === 'bearerToken' && authTokenInput) {
                formData.append('auth_token', authTokenInput.value);
            } else if (authTypeSelect.value === 'basic') {
                formData.append('username', usernameInput.value);
                formData.append('password', passwordInput.value);
            }
            formData.append('upload_mode', uploadModeSelect.value);
            formData.append('error_handling', document.getElementById('error_handling').value);
            formData.append('validate_before_upload', validateCheckbox.checked ? 'true' : 'false');
            if (validateCheckbox.checked) { formData.append('validation_package_id', validationPackageSelect.value); }
            formData.append('use_conditional_uploads', conditionalUploadCheckbox.checked ? 'true' : 'false');

            for (let i = 0; i < fileInput.files.length; i++) {
                formData.append('test_data_files', fileInput.files[i]);
            }

            const csrfTokenInput = form.querySelector('input[name="csrf_token"]');
            const csrfToken = csrfTokenInput ? csrfTokenInput.value : "";
            const internalApiKey = {{ api_key | default("") | tojson }};

            try {
                const response = await fetch('/api/upload-test-data', {
                    method: 'POST',
                    headers: { 'Accept': 'application/x-ndjson', 'X-CSRFToken': csrfToken, 'X-API-Key': internalApiKey },
                    body: formData
                });

                if (!response.ok) {
                    let errorMsg = `Upload failed: ${response.status} ${response.statusText}`;
                    try { const errorData = await response.json(); errorMsg = errorData.message || JSON.stringify(errorData); } catch (e) {}
                    throw new Error(errorMsg);
                }
                if (!response.body) { throw new Error("Response body missing."); }

                const reader = response.body.getReader();
                const decoder = new TextDecoder();
                let buffer = '';

                while (true) {
                    const { done, value } = await reader.read(); if (done) break;
                    buffer += decoder.decode(value, { stream: true });
                    const lines = buffer.split('\n'); buffer = lines.pop() || '';

                    for (const line of lines) {
                        if (!line.trim()) continue;
                        try {
                            const data = JSON.parse(line); const timestamp = new Date().toLocaleTimeString();
                            let messageClass = 'text-info'; let prefix = '[INFO]';

                            if (data.type === 'error') { prefix = '[ERROR]'; messageClass = 'text-danger'; }
                            else if (data.type === 'success') { prefix = '[SUCCESS]'; messageClass = 'text-success'; }
                            else if (data.type === 'warning') { prefix = '[WARNING]'; messageClass = 'text-warning'; }
                            else if (data.type === 'progress') { prefix = '[PROGRESS]'; messageClass = 'text-light'; }
                            else if (data.type === 'complete') { prefix = '[COMPLETE]'; messageClass = 'text-primary'; }
                            else if (data.type === 'validation_info') { prefix = '[VALIDATION]'; messageClass = 'text-info'; }
                            else if (data.type === 'validation_warning') { prefix = '[VALIDATION]'; messageClass = 'text-warning'; }
                            else if (data.type === 'validation_error') { prefix = '[VALIDATION]'; messageClass = 'text-danger'; }

                            const messageDiv = document.createElement('div'); messageDiv.className = messageClass;
                            let messageText = sanitizeText(data.message) || '...';
                            if (data.details) { messageText += ` <small>(${sanitizeText(data.details)})</small>`; }
                            messageDiv.innerHTML = `${timestamp} ${prefix} ${messageText}`;
                            liveConsole.appendChild(messageDiv); liveConsole.scrollTop = liveConsole.scrollHeight;

                            if (data.type === 'complete' && data.data) {
                                const summary = data.data;
                                let alertClass = 'alert-secondary';
                                if (summary.status === 'success') alertClass = 'alert-success';
                                else if (summary.status === 'partial') alertClass = 'alert-warning';
                                else if (summary.status === 'failure') alertClass = 'alert-danger';

                                responseDiv.innerHTML = `
                                    <div class="alert ${alertClass} mt-3">
                                        <strong>Status: ${sanitizeText(summary.status)}</strong><br>
                                        ${sanitizeText(summary.message)}<hr>
                                        Files Processed: ${summary.files_processed ?? 'N/A'}<br>
                                        Resources Parsed: ${summary.resources_parsed ?? 'N/A'}<br>
                                        Validation Errors: ${summary.validation_errors ?? 'N/A'}<br>
                                        Validation Warnings: ${summary.validation_warnings ?? 'N/A'}<br>
                                        Resources Uploaded: ${summary.resources_uploaded ?? 'N/A'}<br>
                                        Upload Errors: ${summary.error_count ?? 'N/A'}
                                        ${summary.errors?.length > 0 ? '<br><strong>Details:</strong><ul>' + summary.errors.map(e => `<li>${sanitizeText(e)}</li>`).join('') + '</ul>' : ''}
                                    </div>`;
                            }
                        } catch (parseError) { console.error('Stream parse error:', parseError, 'Line:', line); }
                    }
                }

                if (buffer.trim()) {
                    try {
                        const data = JSON.parse(buffer.trim());
                        if (data.type === 'complete' && data.data) { /* ... update summary ... */ }
                    } catch (parseError) { console.error('Final buffer parse error:', parseError); }
                }

            } catch (error) {
                console.error("Upload failed:", error);
                responseDiv.innerHTML = `<div class="alert alert-danger mt-3"><strong>Error:</strong> ${sanitizeText(error.message)}</div>`;
                const ts = new Date().toLocaleTimeString(); const errDiv = document.createElement('div'); errDiv.className = 'text-danger'; errDiv.textContent = `${ts} [CLIENT_ERROR] ${sanitizeText(error.message)}`; liveConsole.appendChild(errDiv);
            } finally {
                uploadButton.disabled = false;
                if(spinner) spinner.style.display = 'none';
                const uploadIcon = uploadButton.querySelector('i');
                if (uploadIcon) uploadIcon.style.display = 'inline-block';
            }
        });
    } else { console.error("Could not find all required elements for form submission."); }
});
</script>
{% endblock %}