{% extends "base.html" %}
{% block content %}
<div class="container mt-4">
  <h1 class="mb-4">HAPI FHIR Configuration Manager</h1>
  {% with messages = get_flashed_messages(with_categories=true) %}
    {% if messages %}
      {% for category, message in messages %}
        <div class="alert alert-{{ category }} alert-dismissible fade show" role="alert">
          {{ message }}
          <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
        </div>
      {% endfor %}
    {% endif %}
  {% endwith %}
  <div id="loading" class="text-center my-4">
    <p>Loading configuration...</p>
    <div class="spinner-border" role="status">
      <span class="visually-hidden">Loading...</span>
    </div>
  </div>
  <div id="error" class="alert alert-danger d-none" role="alert"></div>
  <div id="config-form" class="d-none">
    <div class="mb-3">
      <button id="save-btn" class="btn btn-primary me-2">Save Configuration</button>
      <button id="restart-btn" class="btn btn-success">Restart HAPI Server</button>
      <span id="restart-status" class="ms-3 text-success d-none"></span>
    </div>
    <div id="config-sections"></div>
  </div>
</div>

<script>
  // Configuration descriptions from HAPI FHIR JPA documentation
  const CONFIG_DESCRIPTIONS = {
    'hapi.fhir.narrative_enabled': 'Enables or disables the generation of FHIR resource narratives (human-readable summaries). Set to false to reduce processing overhead. Default: false.',
    'hapi.fhir.mdm_enabled': 'Enables Master Data Management (MDM) features for linking and matching resources (e.g., Patient records). Requires mdm_rules_json_location to be set. Default: false.',
    'hapi.fhir.mdm_rules_json_location': 'Path to the JSON file defining MDM rules for resource matching. Example: "mdm-rules.json".',
    'hapi.fhir.cors.allow_Credentials': 'Allows credentials (e.g., cookies, authorization headers) in CORS requests. Set to true to support authenticated cross-origin requests. Default: true.',
    'hapi.fhir.cors.allowed_origin': 'List of allowed origins for CORS requests. Use ["*"] to allow all origins or specify domains (e.g., ["https://example.com"]). Default: ["*"].',
    'hapi.fhir.tester.home.name': 'Name of the local tester configuration for HAPI FHIR testing UI. Example: "Local Tester".',
    'hapi.fhir.tester.home.server_address': 'URL of the local FHIR server for testing. Example: "http://localhost:8080/fhir".',
    'hapi.fhir.tester.home.refuse_to_fetch_third_party_urls': 'Prevents the tester from fetching third-party URLs. Set to true for security. Default: false.',
    'hapi.fhir.tester.home.fhir_version': 'FHIR version for the local tester (e.g., "R4", "R5"). Default: R4.',
    'hapi.fhir.tester.global.name': 'Name of the global tester configuration for HAPI FHIR testing UI. Example: "Global Tester".',
    'hapi.fhir.tester.global.server_address': 'URL of the global FHIR server for testing. Example: "http://hapi.fhir.org/baseR4".',
    'hapi.fhir.tester.global.refuse_to_fetch_third_party_urls': 'Prevents the global tester from fetching third-party URLs. Default: false.',
    'hapi.fhir.tester.global.fhir_version': 'FHIR version for the global tester (e.g., "R4"). Default: R4.',
    'hapi.fhir.cr.enabled': 'Enables Clinical Reasoning (CR) module for operations like evaluate-measure. Default: false.',
    'hapi.fhir.cr.caregaps.reporter': 'Reporter mode for care gaps in the CR module. Default: "default".',
    'hapi.fhir.cr.caregaps.section_author': 'Author identifier for care gap sections. Default: "default".',
    'hapi.fhir.cr.cql.use_embedded_libraries': 'Uses embedded CQL libraries for Clinical Quality Language processing. Default: true.',
    'hapi.fhir.inline_resource_storage_below_size': 'Maximum size (in bytes) for storing FHIR resources inline in the database. Default: 4000.',
    'hapi.fhir.advanced_lucene_indexing': 'Enables experimental advanced Lucene/Elasticsearch indexing for enhanced search capabilities. Default: false. Note: May not support all FHIR features like _total=accurate.',
    'hapi.fhir.enable_index_of_type': 'Enables indexing of resource types for faster searches. Default: true.',
    // Add more descriptions as needed based on your application.yaml
  };

  document.addEventListener('DOMContentLoaded', () => {
    const configForm = document.getElementById('config-form');
    const loading = document.getElementById('loading');
    const errorDiv = document.getElementById('error');
    const configSections = document.getElementById('config-sections');
    const saveBtn = document.getElementById('save-btn');
    const restartBtn = document.getElementById('restart-btn');
    const restartStatus = document.getElementById('restart-status');
    let configData = {};

    // Fetch initial configuration
    fetch('/api/config')
      .then(res => res.json())
      .then(data => {
        configData = data;
        renderConfigSections();
        loading.classList.add('d-none');
        configForm.classList.remove('d-none');
        // Initialize Bootstrap tooltips
        document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => {
          new bootstrap.Tooltip(el);
        });
      })
      .catch(err => {
        showError('Failed to load configuration');
        loading.classList.add('d-none');
      });

    // Render configuration sections
    function renderConfigSections() {
      configSections.innerHTML = '';
      Object.entries(configData).forEach(([section, values]) => {
        const sectionDiv = document.createElement('div');
        sectionDiv.className = 'card mb-3';
        sectionDiv.innerHTML = `
          <div class="card-header">
            <h3 class="card-title">${section.charAt(0).toUpperCase() + section.slice(1)}</h3>
          </div>
          <div class="card-body">
            ${renderInputs(values, [section])}
          </div>
        `;
        configSections.appendChild(sectionDiv);
      });
    }

    // Render inputs recursively with descriptions
    function renderInputs(obj, path) {
      let html = '';
      Object.entries(obj).forEach(([key, value]) => {
        const inputId = path.concat(key).join('-');
        const configPath = path.concat(key).join('.');
        const description = CONFIG_DESCRIPTIONS[configPath] || 'No description available.';
        if (typeof value === 'boolean') {
          html += `
            <div class="form-check mb-2">
              <input class="form-check-input" type="checkbox" id="${inputId}" ${value ? 'checked' : ''}>
              <label class="form-check-label" for="${inputId}">
                ${key}
                <i class="fas fa-info-circle ms-1" data-bs-toggle="tooltip" data-bs-placement="top" title="${description}"></i>
              </label>
            </div>
          `;
        } else if (typeof value === 'string' || typeof value === 'number') {
          html += `
            <div class="mb-2">
              <label for="${inputId}" class="form-label">
                ${key}
                <i class="fas fa-info-circle ms-1" data-bs-toggle="tooltip" data-bs-placement="top" title="${description}"></i>
              </label>
              <input type="text" class="form-control" id="${inputId}" value="${value}">
            </div>
          `;
        } else if (Array.isArray(value)) {
          html += `
            <div class="mb-2">
              <label for="${inputId}" class="form-label">
                ${key} (comma-separated)
                <i class="fas fa-info-circle ms-1" data-bs-toggle="tooltip" data-bs-placement="top" title="${description}"></i>
              </label>
              <input type="text" class="form-control" id="${inputId}" value="${value.join(',')}">
            </div>
          `;
        } else if (typeof value === 'object' && value !== null) {
          html += `
            <div class="border-start ps-3 ms-3">
              <h4>${key}</h4>
              ${renderInputs(value, path.concat(key))}
            </div>
          `;
        }
      });
      return html;
    }

    // Update config data on input change
    configSections.addEventListener('change', (e) => {
      const path = e.target.id.split('-');
      let value = e.target.type === 'checkbox' ? e.target.checked : e.target.value;
      if (e.target.type === 'text' && e.target.value.includes(',')) {
        value = e.target.value.split(',').map(v => v.trim());
      }
      updateConfig(path, value);
    });

    // Update config object
    function updateConfig(path, value) {
      let current = configData;
      for (let i = 0; i < path.length - 1; i++) {
        current = current[path[i]];
      }
      current[path[path.length - 1]] = value;
    }

    // Save configuration
    saveBtn.addEventListener('click', () => {
      fetch('/api/config', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(configData)
      })
        .then(res => res.json())
        .then(data => {
          if (data.error) {
            showError(data.error);
          } else {
            showSuccess('Configuration saved successfully');
          }
        })
        .catch(() => showError('Failed to save configuration'));
    });

    // Restart HAPI server
    restartBtn.addEventListener('click', () => {
      restartStatus.textContent = 'Restarting...';
      restartStatus.classList.remove('d-none');
      fetch('/api/restart-tomcat', { method: 'POST' })
        .then(res => res.json())
        .then(data => {
          if (data.error) {
            showError(data.error);
            restartStatus.classList.add('d-none');
          } else {
            restartStatus.textContent = 'HAPI server restarted successfully';
            setTimeout(() => {
              restartStatus.classList.add('d-none');
              restartStatus.textContent = '';
            }, 3000);
          }
        })
        .catch(() => {
          showError('Failed to restart HAPI server');
          restartStatus.classList.add('d-none');
        });
    });

    // Show error message
    function showError(message) {
      errorDiv.textContent = message;
      errorDiv.classList.remove('d-none');
      setTimeout(() => errorDiv.classList.add('d-none'), 5000);
    }

    // Show success message
    function showSuccess(message) {
      const alert = document.createElement('div');
      alert.className = 'alert alert-success alert-dismissible fade show';
      alert.innerHTML = `
        ${message}
        <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
      `;
      document.querySelector('.container').insertBefore(alert, configForm);
      setTimeout(() => alert.remove(), 5000);
    }
  });
</script>
{% endblock %}