<!-- #region ApiKeysTab [C:3] [TYPE Component] [SEMANTICS settings, api_keys, admin, crud] -->
<!-- @BRIEF API Key management tab — list, generate (one-time reveal), and revoke API keys. -->
<!-- @LAYER UI -->
<!-- @RELATION DEPENDS_ON -> [ApiModule] -->
<!-- @RELATION DEPENDS_ON -> [I18nModule] -->
<!-- @RELATION DEPENDS_ON -> [ToastsModule] -->
<!-- @UX_STATE Loading -> Skeleton rows, generate button disabled -->
<!-- @UX_STATE Loaded -> Keys table with revoke buttons, generate form collapsed -->
<!-- @UX_STATE Generating -> Spinner on generate button -->
<!-- @UX_STATE Revoking -> Confirm dialog visible -->
<!-- @UX_STATE Revealing -> Warning panel with raw key and copy button -->
<!-- @UX_FEEDBACK Toast on generate success/error, revoke success/error -->
<!-- @UX_RECOVERY Retry button on load error -->
<!-- @UX_REACTIVITY Props -> $props(), LocalState -> $state(keys, isLoading, error) -->
<script lang="ts">
  import { onMount } from 'svelte';
  import { t } from '$lib/i18n/index.svelte.js';
  import { api } from '$lib/api.js';
  import { addToast } from '$lib/toasts.svelte.js';

  let keys = $state([]);
  let environments = $state([]);
  let isLoading = $state(true);
  let error = $state(null);
  let showGenerateForm = $state(false);
  let isGenerating = $state(false);
  let revokingId = $state(null);
  let revealedKey = $state(null);

  // Generate form state
  let formName = $state('');
  let formEnvironmentId = $state('');
  let formPermissions = $state([]);
  let formExpiresAt = $state('');

  const AVAILABLE_PERMISSIONS = [
    'maintenance:start',
    'maintenance:end',
    'maintenance:end_all',
  ];

  const PERMISSION_LABELS = {
    'maintenance:start': 'maintenance:start',
    'maintenance:end': 'maintenance:end',
    'maintenance:end_all': 'maintenance:end_all',
  };

  onMount(() => {
    loadKeys();
    loadEnvironments();
  });

  async function loadKeys() {
    isLoading = true;
    error = null;
    try {
      keys = await api.listApiKeys();
    } catch (err) {
      error = err.message || 'Failed to load API keys';
      console.error('[ApiKeysTab] Failed to load keys:', err);
    } finally {
      isLoading = false;
    }
  }

  async function loadEnvironments() {
    try {
      environments = await api.getEnvironmentsList();
    } catch (err) {
      // Non-critical — environments are optional
      console.error('[ApiKeysTab] Failed to load environments:', err);
    }
  }

  function togglePermission(perm) {
    if (formPermissions.includes(perm)) {
      formPermissions = formPermissions.filter(p => p !== perm);
    } else {
      formPermissions = [...formPermissions, perm];
    }
  }

  function resetForm() {
    formName = '';
    formEnvironmentId = '';
    formPermissions = [];
    formExpiresAt = '';
    showGenerateForm = false;
  }

  async function handleGenerate() {
    if (!formName.trim()) {
      addToast('Name is required', 'error');
      return;
    }
    if (formPermissions.length === 0) {
      addToast('At least one permission is required', 'error');
      return;
    }

    isGenerating = true;
    try {
      const payload = {
        name: formName.trim(),
        permissions: formPermissions,
        environment_id: formEnvironmentId || null,
        expires_at: formExpiresAt ? new Date(formExpiresAt).toISOString() : null,
      };
      const result = await api.createApiKey(payload);
      revealedKey = result;
      keys = [{
        id: result.id,
        name: result.name,
        prefix: result.prefix,
        environment_id: result.environment_id,
        permissions: result.permissions,
        active: result.active,
        created_at: result.created_at,
        expires_at: result.expires_at,
        last_used_at: null,
      }, ...keys];
      resetForm();
      addToast('API key generated successfully', 'success');
    } catch (err) {
      addToast(err.message || 'Failed to generate API key', 'error');
    } finally {
      isGenerating = false;
    }
  }

  async function handleRevoke(keyId) {
    revokingId = keyId;
    try {
      await api.revokeApiKey(keyId);
      keys = keys.map(k => k.id === keyId ? { ...k, active: false } : k);
      addToast('API key revoked', 'success');
    } catch (err) {
      addToast(err.message || 'Failed to revoke API key', 'error');
    } finally {
      revokingId = null;
    }
  }

  function confirmRevoke(key) {
    if (confirm('All tools using this key will get 401. Are you sure?')) {
      handleRevoke(key.id);
    }
  }

  async function copyToClipboard(text) {
    try {
      await navigator.clipboard.writeText(text);
      addToast('Copied!', 'success');
    } catch {
      addToast('Failed to copy', 'error');
    }
  }

  function dismissReveal() {
    revealedKey = null;
  }

  function formatDate(dateStr) {
    if (!dateStr) return '—';
    return new Date(dateStr).toLocaleDateString();
  }

  function getStatusDot(active) {
    return active
      ? 'bg-green-500'
      : 'bg-red-500';
  }
