<!-- [DEF:AdminSettingsPage:Component] -->
<!--
@TIER:      STANDARD
@SEMANTICS: admin, adfs, mappings, configuration, logging
@PURPOSE:   UI for configuring Active Directory Group to local Role mappings for ADFS SSO and logging settings.
@LAYER:     Feature
@RELATION:  DEPENDS_ON -> frontend.src.services.adminService
@RELATION:  DEPENDS_ON -> frontend.src.components.auth.ProtectedRoute

@INVARIANT: Only accessible by users with "admin:settings" permission.
-->

<script lang="ts">
  // [SECTION: IMPORTS]
  import { onMount } from 'svelte';
  import { t } from '$lib/i18n';
  import ProtectedRoute from '../../../components/auth/ProtectedRoute.svelte';
  import { adminService } from '../../../services/adminService';
  // [/SECTION: IMPORTS]

  let mappings = [];
  let roles = [];
  let loading = true;
  let error = null;

  let showCreateModal = false;
  let newMapping = {
    ad_group: '',
    role_id: ''
  };

  // [SECTION: LOGGING_CONFIG]
  let loggingConfig = {
    level: 'INFO',
    task_log_level: 'INFO',
    enable_belief_state: true
  };
  let loggingConfigLoading = false;
  let loggingConfigSaving = false;
  let loggingConfigSaved = false;
  // [/SECTION]

  const LOG_LEVELS = ['DEBUG', 'INFO', 'WARNING', 'ERROR'];

  // [DEF:loadData:Function]
  /**
   * @purpose Fetches AD mappings and roles from the backend to populate the UI.
   * @pre     Component is mounted and user has active session.
   * @post    mappings and roles variables are updated with backend data.
   * @returns {Promise<void>}
   * @side_effect Updates local 'mappings', 'roles', 'loading', and 'error' states.
   * @relation CALLS -> adminService.getRoles
   * @relation CALLS -> adminService.getADGroupMappings
   */
  async function loadData() {
    console.log('[AdminSettingsPage][loadData][Entry]');
    loading = true;
    try {
      // Fetch roles first as they are required for displaying mapping labels
      roles = await adminService.getRoles();
      
      try {
        mappings = await adminService.getADGroupMappings();
      } catch (e) {
        console.warn("[AdminSettingsPage][loadData] AD Mappings endpoint potentially unavailable.");
      }
      
      console.log('[AdminSettingsPage][loadData][Coherence:OK]');
    } catch (e) {
      error = $t.admin?.settings?.load_failed ;
      console.error('[AdminSettingsPage][loadData][Coherence:Failed]', e);
    } finally {
      loading = false;
    }
  }
  // [/DEF:loadData:Function]

  // [DEF:handleCreateMapping:Function]
  /**
   * @purpose Submits a new AD Group to Role mapping to the backend.
   * @pre     'newMapping' object contains valid 'ad_group' and 'role_id'.
   * @post    A new mapping is created in the database and the table is refreshed.
   * @returns {Promise<void>}
   * @side_effect Closes the modal on success, shows alert on failure.
   * @relation CALLS -> adminService.createADGroupMapping
   */
  async function handleCreateMapping() {
    console.log('[AdminSettingsPage][handleCreateMapping][Entry]');
    
    // Guard Clause (@PRE)
    if (!newMapping.ad_group || !newMapping.role_id) {
        alert($t.admin?.settings?.fill_all_fields );
        return;
    }

    try {
      await adminService.createADGroupMapping(newMapping);
      showCreateModal = false;
      // Reset form
      newMapping = { ad_group: '', role_id: '' };
      await loadData();
      console.log('[AdminSettingsPage][handleCreateMapping][Coherence:OK]');
    } catch (e) {
      alert(
        ($t.admin?.settings?.create_mapping_failed )
          .replace('{error}', e.message || ($t.common?.unknown )),
      );
      console.error('[AdminSettingsPage][handleCreateMapping][Coherence:Failed]', e);
    }
  }
  // [/DEF:handleCreateMapping:Function]

  // [DEF:loadLoggingConfig:Function]
  /**
   * @purpose Fetches current logging configuration from the backend.
   * @pre     Component is mounted and user has active session.
   * @post    loggingConfig variable is updated with backend data.
   * @returns {Promise<void>}
   * @relation CALLS -> adminService.getLoggingConfig
   */
  async function loadLoggingConfig() {
    console.log('[AdminSettingsPage][loadLoggingConfig][Entry]');
    loggingConfigLoading = true;
    try {
      const config = await adminService.getLoggingConfig();
      loggingConfig = {
        level: config.level || 'INFO',
        task_log_level: config.task_log_level || 'INFO',
        enable_belief_state: config.enable_belief_state ?? true
      };
      console.log('[AdminSettingsPage][loadLoggingConfig][Coherence:OK]');
    } catch (e) {
      console.error('[AdminSettingsPage][loadLoggingConfig][Coherence:Failed]', e);
    } finally {
      loggingConfigLoading = false;
    }
  }
  // [/DEF:loadLoggingConfig:Function]

  // [DEF:saveLoggingConfig:Function]
  /**
   * @purpose Saves logging configuration to the backend.
   * @pre     loggingConfig contains valid values.
   * @post    Configuration is saved and feedback is shown.
   * @returns {Promise<void>}
   * @relation CALLS -> adminService.updateLoggingConfig
   */
  async function saveLoggingConfig() {
    console.log('[AdminSettingsPage][saveLoggingConfig][Entry]');
    loggingConfigSaving = true;
    loggingConfigSaved = false;
    try {
      await adminService.updateLoggingConfig(loggingConfig);
      loggingConfigSaved = true;
      console.log('[AdminSettingsPage][saveLoggingConfig][Coherence:OK]');
      // Reset saved indicator after 2 seconds
      setTimeout(() => { loggingConfigSaved = false; }, 2000);
    } catch (e) {
      alert(
        ($t.admin?.settings?.save_logging_failed )
          .replace('{error}', e.message || ($t.common?.unknown )),
      );
      console.error('[AdminSettingsPage][saveLoggingConfig][Coherence:Failed]', e);
    } finally {
      loggingConfigSaving = false;
    }
  }
  // [/DEF:saveLoggingConfig:Function]

  onMount(() => {
    loadData();
    loadLoggingConfig();
  });
