{% extends "base.html" %}
{% block title %}Settings - DocuElevate{% endblock %}

{% block head_extra %}
<style>
  .setting-input {
    font-family: 'Courier New', monospace;
  }
</style>
{% endblock %}

{% block content %}
<div class="container mx-auto px-4 py-8" x-data="settingsApp()">
  <!-- Header -->
  <div class="mb-8">
    <div class="flex justify-between items-start">
      <div>
        <h1 class="text-3xl font-bold mb-2">Application Settings</h1>
        <p class="text-gray-600">
          This is a convenience feature to view and edit application settings through the web interface.
        </p>
      </div>
      <div class="flex items-center gap-2">
        <a href="/setup?step=1"
           class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
          <i class="fas fa-magic mr-2" aria-hidden="true"></i> Setup Wizard
        </a>
        <div class="relative" x-data="{ exportOpen: false }">
          <button @click="exportOpen = !exportOpen"
                  class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50">
            <i class="fas fa-download mr-2" aria-hidden="true"></i> Export .env
            <i class="fas fa-chevron-down ml-1 text-xs" aria-hidden="true"></i>
          </button>
          <div x-show="exportOpen" @click.outside="exportOpen = false" x-transition
               class="absolute right-0 mt-1 w-52 bg-white border border-gray-200 rounded-md shadow-lg z-10">
            <a href="/api/settings/export-env?source=db"
               class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-50"
               @click="exportOpen = false">
              <i class="fas fa-database mr-2 text-green-600" aria-hidden="true"></i>DB settings only
            </a>
            <a href="/api/settings/export-env?source=effective"
               class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-50"
               @click="exportOpen = false">
              <i class="fas fa-layer-group mr-2 text-blue-600" aria-hidden="true"></i>Full effective config
            </a>
          </div>
        </div>
        <a href="/admin/settings/audit-log"
           class="inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">
          <i class="fas fa-history mr-2" aria-hidden="true"></i> Audit Log
        </a>
      </div>
    </div>
    <div class="bg-blue-50 border-l-4 border-blue-500 text-blue-700 p-4 my-4" role="alert">
      <p class="font-bold">📋 Settings Precedence Order:</p>
      <ul class="list-disc list-inside ml-4 mt-2">
        <li><span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-green-100 text-green-800">DB</span> Database settings (highest priority) - explicitly saved via this UI</li>
        <li><span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800">ENV</span> Environment variables - from .env file or system environment</li>
        <li><span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-gray-100 text-gray-800">DEFAULT</span> Default values - built-in application defaults</li>
      </ul>
    </div>
    <div class="bg-yellow-100 border-l-4 border-yellow-500 text-yellow-700 p-4 my-4" role="alert">
      <p class="font-bold">⚠️ Important Notes:</p>
      <ul class="list-disc list-inside ml-4 mt-2">
        <li>Settings marked with <span class="text-red-600">*</span> require an application restart to take effect.</li>
        <li>Sensitive values (passwords, API keys) are <strong>encrypted at rest</strong> in the database <i class="fas fa-lock text-xs"></i>.</li>
        <li>Use the <i class="fas fa-eye"></i> icon to temporarily show/hide sensitive values.</li>
        <li>Saving a setting here stores it in the database and overrides environment variables.</li>
        <li>Only administrators can access and modify these settings.</li>
        <li>All fields are optional - you can save just the settings you want to override.</li>
      </ul>
    </div>
  </div>

  <!-- Alert Messages -->
  <div x-show="showAlert" x-transition class="mb-4">
    <div :class="alertType === 'success' ? 'bg-green-100 border-green-500 text-green-700' : 'bg-red-100 border-red-500 text-red-700'"
         class="border-l-4 p-4" role="alert">
      <p class="font-bold" x-text="alertTitle"></p>
      <p x-text="alertMessage"></p>
    </div>
  </div>

  <!-- Form -->
  <form @submit.prevent="saveSettings">
    {% for category, settings_list in settings_data.items() %}
    <div class="bg-white shadow rounded-lg mb-6">
      <!-- Category Header -->
      <div class="bg-gray-100 px-6 py-4 border-b border-gray-200">
        <h2 class="text-xl font-semibold text-gray-800">{{ category }}</h2>
      </div>

      <!-- Settings in this category -->
      <div class="px-6 py-4 space-y-6">
        {% for setting in settings_list %}
        <div class="border-b border-gray-200 pb-6 last:border-b-0">
          <div class="flex justify-between items-start">
            <div class="flex-1">
              <div class="flex items-center gap-2 mb-1">
                <label for="{{ setting.key }}" class="block text-sm font-medium text-gray-700">
                  {{ setting.key.replace('_', ' ').title() }}
                  {% if setting.metadata.restart_required %}
                  <span class="text-red-600">*</span>
                  {% endif %}
                  {% if setting.metadata.required %}
                  <span class="text-red-600 text-xs">(required)</span>
                  {% endif %}
                </label>
                <!-- Source Indicator Badge -->
                <span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium
                  {% if setting.source == 'database' %}
                    bg-green-100 text-green-800
                  {% elif setting.source == 'environment' %}
                    bg-blue-100 text-blue-800
                  {% else %}
                    bg-gray-100 text-gray-800
                  {% endif %}
                " title="Value source: {{ setting.source }}">
                  {{ setting.source_label }}
                </span>
              </div>

              <p class="text-xs text-gray-500 mb-2">
                {{ setting.metadata.description }}
              </p>

              {% if setting.metadata.type == 'boolean' %}
              <!-- Boolean/Checkbox Input -->
              <div class="flex items-center">
                <input
                  type="checkbox"
                  id="{{ setting.key }}"
                  name="{{ setting.key }}"
                  :checked="formData['{{ setting.key }}'] === 'true' || formData['{{ setting.key }}'] === true"
                  @change="formData['{{ setting.key }}'] = $event.target.checked ? 'true' : 'false'"
                  class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
                />
                <label for="{{ setting.key }}" class="ml-2 text-sm text-gray-700">
                  Enable {{ setting.key.replace('_', ' ').title() }}
                </label>
              </div>
              {% elif setting.metadata.type == 'multiselect' and setting.metadata.options %}
              <!-- Multi-select checkboxes: stored as comma-separated string -->
              <div class="flex flex-wrap gap-2 mt-1">
                {% for opt in setting.metadata.options %}
                <label class="inline-flex items-center gap-1.5 px-3 py-1.5 rounded-full border cursor-pointer select-none
                              transition-colors
                              bg-white border-gray-300 hover:border-blue-400"
                       :class="isSelected('{{ setting.key }}', '{{ opt }}')
                               ? 'bg-blue-100 border-blue-500 text-blue-800 font-medium'
                               : 'text-gray-700'">
                  <input type="checkbox"
                         class="sr-only"
                         :checked="isSelected('{{ setting.key }}', '{{ opt }}')"
                         @change="toggleMultiselect('{{ setting.key }}', '{{ opt }}', $event.target.checked)"
                  />
                  <i :class="isSelected('{{ setting.key }}', '{{ opt }}') ? 'fas fa-check-circle text-blue-600' : 'far fa-circle text-gray-400'"></i>
                  <span class="text-sm">{{ opt }}</span>
                </label>
                {% endfor %}
              </div>
              <p class="mt-1 text-xs text-gray-400">Effective value: <code x-text="formData['{{ setting.key }}'] || '(none)'"></code></p>
              {% elif setting.metadata.type == 'model_picker' %}
              <!-- Model Picker: free-text input with datalist of common models -->
              <div class="relative">
                <input
                  type="text"
                  id="{{ setting.key }}"
                  name="{{ setting.key }}"
                  list="{{ setting.key }}_models"
                  x-model="formData['{{ setting.key }}']"
                  class="setting-input w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
                  placeholder="Select a common model or type a custom name…"
                  autocomplete="off"
                />
                <datalist id="{{ setting.key }}_models">
                  {% for m in setting.metadata.suggested_models %}
                  <option value="{{ m }}">{{ m }}</option>
                  {% endfor %}
                </datalist>
                <p class="text-xs text-gray-400 mt-1">
                  <i class="fas fa-info-circle mr-1" aria-hidden="true"></i>
                  Pick from the list or type any model name supported by your provider.
                </p>
              </div>
              {% elif setting.metadata.options %}
              <!-- Dropdown Select for fields with a fixed list of values -->
              <select
                id="{{ setting.key }}"
                name="{{ setting.key }}"
                x-model="formData['{{ setting.key }}']"
                class="setting-input w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
              >
                <option value="">— select —</option>
                {% for opt in setting.metadata.options %}
                <option value="{{ opt }}">{{ opt }}</option>
                {% endfor %}
              </select>
              {% else %}
              <!-- Text / Password Input -->
              <div class="relative">
                {% if setting.metadata.sensitive %}
                <!-- Sensitive Field with Show/Hide Toggle -->
                <div class="relative">
                  <input
                    :type="showPassword['{{ setting.key }}'] ? 'text' : 'password'"
                    id="{{ setting.key }}"
                    name="{{ setting.key }}"
                    x-model="formData['{{ setting.key }}']"
                    class="setting-input w-full px-3 py-2 pr-24 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 font-mono text-sm"
                    placeholder="{{ setting.metadata.description }}"
                    autocomplete="off"
                  />
                  <div class="absolute inset-y-0 right-0 flex items-center pr-3 space-x-2">
                    <!-- Encrypted indicator -->
                    <span class="text-xs text-gray-400" title="Value is encrypted at rest in database">
                      <i class="fas fa-lock"></i>
                    </span>
                    <!-- Show/Hide Toggle -->
                    <button
                      type="button"
                      @click="togglePassword('{{ setting.key }}')"
                      class="text-gray-400 hover:text-gray-600 focus:outline-none"
                      title="Show/hide value"
                      aria-label="Toggle password visibility"
                    >
                      <i :class="showPassword['{{ setting.key }}'] ? 'fas fa-eye-slash' : 'fas fa-eye'"></i>
                    </button>
                  </div>
                </div>
                {% else %}
                <!-- Non-Sensitive Field -->
                <input
                  type="text"
                  id="{{ setting.key }}"
                  name="{{ setting.key }}"
                  x-model="formData['{{ setting.key }}']"
                  class="setting-input w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
                  placeholder="{{ setting.metadata.description }}"
                />
                {% endif %}
              </div>
              {% endif %}
            </div>

            <!-- Per-setting Save / Back-to-ENV buttons -->
            <div class="ml-4 flex-shrink-0 flex flex-row items-center gap-2 pt-1">
              <button
                type="button"
                x-show="isDbOverride['{{ setting.key }}']"
                x-transition
                @click="revertSetting('{{ setting.key }}')"
                :disabled="revertingKey === '{{ setting.key }}'"
                class="px-3 py-1 text-sm bg-red-600 text-white rounded-md hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap"
                title="Remove DB override and revert to environment variable or default"
              >
                <span x-show="revertingKey !== '{{ setting.key }}'"><i class="fas fa-trash-alt mr-1" aria-hidden="true"></i>Remove from DB</span>
                <span x-show="revertingKey === '{{ setting.key }}'">Reverting…</span>
              </button>
              <button
                type="button"
                x-show="formData['{{ setting.key }}'] !== originalData['{{ setting.key }}']"
                x-transition
                @click="saveSetting('{{ setting.key }}')"
                :disabled="savingKey === '{{ setting.key }}'"
                class="px-3 py-1 text-sm bg-green-600 text-white rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-500 disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap"
                title="Save this setting"
              >
                <span x-show="savingKey !== '{{ setting.key }}'"><i class="fas fa-save mr-1" aria-hidden="true"></i>Save</span>
                <span x-show="savingKey === '{{ setting.key }}'">Saving…</span>
              </button>
            </div>
          </div>
        </div>
        {% endfor %}
      </div>
    </div>
    {% endfor %}

    <!-- Action Buttons -->
    <div class="flex justify-end space-x-4 mt-6">
      <button
        type="button"
        @click="resetForm"
        class="px-6 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
      >
        Reset
      </button>
      <button
        type="submit"
        :disabled="saving"
        class="px-6 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 disabled:opacity-50 disabled:cursor-not-allowed"
      >
        <span x-show="!saving">Save Settings</span>
        <span x-show="saving">Saving...</span>
      </button>
    </div>
  </form>