</script>

<div class="space-y-6">
  <!-- Header -->
  <div class="flex items-center justify-between">
    <div>
      <h2 class="text-xl font-bold text-gray-900">{$t.api_keys?.title || 'API Keys'}</h2>
      <p class="text-sm text-gray-500 mt-1">
        {$t.api_keys?.description || 'Manage API keys for service-to-service authentication.'}
      </p>
    </div>
    <button
      class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 disabled:opacity-50 text-sm"
      onclick={() => { showGenerateForm = !showGenerateForm; }}
      disabled={isLoading}
    >
      {$t.api_keys?.generate?.title || 'Generate New API Key'}
    </button>
  </div>

  <!-- Generate Form -->
  {#if showGenerateForm}
    <div class="bg-gray-50 border border-gray-200 rounded-lg p-4 space-y-4">
      <h3 class="font-semibold text-gray-900">{$t.api_keys?.generate?.title || 'Generate New API Key'}</h3>

      <!-- Name -->
      <div>
        <label class="block text-sm font-medium text-gray-700 mb-1">
          {$t.api_keys?.generate?.name || 'Key Name'} *
        </label>
        <input
          type="text"
          bind:value={formName}
          placeholder={$t.api_keys?.generate?.name_placeholder || 'e.g. CI/CD Pipeline'}
          class="block w-full max-w-md px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
        />
      </div>

      <!-- Environment -->
      <div>
        <label class="block text-sm font-medium text-gray-700 mb-1">
          {$t.api_keys?.generate?.environment || 'Environment'}
        </label>
        <select
          bind:value={formEnvironmentId}
          class="block w-full max-w-md px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
        >
          <option value="">{$t.api_keys?.generate?.environment_all || 'All Environments'}</option>
          {#each environments as env (env.id)}
            <option value={env.id}>{env.name}</option>
          {/each}
        </select>
      </div>

      <!-- Permissions -->
      <div>
        <label class="block text-sm font-medium text-gray-700 mb-1">
          {$t.api_keys?.generate?.permissions || 'Permissions'} *
        </label>
        <div class="space-y-1">
          {#each AVAILABLE_PERMISSIONS as perm}
            <label class="flex items-center gap-2 text-sm">
              <input
                type="checkbox"
                checked={formPermissions.includes(perm)}
                onchange={() => togglePermission(perm)}
                class="rounded border-gray-300 text-blue-600 focus:ring-blue-500"
              />
              <span class="font-mono text-xs">{perm}</span>
            </label>
          {/each}
        </div>
      </div>

      <!-- Expires At -->
      <div>
        <label class="block text-sm font-medium text-gray-700 mb-1">
          {$t.api_keys?.generate?.expires_at || 'Expires At (optional)'}
        </label>
        <input
          type="date"
          bind:value={formExpiresAt}
          class="block w-full max-w-md px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500"
        />
      </div>

      <!-- Buttons -->
      <div class="flex gap-2 pt-2">
        <button
          class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 disabled:opacity-50 text-sm flex items-center gap-2"
          onclick={handleGenerate}
          disabled={isGenerating}
        >
          {#if isGenerating}
            <svg class="animate-spin h-4 w-4" viewBox="0 0 24 24">
              <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none"/>
              <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/>
            </svg>
          {/if}
          {$t.api_keys?.generate?.generate || 'Generate Key'}
        </button>
        <button
          class="border border-gray-300 text-gray-700 px-4 py-2 rounded-md hover:bg-gray-50 text-sm"
          onclick={resetForm}
        >
          {$t.api_keys?.generate?.cancel || 'Cancel'}
        </button>
      </div>
    </div>
  {/if}

  <!-- Revealed Key Panel -->
  {#if revealedKey}
    <div class="bg-amber-50 border border-amber-400 rounded-lg p-4 space-y-3">
      <div class="flex items-start gap-2">
        <span class="text-amber-600 text-lg" aria-hidden="true">⚠️</span>
        <div>
          <p class="text-sm font-medium text-amber-800">
            {$t.api_keys?.reveal?.warning || 'This is the ONLY time the key will be shown. Copy it now.'}
          </p>
          <pre class="mt-2 p-3 bg-amber-100 rounded text-sm font-mono break-all select-all">{revealedKey.raw_key}</pre>
        </div>
      </div>
      <div class="flex gap-2">
        <button
          class="bg-amber-600 text-white px-4 py-2 rounded-md hover:bg-amber-700 text-sm"
          onclick={() => copyToClipboard(revealedKey.raw_key)}
        >
          {$t.api_keys?.reveal?.copy || 'Copy to Clipboard'}
        </button>
        <button
          class="border border-amber-300 text-amber-700 px-4 py-2 rounded-md hover:bg-amber-100 text-sm"
          onclick={dismissReveal}
        >
          {$t.api_keys?.reveal?.dismiss || 'Dismiss'}
        </button>
      </div>
    </div>
  {/if}

  <!-- Error State -->
  {#if error}
    <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded flex items-center justify-between">
      <span class="text-sm">{error}</span>
      <button
        class="px-3 py-1 bg-red-600 text-white rounded text-sm hover:bg-red-700"
        onclick={loadKeys}
      >
        Retry
      </button>
    </div>
  {:else if isLoading}
    <!-- Loading State -->
    <div class="space-y-2">
      {#each [1, 2, 3] as _}
        <div class="h-12 animate-pulse bg-gray-200 rounded"></div>
      {/each}
    </div>
  {:else if keys.length === 0}
    <!-- Empty State -->
    <div class="text-center py-8 text-gray-500 text-sm border-2 border-dashed border-gray-200 rounded-lg">
      {$t.api_keys?.empty || 'No API keys configured.'}
    </div>
  {:else}
    <!-- Keys Table -->
    <div class="overflow-x-auto border border-gray-200 rounded-lg">
      <table class="min-w-full divide-y divide-gray-200">
        <thead class="bg-gray-50">
          <tr>
            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
              {$t.api_keys?.table?.name || 'Name'}
            </th>
            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
              {$t.api_keys?.table?.prefix || 'Prefix'}
            </th>
            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
              {$t.api_keys?.table?.environment || 'Environment'}
            </th>
            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
              {$t.api_keys?.table?.permissions || 'Permissions'}
            </th>
            <th class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
              {$t.api_keys?.table?.status || 'Status'}
            </th>
            <th class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">
              {$t.api_keys?.table?.actions || 'Actions'}
            </th>
          </tr>
        </thead>
        <tbody class="bg-white divide-y divide-gray-200">
          {#each keys as key (key.id)}
            <tr class="hover:bg-gray-50">
              <td class="px-4 py-3 text-sm font-medium text-gray-900">{key.name}</td>
              <td class="px-4 py-3 text-sm font-mono text-gray-500">{key.prefix}...</td>
              <td class="px-4 py-3 text-sm text-gray-500">{key.environment_id || '—'}</td>
              <td class="px-4 py-3 text-sm text-gray-500">
                <div class="flex flex-wrap gap-1">
                  {#each key.permissions as perm}
                    <span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-100 text-blue-800">{perm}</span>
                  {/each}
                </div>
              </td>
              <td class="px-4 py-3 text-sm">
                <span class="flex items-center gap-1.5">
                  <span class="inline-block w-2.5 h-2.5 rounded-full {getStatusDot(key.active)}" aria-hidden="true"></span>
                  {key.active
                    ? ($t.api_keys?.status?.active || 'Active')
                    : ($t.api_keys?.status?.revoked || 'Revoked')}
                </span>
              </td>
              <td class="px-4 py-3 text-sm text-right">
                {#if key.active}
                  <button
                    class="text-red-600 hover:text-red-800 disabled:opacity-50 text-xs font-medium"
                    onclick={() => confirmRevoke(key)}
                    disabled={revokingId === key.id}
                  >
                    {#if revokingId === key.id}
                      <span class="inline-block animate-pulse">Revoking...</span>
                    {:else}
                      ✕ {$t.api_keys?.revoke?.revoke || 'Revoke'}
                    {/if}
                  </button>
                {:else}
                  <span class="text-gray-400 text-xs">—</span>
                {/if}
              </td>
            </tr>
          {/each}
        </tbody>
      </table>
    </div>
  {/if}
</div>
<!-- #endregion ApiKeysTab -->