</script>

<ProtectedRoute requiredPermission="admin:settings">
  <!-- [SECTION: TEMPLATE] -->
  <div class="container mx-auto p-4">
    <div class="flex justify-between items-center mb-6">
      <h1 class="text-2xl font-bold">{$t.admin.settings.title}</h1>
      <button
        class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700 transition-colors"
        onclick={() => showCreateModal = true}
      >
        {$t.admin.settings.add_mapping}
      </button>
    </div>

    {#if loading}
      <div class="flex justify-center py-8">
        <p class="text-gray-500 animate-pulse">{$t.common.loading}</p>
      </div>
    {:else if error}
      <div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 rounded mb-4" role="alert">
        <p class="font-bold">{$t.common.error}</p>
        <p>{error}</p>
      </div>
    {:else}
      <div class="bg-white shadow rounded-lg overflow-hidden border border-gray-200">
        <table class="min-w-full divide-y divide-gray-200">
          <thead class="bg-gray-50">
            <tr>
              <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">{$t.admin.settings.ad_group}</th>
              <th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">{$t.admin.settings.local_role}</th>
            </tr>
          </thead>
          <tbody class="bg-white divide-y divide-gray-200">
            {#each mappings as mapping}
              <tr class="hover:bg-gray-50 transition-colors">
                <td class="px-6 py-4 whitespace-nowrap font-mono text-sm text-gray-600">{mapping.ad_group}</td>
                <td class="px-6 py-4 whitespace-nowrap">
                  <span class="px-2 py-1 bg-blue-100 text-blue-800 text-xs font-semibold rounded-full">
                    {roles.find(r => r.id === mapping.role_id)?.name || mapping.role_id}
                  </span>
                </td>
              </tr>
            {/each}
            {#if mappings.length === 0}
              <tr>
                <td colspan="2" class="px-6 py-12 text-center text-gray-500">
                  <div class="flex flex-col items-center">
                    <svg class="w-12 h-12 text-gray-300 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path>
                    </svg>
                    <p>{$t.admin.settings.no_mappings}</p>
                  </div>
                </td>
              </tr>
            {/if}
          </tbody>
        </table>
      </div>
    {/if}

    <!-- [SECTION: LOGGING_CONFIG_UI] -->
    <div class="mt-8 bg-white shadow rounded-lg border border-gray-200 p-6">
      <h2 class="text-xl font-bold mb-4 text-gray-800">{$t.settings?.logging }</h2>
      
      {#if loggingConfigLoading}
        <div class="flex justify-center py-4">
          <p class="text-gray-500 animate-pulse">{$t.admin?.settings?.loading_logging }</p>
        </div>
      {:else}
        <div class="space-y-4">
          <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <label for="admin-app-log-level" class="block text-sm font-medium text-gray-700 mb-1">{$t.admin?.settings?.app_log_level }</label>
              <select
                id="admin-app-log-level"
                bind:value={loggingConfig.level}
                class="w-full border border-gray-300 p-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
              >
                {#each LOG_LEVELS as level}
                  <option value={level}>{level}</option>
                {/each}
              </select>
              <p class="text-xs text-gray-500 mt-1">{$t.admin?.settings?.app_log_level_hint }</p>
            </div>
            
            <div>
              <label for="admin-task-log-level" class="block text-sm font-medium text-gray-700 mb-1">{$t.settings?.task_log_level }</label>
              <select
                id="admin-task-log-level"
                bind:value={loggingConfig.task_log_level}
                class="w-full border border-gray-300 p-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
              >
                {#each LOG_LEVELS as level}
                  <option value={level}>{level}</option>
                {/each}
              </select>
              <p class="text-xs text-gray-500 mt-1">{$t.admin?.settings?.task_log_level_hint }</p>
            </div>
          </div>
          
          <div class="flex items-center">
            <input
              type="checkbox"
              id="enable_belief_state"
              bind:checked={loggingConfig.enable_belief_state}
              class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded"
            />
            <label for="enable_belief_state" class="ml-2 block text-sm text-gray-700">
              {$t.settings?.enable_belief_state }
            </label>
          </div>
          <p class="text-xs text-gray-500 -mt-2">{$t.admin?.settings?.belief_state_hint }</p>
          
          <div class="flex items-center gap-3 pt-2">
            <button
              onclick={saveLoggingConfig}
              disabled={loggingConfigSaving}
              class="px-4 py-2 bg-blue-600 text-white rounded font-medium hover:bg-blue-700 disabled:bg-gray-400 disabled:cursor-not-allowed transition-colors"
            >
              {loggingConfigSaving ? ($t.settings?.saving ) : ($t.admin?.settings?.save_configuration )}
            </button>
            {#if loggingConfigSaved}
              <span class="text-green-600 text-sm font-medium">✓ {$t.admin?.settings?.saved }</span>
            {/if}
          </div>
        </div>
      {/if}
    </div>
    <!-- [/SECTION: LOGGING_CONFIG_UI] -->

    {#if showCreateModal}
      <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50">
        <div class="bg-white rounded-lg shadow-xl p-6 max-w-md w-full">
          <h2 class="text-xl font-bold mb-4 border-b pb-2">{$t.admin.settings.modal_title}</h2>
          <form onsubmit={(event) => {
            event.preventDefault();
            handleCreateMapping();
          }}>
            <div class="mb-4">
              <label for="admin-ad-group-dn" class="block text-sm font-medium text-gray-700 mb-1">{$t.admin.settings.ad_group_dn}</label>
              <input
                id="admin-ad-group-dn"
                type="text"
                bind:value={newMapping.ad_group}
                class="w-full border border-gray-300 p-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                placeholder={$t.admin?.settings?.ad_group_placeholder }
                required
              />
              <p class="text-xs text-gray-500 mt-1">{$t.admin.settings.ad_group_hint}</p>
            </div>
            <div class="mb-6">
              <label for="admin-local-role-select" class="block text-sm font-medium text-gray-700 mb-1">{$t.admin.settings.local_role_select}</label>
              <select
                id="admin-local-role-select"
                bind:value={newMapping.role_id}
                class="w-full border border-gray-300 p-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
                required
              >
                <option value="" disabled>{$t.admin.settings.select_role}</option>
                {#each roles as role}
                  <option value={role.id}>{role.name}</option>
                {/each}
              </select>
            </div>
            <div class="flex justify-end gap-3">
              <button
                type="button"
                class="px-4 py-2 text-gray-600 hover:text-gray-800 font-medium"
                onclick={() => showCreateModal = false}
              >
                {$t.common.cancel}
              </button>
              <button
                type="submit"
                class="px-6 py-2 bg-blue-600 text-white rounded font-bold hover:bg-blue-700 shadow-md"
              >
                {$t.common.save}
              </button>
            </div>
          </form>
        </div>
      </div>
    {/if}
  </div>
  <!-- [/SECTION: TEMPLATE] -->
</ProtectedRoute>


<!-- [/DEF:AdminSettingsPage:Component] -->