</div>

<script>
function settingsApp() {
  return {
    formData: {},
    originalData: {},
    isDbOverride: {},
    showPassword: {},
    saving: false,
    savingKey: null,
    revertingKey: null,
    showAlert: false,
    alertType: 'success',
    alertTitle: '',
    alertMessage: '',

    init() {
      // Initialize form data from current settings
      {% for category, settings_list in settings_data.items() %}
        {% for setting in settings_list %}
          this.formData['{{ setting.key }}'] = {{ setting.display_value|tojson }};
          this.originalData['{{ setting.key }}'] = {{ setting.display_value|tojson }};
          this.isDbOverride['{{ setting.key }}'] = {{ (setting.source == 'database')|tojson }};
          this.showPassword['{{ setting.key }}'] = false;
        {% endfor %}
      {% endfor %}
    },

    /** Parse a comma-separated multiselect value into a trimmed array. */
    parseMultiselect(key) {
      return (this.formData[key] || '').split(',').map(s => s.trim()).filter(Boolean);
    },

    /** Return true when *option* is present in the comma-separated *key* value. */
    isSelected(key, option) {
      return this.parseMultiselect(key).includes(option);
    },

    /** Add or remove *option* from the comma-separated *key* value. */
    toggleMultiselect(key, option, checked) {
      const current = this.parseMultiselect(key);
      if (checked) {
        if (!current.includes(option)) current.push(option);
      } else {
        const idx = current.indexOf(option);
        if (idx !== -1) current.splice(idx, 1);
      }
      this.formData[key] = current.join(',');
    },

    togglePassword(key) {
      this.showPassword[key] = !this.showPassword[key];
    },

    resetForm() {
      this.formData = { ...this.originalData };
      this.hideAlert();
    },

    showSuccessAlert(title, message) {
      this.alertType = 'success';
      this.alertTitle = title;
      this.alertMessage = message;
      this.showAlert = true;
      setTimeout(() => this.hideAlert(), 5000);
    },

    showErrorAlert(title, message) {
      this.alertType = 'error';
      this.alertTitle = title;
      this.alertMessage = message;
      this.showAlert = true;
      setTimeout(() => this.hideAlert(), 10000);
    },

    hideAlert() {
      this.showAlert = false;
    },

    async saveSetting(key) {
      this.savingKey = key;
      this.hideAlert();

      try {
        const value = this.formData[key];
        const response = await fetch(`/api/settings/${key}`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({ key, value }),
        });

        const result = await response.json();

        if (response.ok && result.success) {
          this.originalData[key] = value;
          this.isDbOverride[key] = true;
          let message = `Setting '${key}' saved successfully.`;
          if (result.restart_required) {
            message += ' Please restart the application for this change to take effect.';
          }
          this.showSuccessAlert('Setting Saved', message);
        } else {
          this.showErrorAlert('Save Failed', result.detail || 'Unknown error');
        }
      } catch (error) {
        console.error('Error saving setting:', error);
        this.showErrorAlert('Error', 'Failed to save setting. Please try again.');
      } finally {
        this.savingKey = null;
      }
    },

    async revertSetting(key) {
      if (!confirm(`Remove '${key}' from the database?\n\nThe setting will revert to its environment variable or default value.`)) {
        return;
      }

      this.revertingKey = key;
      this.hideAlert();

      try {
        const response = await fetch(`/api/settings/${key}`, {
          method: 'DELETE',
        });

        if (response.ok) {
          // Reload the page so the ENV/default value and source badge refresh
          window.location.reload();
        } else {
          const result = await response.json();
          this.showErrorAlert('Revert Failed', result.detail || 'Unknown error');
          this.revertingKey = null;
        }
      } catch (error) {
        console.error('Error reverting setting:', error);
        this.showErrorAlert('Error', 'Failed to revert setting. Please try again.');
        this.revertingKey = null;
      }
    },

    async saveSettings() {
      this.saving = true;
      this.hideAlert();

      try {
        // Prepare updates array
        const updates = [];
        for (const [key, value] of Object.entries(this.formData)) {
          // Only include changed settings
          if (value !== this.originalData[key]) {
            updates.push({ key, value });
          }
        }

        if (updates.length === 0) {
          this.showSuccessAlert('No Changes', 'No settings were modified.');
          this.saving = false;
          return;
        }

        // Send bulk update request
        const response = await fetch('/api/settings/bulk-update', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(updates),
        });

        const result = await response.json();

        if (response.ok && result.success) {
          for (const updated of result.updated) {
            this.originalData[updated.key] = updated.value;
            this.isDbOverride[updated.key] = true;
          }
          let message = `${result.updated.length} setting(s) updated successfully.`;
          if (result.restart_required) {
            message += ' Please restart the application for changes to take effect.';
          }
          this.showSuccessAlert('Settings Saved', message);
        } else {
          const errorMessages = result.errors ? result.errors.map(e => `${e.key}: ${e.error}`).join(', ') : 'Unknown error';
          this.showErrorAlert('Save Failed', errorMessages);
        }
      } catch (error) {
        console.error('Error saving settings:', error);
        this.showErrorAlert('Error', 'Failed to save settings. Please try again.');
      } finally {
        this.saving = false;
      }
    }
  };
}
</script>
{% endblock %}
