{% extends "base.html" %}
{% block title %}{{ _("integrations.page_title") }} – DocuElevate{% endblock %}

{% block content %}
<div
  class="container mx-auto px-4 py-8"
  x-data="integrationsDashboard()"
  x-init="init()"
>

  <!-- ── Header ───────────────────────────────────────────────────────────── -->
  <div class="mb-6 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3">
    <div>
      <h1 class="text-3xl font-bold text-gray-900 dark:text-white flex items-center gap-2">
        <i class="fas fa-plug text-indigo-500" aria-hidden="true"></i>
        {{ _("integrations.page_title") }}
      </h1>
      <p class="text-gray-500 dark:text-gray-400 text-sm mt-1">
        {{ _("integrations.subtitle") }}
      </p>
    </div>
    <button
      type="button"
      @click="openCreateModal()"
      :disabled="!canAddAny"
      class="inline-flex items-center px-4 py-2 bg-indigo-600 hover:bg-indigo-700 disabled:bg-gray-300 disabled:cursor-not-allowed text-white text-sm font-medium rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
      style="min-height:44px;"
      :aria-disabled="!canAddAny"
    >
      <i class="fas fa-plus mr-2" aria-hidden="true"></i> {{ _("integrations.add_button") }}
    </button>
  </div>

  <!-- ── Quota indicators ─────────────────────────────────────────────────── -->
  <div class="mb-6 grid grid-cols-1 sm:grid-cols-2 gap-4">
    <!-- Sources quota -->
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow px-5 py-4">
      <div class="flex items-center gap-3">
        <div class="h-10 w-10 rounded-full bg-blue-100 dark:bg-blue-900 flex items-center justify-center flex-shrink-0">
          <i class="fas fa-inbox text-blue-600 dark:text-blue-400" aria-hidden="true"></i>
        </div>
        <div class="flex-1 min-w-0">
          <p class="text-sm font-medium text-gray-700 dark:text-gray-200">
            {{ _("integrations.sources_quota_label") }}
            <strong x-text="quota.src_count"></strong>
            <template x-if="quota.max_sources !== null && quota.max_sources > 0">
              <span> / <strong x-text="quota.max_sources"></strong></span>
            </template>
            <template x-if="quota.max_sources === null">
              <span class="text-gray-400"> {{ _("integrations.quota_unlimited") }}</span>
            </template>
            <template x-if="quota.max_sources === 0">
              <span class="text-gray-400 ml-1">{{ _("integrations.quota_not_available") }}</span>
            </template>
          </p>
          <p class="text-xs text-gray-400 dark:text-gray-500 mt-0.5">
            {{ _("integrations.plan_label") }} <span x-text="quota.tier_name"></span>
          </p>
        </div>
        <!-- Mini usage bar -->
        <template x-if="quota.max_sources !== null && quota.max_sources > 0">
          <div class="w-24 flex-shrink-0">
            <div class="bg-gray-200 dark:bg-gray-600 rounded-full h-2 overflow-hidden">
              <div
                class="h-2 rounded-full transition-all"
                :class="quota.src_count >= quota.max_sources ? 'bg-red-500' : 'bg-blue-500'"
                :style="`width:${Math.min(100, quota.src_count / quota.max_sources * 100)}%`"
                role="progressbar"
                :aria-valuenow="quota.src_count"
                :aria-valuemin="0"
                :aria-valuemax="quota.max_sources"
                :aria-label="`${quota.src_count} of ${quota.max_sources} source integrations used`"
              ></div>
            </div>
          </div>
        </template>
      </div>
      <template x-if="quota.max_sources !== null && quota.src_count >= quota.max_sources && quota.max_sources >= 0">
        <a href="/subscription" class="inline-flex items-center text-xs text-indigo-600 hover:text-indigo-800 mt-2">
          <i class="fas fa-arrow-up mr-1" aria-hidden="true"></i> {{ _("integrations.upgrade_plan") }}
        </a>
      </template>
    </div>

    <!-- Destinations quota -->
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow px-5 py-4">
      <div class="flex items-center gap-3">
        <div class="h-10 w-10 rounded-full bg-green-100 dark:bg-green-900 flex items-center justify-center flex-shrink-0">
          <i class="fas fa-hdd text-green-600 dark:text-green-400" aria-hidden="true"></i>
        </div>
        <div class="flex-1 min-w-0">
          <p class="text-sm font-medium text-gray-700 dark:text-gray-200">
            {{ _("integrations.destinations_quota_label") }}
            <strong x-text="quota.dest_count"></strong>
            <template x-if="quota.max_destinations !== null">
              <span> / <strong x-text="quota.max_destinations"></strong></span>
            </template>
            <template x-if="quota.max_destinations === null">
              <span class="text-gray-400"> {{ _("integrations.quota_unlimited") }}</span>
            </template>
          </p>
          <p class="text-xs text-gray-400 dark:text-gray-500 mt-0.5">
            {{ _("integrations.plan_label") }} <span x-text="quota.tier_name"></span>
          </p>
        </div>
        <!-- Mini usage bar -->
        <template x-if="quota.max_destinations !== null && quota.max_destinations > 0">
          <div class="w-24 flex-shrink-0">
            <div class="bg-gray-200 dark:bg-gray-600 rounded-full h-2 overflow-hidden">
              <div
                class="h-2 rounded-full transition-all"
                :class="quota.dest_count >= quota.max_destinations ? 'bg-red-500' : 'bg-green-500'"
                :style="`width:${Math.min(100, quota.dest_count / quota.max_destinations * 100)}%`"
                role="progressbar"
                :aria-valuenow="quota.dest_count"
                :aria-valuemin="0"
                :aria-valuemax="quota.max_destinations"
                :aria-label="`${quota.dest_count} of ${quota.max_destinations} destination integrations used`"
              ></div>
            </div>
          </div>
        </template>
      </div>
      <template x-if="quota.max_destinations !== null && quota.dest_count >= quota.max_destinations">
        <a href="/subscription" class="inline-flex items-center text-xs text-indigo-600 hover:text-indigo-800 mt-2">
          <i class="fas fa-arrow-up mr-1" aria-hidden="true"></i> {{ _("integrations.upgrade_plan") }}
        </a>
      </template>
    </div>
  </div>

  <!-- ── Alert banner ─────────────────────────────────────────────────────── -->
  <div aria-live="polite" aria-atomic="true">
    <div x-show="alert.show && alert.type !== 'error'" x-transition class="mb-4" role="status">
      <div class="bg-green-50 border-green-400 text-green-800 border-l-4 p-4 rounded dark:bg-opacity-10">
        <p class="font-semibold" x-text="alert.title"></p>
        <p class="text-sm" x-text="alert.message"></p>
      </div>
    </div>
  </div>
  <div aria-live="assertive" aria-atomic="true">
    <div x-show="alert.show && alert.type === 'error'" x-transition class="mb-4" role="alert">
      <div class="bg-red-50 border-red-400 text-red-800 border-l-4 p-4 rounded dark:bg-opacity-10">
        <p class="font-semibold" x-text="alert.title"></p>
        <p class="text-sm" x-text="alert.message"></p>
      </div>
    </div>
  </div>

  <!-- ── Loading ──────────────────────────────────────────────────────────── -->
  <template x-if="loading">
    <div class="text-center py-12 text-gray-400">
      <i class="fas fa-spinner fa-spin text-3xl mb-3" aria-hidden="true"></i>
      <p>{{ _("integrations.loading") }}</p>
    </div>
  </template>

  <!-- ── Empty state ──────────────────────────────────────────────────────── -->
  <template x-if="!loading && integrations.length === 0">
    <div class="text-center py-16 bg-white dark:bg-gray-800 rounded-lg shadow">
      <i class="fas fa-plug text-5xl text-gray-300 mb-4" aria-hidden="true"></i>
      <h2 class="text-xl font-semibold text-gray-700 dark:text-gray-300 mb-2">{{ _("integrations.empty_state") }}</h2>
      <p class="text-gray-500 dark:text-gray-400 mb-6 max-w-md mx-auto">
        {{ _("integrations.no_integrations_body") }}
      </p>
      <button
        type="button"
        @click="openCreateModal()"
        :disabled="!canAddAny"
        class="inline-flex items-center px-5 py-2.5 bg-indigo-600 hover:bg-indigo-700 disabled:bg-gray-300 disabled:cursor-not-allowed text-white text-sm font-medium rounded-md"
        style="min-height:44px;"
      >
        <i class="fas fa-plus mr-2" aria-hidden="true"></i> {{ _("integrations.add_first_button") }}
      </button>
    </div>
  </template>

  <!-- ── Section: Sources ─────────────────────────────────────────────────── -->
  <template x-if="!loading && sources.length > 0">
    <section class="mb-8">
      <h2 class="text-lg font-semibold text-gray-800 dark:text-gray-200 mb-3 flex items-center gap-2">
        <i class="fas fa-inbox text-blue-500" aria-hidden="true"></i> {{ _("integrations.sources_section") }}
      </h2>
      <div class="space-y-3">
        <template x-for="intg in sources" :key="intg.id">
          <div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden border border-gray-100 dark:border-gray-700">
            <div class="p-5 flex flex-col sm:flex-row sm:items-center gap-4">
              <div class="flex items-start gap-3 flex-1 min-w-0">
                <div class="mt-0.5 flex-shrink-0">
                  <i class="fas text-lg" :class="typeIcon(intg.integration_type)" aria-hidden="true"></i>
                </div>
                <div class="min-w-0 flex-1">
                  <h3 class="text-base font-semibold text-gray-900 dark:text-white truncate" x-text="intg.name"></h3>
                  <p class="text-sm text-gray-500 dark:text-gray-400">
                    <span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-blue-50 text-blue-700 dark:bg-blue-900 dark:text-blue-300" x-text="intg.integration_type"></span>
                    <span
                      class="ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium"
                      :class="intg.is_active ? 'bg-green-50 text-green-700 dark:bg-green-900 dark:text-green-300' : 'bg-gray-100 text-gray-500 dark:bg-gray-700 dark:text-gray-400'"
                      x-text="intg.is_active ? '{{ _('common.active') }}' : '{{ _('integrations.paused') }}'"
                    ></span>
                  </p>
                  <template x-if="intg.last_error">
                    <p class="mt-1.5 text-xs text-red-600 bg-red-50 rounded px-2 py-1 break-words" x-text="intg.last_error"></p>
                  </template>
                </div>
              </div>
              <!-- Actions -->
              <div class="flex items-center gap-2 shrink-0">
                <template x-if="isOAuthType(intg)">
                  <a
                    :href="oauthLink(intg) + '?integration_id=' + intg.id"
                    :class="intg.has_credentials
                      ? 'inline-flex items-center px-3 py-1.5 text-xs font-medium rounded border border-blue-300 text-blue-700 bg-blue-50 hover:bg-blue-100 focus:outline-none focus:ring-2 focus:ring-blue-500'
                      : 'inline-flex items-center px-3 py-1.5 text-xs font-medium rounded border border-yellow-400 text-yellow-700 bg-yellow-50 hover:bg-yellow-100 focus:outline-none focus:ring-2 focus:ring-yellow-500'"
                    style="min-height:36px;"
                    :aria-label="`${intg.has_credentials ? 'Re-authorize' : 'Authorize'} ${intg.name}`"
                  >
                    <i class="fas fa-key mr-1" aria-hidden="true"></i>
                    <span x-text="intg.has_credentials ? '{{ _('integrations.authorize_reauth') }}' : '{{ _('integrations.authorize_btn') }}'"></span>
                  </a>
                </template>
                <button
                  type="button"
                  @click="testSavedIntegration(intg)"
                  :disabled="testingId === intg.id"
                  class="inline-flex items-center px-3 py-1.5 text-xs font-medium rounded border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50"
                  style="min-height:36px;"
                  :aria-label="`Test connection for ${intg.name}`"
                >
                  <template x-if="testingId === intg.id">
                    <i class="fas fa-spinner fa-spin mr-1" aria-hidden="true"></i>
                  </template>
                  <template x-if="testingId !== intg.id">
                    <i class="fas fa-plug mr-1" aria-hidden="true"></i>
                  </template>
                  {{ _("common.test") }}
                </button>
                <button
                  type="button"
                  @click="openEditModal(intg)"
                  class="inline-flex items-center px-3 py-1.5 text-xs font-medium rounded border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500"
                  style="min-height:36px;"
                  :aria-label="`Edit ${intg.name}`"
                >
                  <i class="fas fa-edit mr-1" aria-hidden="true"></i>{{ _("common.edit") }}
                </button>
                <button
                  type="button"
                  @click="confirmDelete(intg)"
                  class="inline-flex items-center px-3 py-1.5 text-xs font-medium rounded border border-red-200 text-red-600 hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-red-500"
                  style="min-height:36px;"
                  :aria-label="`Delete ${intg.name}`"
                >
                  <i class="fas fa-trash-alt mr-1" aria-hidden="true"></i>{{ _("common.delete") }}
                </button>
              </div>
            </div>
          </div>
        </template>
      </div>
    </section>
  </template>

  <!-- ── Section: Destinations ────────────────────────────────────────────── -->
  <template x-if="!loading && destinations.length > 0">
    <section class="mb-8">
      <h2 class="text-lg font-semibold text-gray-800 dark:text-gray-200 mb-3 flex items-center gap-2">
        <i class="fas fa-hdd text-green-500" aria-hidden="true"></i> {{ _("integrations.destinations_section") }}
      </h2>
      <div class="space-y-3">
        <template x-for="intg in destinations" :key="intg.id">
          <div class="bg-white dark:bg-gray-800 shadow rounded-lg overflow-hidden border border-gray-100 dark:border-gray-700">
            <div class="p-5 flex flex-col sm:flex-row sm:items-center gap-4">
              <div class="flex items-start gap-3 flex-1 min-w-0">
                <div class="mt-0.5 flex-shrink-0">
                  <i class="fas text-lg" :class="typeIcon(intg.integration_type)" aria-hidden="true"></i>
                </div>
                <div class="min-w-0 flex-1">
                  <h3 class="text-base font-semibold text-gray-900 dark:text-white truncate" x-text="intg.name"></h3>
                  <p class="text-sm text-gray-500 dark:text-gray-400">
                    <span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-green-50 text-green-700 dark:bg-green-900 dark:text-green-300" x-text="intg.integration_type"></span>
                    <span
                      class="ml-2 inline-flex items-center px-2 py-0.5 rounded text-xs font-medium"
                      :class="intg.is_active ? 'bg-green-50 text-green-700 dark:bg-green-900 dark:text-green-300' : 'bg-gray-100 text-gray-500 dark:bg-gray-700 dark:text-gray-400'"
                      x-text="intg.is_active ? '{{ _('common.active') }}' : '{{ _('integrations.paused') }}'"
                    ></span>
                  </p>
                  <template x-if="intg.last_error">
                    <p class="mt-1.5 text-xs text-red-600 bg-red-50 rounded px-2 py-1 break-words" x-text="intg.last_error"></p>
                  </template>
                </div>
              </div>
              <!-- Actions -->
              <div class="flex items-center gap-2 shrink-0">
                <template x-if="isOAuthType(intg)">
                  <a
                    :href="oauthLink(intg) + '?integration_id=' + intg.id"
                    :class="intg.has_credentials
                      ? 'inline-flex items-center px-3 py-1.5 text-xs font-medium rounded border border-blue-300 text-blue-700 bg-blue-50 hover:bg-blue-100 focus:outline-none focus:ring-2 focus:ring-blue-500'
                      : 'inline-flex items-center px-3 py-1.5 text-xs font-medium rounded border border-yellow-400 text-yellow-700 bg-yellow-50 hover:bg-yellow-100 focus:outline-none focus:ring-2 focus:ring-yellow-500'"
                    style="min-height:36px;"
                    :aria-label="`${intg.has_credentials ? 'Re-authorize' : 'Authorize'} ${intg.name}`"
                  >
                    <i class="fas fa-key mr-1" aria-hidden="true"></i>
                    <span x-text="intg.has_credentials ? '{{ _('integrations.authorize_reauth') }}' : '{{ _('integrations.authorize_btn') }}'"></span>
                  </a>
                </template>
                <button
                  type="button"
                  @click="testSavedIntegration(intg)"
                  :disabled="testingId === intg.id"
                  class="inline-flex items-center px-3 py-1.5 text-xs font-medium rounded border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50"
                  style="min-height:36px;"
                  :aria-label="`Test connection for ${intg.name}`"
                >
                  <template x-if="testingId === intg.id">
                    <i class="fas fa-spinner fa-spin mr-1" aria-hidden="true"></i>
                  </template>
                  <template x-if="testingId !== intg.id">
                    <i class="fas fa-plug mr-1" aria-hidden="true"></i>
                  </template>
                  {{ _("common.test") }}
                </button>
                <button
                  type="button"
                  @click="openEditModal(intg)"
                  class="inline-flex items-center px-3 py-1.5 text-xs font-medium rounded border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500"
                  style="min-height:36px;"
                  :aria-label="`Edit ${intg.name}`"
                >
                  <i class="fas fa-edit mr-1" aria-hidden="true"></i>{{ _("common.edit") }}
                </button>
                <button
                  type="button"
                  @click="confirmDelete(intg)"
                  class="inline-flex items-center px-3 py-1.5 text-xs font-medium rounded border border-red-200 text-red-600 hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-red-500"
                  style="min-height:36px;"
                  :aria-label="`Delete ${intg.name}`"
                >
                  <i class="fas fa-trash-alt mr-1" aria-hidden="true"></i>{{ _("common.delete") }}
                </button>
              </div>
            </div>
          </div>
        </template>
      </div>
    </section>
  </template>

  <!-- ── Create / Edit modal ──────────────────────────────────────────────── -->
  <div
    x-show="modalOpen"
    x-transition:enter="ease-out duration-200"
    x-transition:enter-start="opacity-0"
    x-transition:enter-end="opacity-100"
    x-transition:leave="ease-in duration-150"
    x-transition:leave-start="opacity-100"
    x-transition:leave-end="opacity-0"
    class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 px-4"
    role="dialog"
    aria-modal="true"
    :aria-labelledby="editingIntegration ? 'modal-title-edit' : 'modal-title-create'"
    @keydown.escape.window="closeModal()"
    style="display:none;"
  >
    <div
      class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-lg overflow-y-auto max-h-[90vh]"
      @click.stop
    >
      <div class="px-6 pt-6 pb-2 flex items-center justify-between">
        <h2
          :id="editingIntegration ? 'modal-title-edit' : 'modal-title-create'"
          class="text-lg font-semibold text-gray-900 dark:text-white"
          x-text="editingIntegration ? '{{ _('integrations.modal_title_edit') }}' : '{{ _('integrations.modal_title_add') }}'"
        ></h2>
        <button
          type="button"
          @click="closeModal()"
          class="text-gray-400 hover:text-gray-600 dark:hover:text-gray-200 focus:outline-none focus:ring-2 focus:ring-indigo-500 rounded"
          aria-label="{{ _('integrations.modal_close') }}"
        >
          <i class="fas fa-times text-xl" aria-hidden="true"></i>
        </button>
      </div>

      <form @submit.prevent="saveIntegration()" class="px-6 pb-6 pt-4 space-y-4">

        <!-- Direction -->
        <div>
          <label for="intg-direction" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
            {{ _("integrations.direction_label") }} <span class="text-red-500" aria-hidden="true">*</span>
          </label>
          <select
            id="intg-direction"
            x-model="form.direction"
            required
            :disabled="!!editingIntegration"
            class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm"
            aria-required="true"
            @change="onDirectionChange()"
          >
            <option value="">{{ _("integrations.direction_placeholder") }}</option>
            <option value="SOURCE">{{ _("integrations.direction_source") }}</option>
            <option value="DESTINATION">{{ _("integrations.direction_destination") }}</option>
          </select>
        </div>

        <!-- Integration type -->
        <div>
          <label for="intg-type" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
            {{ _("integrations.type_label") }} <span class="text-red-500" aria-hidden="true">*</span>
          </label>
          <select
            id="intg-type"
            x-model="form.integration_type"
            required
            :disabled="!!editingIntegration"
            class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm"
            aria-required="true"
            @change="onTypeChange()"
          >
            <option value="">{{ _("integrations.type_placeholder") }}</option>
            <template x-for="t in availableTypes" :key="t">
              <option :value="t" x-text="typeLabel(t)"></option>
            </template>
          </select>
        </div>

        <!-- Name -->
        <div>
          <label for="intg-name" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">
            {{ _("integrations.name_label") }} <span class="text-red-500" aria-hidden="true">*</span>
          </label>
          <input
            id="intg-name"
            type="text"
            x-model="form.name"
            placeholder="{{ _('integrations.name_placeholder') }}"
            required
            maxlength="255"
            class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm"
            aria-required="true"
          />
        </div>

        <!-- ── Dynamic config fields per integration type ─────────────── -->

        <!-- IMAP fields -->
        <template x-if="form.integration_type === 'IMAP'">
          <div class="space-y-3 border-t border-gray-200 dark:border-gray-700 pt-3">
            <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider">{{ _("integrations.imap_settings") }}</p>
            <div class="grid grid-cols-3 gap-3">
              <div class="col-span-2">
                <label for="imap-host" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.host_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                <input id="imap-host" type="text" x-model="form.config.host" placeholder="imap.example.com" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
              </div>
              <div>
                <label for="imap-port" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.port_label") }}</label>
                <input id="imap-port" type="number" x-model.number="form.config.port" min="1" max="65535" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
              </div>
            </div>
            <div>
              <label for="imap-username" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.username_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="imap-username" type="text" x-model="form.config.username" placeholder="user@example.com" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
            </div>
            <div>
              <label for="imap-password" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.password_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="imap-password" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.password" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <div class="flex flex-wrap items-center gap-4">
              <label class="inline-flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer">
                <input type="checkbox" x-model="form.config.use_ssl" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
                {{ _("integrations.use_ssl") }}
              </label>
              <label class="inline-flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer">
                <input type="checkbox" x-model="form.config.delete_after_process" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
                {{ _("integrations.delete_emails_label") }}
              </label>
              <label class="inline-flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer">
                <input type="checkbox" x-model="form.config.gmail_apply_labels" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
                {{ _("integrations.gmail_labels") }}
              </label>
              <label class="inline-flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer">
                <input type="checkbox" x-model="showPassword" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
                {{ _("integrations.show_password") }}
              </label>
            </div>
            <p class="text-xs text-gray-500 dark:text-gray-400">
              <i class="fas fa-info-circle mr-1" aria-hidden="true"></i>
              {{ _("integrations.gmail_hint") }}
            </p>
          </div>
        </template>

        <!-- S3 fields -->
        <template x-if="form.integration_type === 'S3'">
          <div class="space-y-3 border-t border-gray-200 dark:border-gray-700 pt-3">
            <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider">{{ _("integrations.s3_settings") }}</p>
            <div>
              <label for="s3-bucket" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.bucket_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="s3-bucket" type="text" x-model="form.config.bucket" placeholder="my-bucket" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
            </div>
            <div class="grid grid-cols-2 gap-3">
              <div>
                <label for="s3-region" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.region_label") }}</label>
                <input id="s3-region" type="text" x-model="form.config.region" placeholder="us-east-1" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
              </div>
              <div>
                <label for="s3-prefix" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.folder_prefix_label") }}</label>
                <input id="s3-prefix" type="text" x-model="form.config.folder_prefix" placeholder="documents/" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
              </div>
            </div>
            <div>
              <label for="s3-endpoint" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.endpoint_label") }} <span class="text-gray-400">{{ _("integrations.endpoint_optional") }}</span></label>
              <input id="s3-endpoint" type="url" x-model="form.config.endpoint_url" placeholder="https://s3.example.com" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <div>
              <label for="s3-key" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.access_key_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="s3-key" type="text" x-model="form.credentials.access_key_id" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <div>
              <label for="s3-secret" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.secret_key_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="s3-secret" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.secret_access_key" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <label class="inline-flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer">
              <input type="checkbox" x-model="showPassword" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
              {{ _("integrations.show_secrets") }}
            </label>
          </div>
        </template>

        <!-- WebDAV / Nextcloud fields -->
        <template x-if="form.integration_type === 'WEBDAV' || form.integration_type === 'NEXTCLOUD'">
          <div class="space-y-3 border-t border-gray-200 dark:border-gray-700 pt-3">
            <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider" x-text="form.integration_type === 'NEXTCLOUD' ? 'Nextcloud Settings' : 'WebDAV Settings'"></p>
            <div>
              <label for="webdav-url" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.webdav_url_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="webdav-url" type="url" x-model="form.config.url" placeholder="https://cloud.example.com/remote.php/dav/files/user/" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
            </div>
            <div>
              <label for="webdav-folder" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.folder_path_label") }}</label>
              <input id="webdav-folder" type="text" x-model="form.config.folder" placeholder="/Documents" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <div>
              <label for="webdav-user" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.username_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="webdav-user" type="text" x-model="form.credentials.username" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <div>
              <label for="webdav-pass" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.password_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="webdav-pass" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.password" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <label class="inline-flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer">
              <input type="checkbox" x-model="showPassword" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
              {{ _("integrations.show_password") }}
            </label>
          </div>
        </template>

        <!-- FTP / SFTP fields -->
        <template x-if="form.integration_type === 'FTP' || form.integration_type === 'SFTP'">
          <div class="space-y-3 border-t border-gray-200 dark:border-gray-700 pt-3">
            <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider" x-text="form.integration_type + ' Settings'"></p>
            <div class="grid grid-cols-3 gap-3">
              <div class="col-span-2">
                <label for="ftp-host" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.host_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                <input id="ftp-host" type="text" x-model="form.config.host" placeholder="ftp.example.com" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
              </div>
              <div>
                <label for="ftp-port" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.port_label") }}</label>
                <input id="ftp-port" type="number" x-model.number="form.config.port" :placeholder="form.integration_type === 'SFTP' ? '22' : '21'" min="1" max="65535" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
              </div>
            </div>
            <div>
              <label for="ftp-folder" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.remote_path_label") }}</label>
              <input id="ftp-folder" type="text" x-model="form.config.folder" placeholder="/upload" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <div>
              <label for="ftp-user" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.username_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="ftp-user" type="text" x-model="form.credentials.username" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <div>
              <label for="ftp-pass" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.password_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="ftp-pass" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.password" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <label class="inline-flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer">
              <input type="checkbox" x-model="showPassword" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
              {{ _("integrations.show_password") }}
            </label>
          </div>
        </template>

        <!-- Dropbox / Google Drive / OneDrive (OAuth) fields -->
        <template x-if="form.integration_type === 'DROPBOX' || form.integration_type === 'GOOGLE_DRIVE' || form.integration_type === 'ONEDRIVE'">
          <div class="space-y-3 border-t border-gray-200 dark:border-gray-700 pt-3">
            <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider" x-text="typeLabel(form.integration_type) + ' Settings'"></p>
            <div>
              <label for="oauth-folder" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.oauth_folder_label") }} <span class="text-gray-400">{{ _("integrations.folder_optional") }}</span></label>
              <input id="oauth-folder" type="text" x-model="form.config.folder" placeholder="/DocuElevate" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <div class="bg-blue-50 dark:bg-blue-900/30 rounded-md p-3 text-sm text-blue-700 dark:text-blue-300">
              <i class="fas fa-info-circle mr-1" aria-hidden="true"></i>
              {{ _("integrations.oauth_hint") }}
            </div>
          </div>
        </template>

        <!-- Email (destination) fields -->
        <template x-if="form.integration_type === 'EMAIL'">
          <div class="space-y-3 border-t border-gray-200 dark:border-gray-700 pt-3">
            <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider">{{ _("integrations.email_settings") }}</p>
            <div>
              <label for="email-to" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.recipient_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="email-to" type="email" x-model="form.config.recipient" placeholder="archive@example.com" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
            </div>
          </div>
        </template>

        <!-- Watch Folder fields -->
        <template x-if="form.integration_type === 'WATCH_FOLDER'">
          <div class="space-y-3 border-t border-gray-200 dark:border-gray-700 pt-3">
            <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider">{{ _("integrations.watch_folder_settings") }}</p>
            <div>
              <label for="wf-source-type" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.source_type_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <select id="wf-source-type" x-model="form.config.source_type" @change="onWatchFolderSourceTypeChange()" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true">
                <option value="local">{{ _("integrations.source_local") }}</option>
                <option value="s3">Amazon S3</option>
                <option value="dropbox">Dropbox</option>
                <option value="google_drive">Google Drive</option>
                <option value="onedrive">OneDrive</option>
                <option value="nextcloud">Nextcloud</option>
                <option value="webdav">WebDAV</option>
              </select>
            </div>

            <!-- Local filesystem fields -->
            <template x-if="form.config.source_type === 'local'">
              <div>
                <label for="wf-path" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.folder_path_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                <input id="wf-path" type="text" x-model="form.config.folder_path" placeholder="/data/inbox" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
              </div>
            </template>

            <!-- S3 fields -->
            <template x-if="form.config.source_type === 's3'">
              <div class="space-y-3">
                <div class="grid grid-cols-2 gap-3">
                  <div>
                    <label for="wf-s3-bucket" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.bucket_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                    <input id="wf-s3-bucket" type="text" x-model="form.config.bucket" placeholder="my-bucket" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                  </div>
                  <div>
                    <label for="wf-s3-region" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.region_label") }}</label>
                    <input id="wf-s3-region" type="text" x-model="form.config.region" placeholder="us-east-1" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
                  </div>
                </div>
                <div>
                  <label for="wf-s3-prefix" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.s3_prefix_label") }}</label>
                  <input id="wf-s3-prefix" type="text" x-model="form.config.prefix" placeholder="inbox/" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
                </div>
                <div>
                  <label for="wf-s3-endpoint" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.endpoint_label") }} <span class="text-xs text-gray-400">{{ _("integrations.endpoint_optional") }}</span></label>
                  <input id="wf-s3-endpoint" type="text" x-model="form.config.endpoint_url" placeholder="https://s3.example.com" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
                </div>
                <div class="grid grid-cols-2 gap-3">
                  <div>
                    <label for="wf-s3-ak" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.access_key_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                    <input id="wf-s3-ak" type="text" x-model="form.credentials.access_key_id" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                  </div>
                  <div>
                    <label for="wf-s3-sk" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.secret_key_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                    <input id="wf-s3-sk" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.secret_access_key" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
                  </div>
                </div>
              </div>
            </template>

            <!-- Dropbox fields -->
            <template x-if="form.config.source_type === 'dropbox'">
              <div class="space-y-3">
                <div>
                  <label for="wf-dbx-folder" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.folder_path_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                  <input id="wf-dbx-folder" type="text" x-model="form.config.folder_path" placeholder="/Inbox/Scanner" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                </div>
                <div>
                  <label for="wf-dbx-token" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">Refresh Token <span class="text-red-500" aria-hidden="true">*</span></label>
                  <input id="wf-dbx-token" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.refresh_token" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
                </div>
                <div class="grid grid-cols-2 gap-3">
                  <div>
                    <label for="wf-dbx-key" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">App Key <span class="text-red-500" aria-hidden="true">*</span></label>
                    <input id="wf-dbx-key" type="text" x-model="form.credentials.app_key" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                  </div>
                  <div>
                    <label for="wf-dbx-secret" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">App Secret <span class="text-red-500" aria-hidden="true">*</span></label>
                    <input id="wf-dbx-secret" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.app_secret" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
                  </div>
                </div>
              </div>
            </template>

            <!-- Google Drive fields -->
            <template x-if="form.config.source_type === 'google_drive'">
              <div class="space-y-3">
                <div>
                  <label for="wf-gd-folder" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">Folder ID <span class="text-red-500" aria-hidden="true">*</span></label>
                  <input id="wf-gd-folder" type="text" x-model="form.config.folder_id" placeholder="1ABCdef..." required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                </div>
                <div>
                  <label for="wf-gd-creds" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">Service Account JSON <span class="text-red-500" aria-hidden="true">*</span></label>
                  <textarea id="wf-gd-creds" x-model="form.credentials.credentials_json" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" rows="3" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm font-mono"></textarea>
                </div>
              </div>
            </template>

            <!-- OneDrive fields -->
            <template x-if="form.config.source_type === 'onedrive'">
              <div class="space-y-3">
                <div>
                  <label for="wf-od-folder" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.folder_path_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                  <input id="wf-od-folder" type="text" x-model="form.config.folder_path" placeholder="/Documents/Inbox" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                </div>
                <div>
                  <label for="wf-od-token" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">Refresh Token <span class="text-red-500" aria-hidden="true">*</span></label>
                  <input id="wf-od-token" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.refresh_token" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
                </div>
                <div class="grid grid-cols-2 gap-3">
                  <div>
                    <label for="wf-od-cid" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">Client ID <span class="text-red-500" aria-hidden="true">*</span></label>
                    <input id="wf-od-cid" type="text" x-model="form.credentials.client_id" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                  </div>
                  <div>
                    <label for="wf-od-cs" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">Client Secret <span class="text-red-500" aria-hidden="true">*</span></label>
                    <input id="wf-od-cs" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.client_secret" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
                  </div>
                </div>
              </div>
            </template>

            <!-- Nextcloud fields -->
            <template x-if="form.config.source_type === 'nextcloud'">
              <div class="space-y-3">
                <div>
                  <label for="wf-nc-url" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.nextcloud_url_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                  <input id="wf-nc-url" type="url" x-model="form.config.url" placeholder="https://cloud.example.com" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                </div>
                <div>
                  <label for="wf-nc-folder" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.folder_path_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                  <input id="wf-nc-folder" type="text" x-model="form.config.folder_path" placeholder="/Documents/Inbox" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                </div>
                <div class="grid grid-cols-2 gap-3">
                  <div>
                    <label for="wf-nc-user" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.username_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                    <input id="wf-nc-user" type="text" x-model="form.credentials.username" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                  </div>
                  <div>
                    <label for="wf-nc-pass" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.password_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                    <input id="wf-nc-pass" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.password" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
                  </div>
                </div>
              </div>
            </template>

            <!-- WebDAV fields -->
            <template x-if="form.config.source_type === 'webdav'">
              <div class="space-y-3">
                <div>
                  <label for="wf-dav-url" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.webdav_url_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                  <input id="wf-dav-url" type="url" x-model="form.config.url" placeholder="https://webdav.example.com/dav/" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                </div>
                <div>
                  <label for="wf-dav-folder" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.folder_path_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                  <input id="wf-dav-folder" type="text" x-model="form.config.folder_path" placeholder="/remote.php/webdav/Inbox" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                </div>
                <div class="grid grid-cols-2 gap-3">
                  <div>
                    <label for="wf-dav-user" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.username_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                    <input id="wf-dav-user" type="text" x-model="form.credentials.username" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
                  </div>
                  <div>
                    <label for="wf-dav-pass" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.password_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
                    <input id="wf-dav-pass" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.password" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
                  </div>
                </div>
              </div>
            </template>

            <!-- Common watch folder options -->
            <div class="flex flex-wrap items-center gap-4 pt-2">
              <label class="inline-flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer">
                <input type="checkbox" x-model="form.config.delete_after_process" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
                {{ _("integrations.delete_files_label") }}
              </label>
              <template x-if="form.config.source_type !== 'local'">
                <label class="inline-flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer">
                  <input type="checkbox" x-model="showPassword" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
                  {{ _("integrations.show_secrets") }}
                </label>
              </template>
            </div>
          </div>
        </template>

        <!-- Paperless fields -->
        <template x-if="form.integration_type === 'PAPERLESS'">
          <div class="space-y-3 border-t border-gray-200 dark:border-gray-700 pt-3">
            <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider">{{ _("integrations.paperless_settings") }}</p>
            <div>
              <label for="paperless-url" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">URL <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="paperless-url" type="url" x-model="form.config.url" placeholder="https://paperless.example.com" required class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" aria-required="true" />
            </div>
            <div>
              <label for="paperless-token" class="block text-sm font-medium text-gray-700 dark:text-gray-200 mb-1">{{ _("integrations.api_token_label") }} <span class="text-red-500" aria-hidden="true">*</span></label>
              <input id="paperless-token" :type="showPassword ? 'text' : 'password'" x-model="form.credentials.api_token" :placeholder="editingIntegration ? '(unchanged if blank)' : ''" :required="!editingIntegration" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-indigo-500 dark:bg-gray-700 dark:text-white text-sm" />
            </div>
            <label class="inline-flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer">
              <input type="checkbox" x-model="showPassword" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
              {{ _("integrations.show_token") }}
            </label>
          </div>
        </template>

        <!-- Webhook explanation and sample snippets -->
        <template x-if="form.integration_type === 'WEBHOOK'">
          <div class="space-y-4 border-t border-gray-200 dark:border-gray-700 pt-3">
            <p class="text-xs font-semibold text-purple-500 uppercase tracking-wider">
              <i class="fas fa-bolt mr-1" aria-hidden="true"></i> {{ _("integrations.webhook_heading") }}
            </p>

            <div class="bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-lg p-4">
              <h4 class="text-sm font-semibold text-blue-800 dark:text-blue-200 mb-2">
                <i class="fas fa-info-circle mr-1" aria-hidden="true"></i>
                {{ _("integrations.webhook_how_heading") }}
              </h4>
              <p class="text-sm text-blue-700 dark:text-blue-300 leading-relaxed">
                {{ _("integrations.webhook_how_text") }}
              </p>
              <p class="text-sm text-blue-700 dark:text-blue-300 leading-relaxed mt-2">
                {{ _("integrations.webhook_ideal_text") }}
              </p>
            </div>

            <div class="bg-gray-50 dark:bg-gray-750 rounded-lg p-4">
              <h4 class="text-sm font-semibold text-gray-800 dark:text-gray-200 mb-2">
                <i class="fas fa-terminal mr-1" aria-hidden="true"></i>
                {{ _("integrations.webhook_quick_start") }}
              </h4>
              <ol class="text-sm text-gray-600 dark:text-gray-400 space-y-2 list-decimal list-inside">
                <li>
                  {% set api_tokens_link %}<a href="/api-tokens" class="text-indigo-600 hover:underline font-medium">{{ _("nav.api_tokens") }}</a>{% endset %}
                  {{ _("integrations.webhook_step1", api_tokens_link=api_tokens_link) | safe }}
                </li>
                <li>{{ _("integrations.webhook_upload_with_token") }}</li>
              </ol>

              <div class="mt-3 relative">
                <pre class="bg-gray-900 text-green-400 rounded-lg p-4 text-xs overflow-x-auto font-mono leading-relaxed"><code>curl -X POST "<span x-text="window.location.origin"></span>/api/files/ui-upload" \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -F "file=@/path/to/document.pdf"</code></pre>
                <button
                  type="button"
                  @click="navigator.clipboard.writeText('curl -X POST \'' + window.location.origin + '/api/files/ui-upload\' \\\n  -H \'Authorization: Bearer YOUR_API_TOKEN\' \\\n  -F \'file=@/path/to/document.pdf\'')"
                  class="absolute top-2 right-2 px-2 py-1 bg-gray-700 text-gray-300 rounded text-xs hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-indigo-500"
                  style="min-height:28px; min-width:28px;"
                  aria-label="Copy curl example to clipboard"
                >
                  <i class="fas fa-copy" aria-hidden="true"></i>
                </button>
              </div>

              <h4 class="text-sm font-semibold text-gray-800 dark:text-gray-200 mt-4 mb-2">
                <i class="fab fa-python mr-1" aria-hidden="true"></i>
                Python Example
              </h4>
              <div class="relative">
                <pre class="bg-gray-900 text-green-400 rounded-lg p-4 text-xs overflow-x-auto font-mono leading-relaxed"><code>import requests

response = requests.post(
    "<span x-text="window.location.origin"></span>/api/files/ui-upload",
    headers={"Authorization": "Bearer YOUR_API_TOKEN"},
    files={"file": open("document.pdf", "rb")},
)
print(response.json())</code></pre>
                <button
                  type="button"
                  @click="navigator.clipboard.writeText('import requests\n\nresponse = requests.post(\n    \'' + window.location.origin + '/api/files/ui-upload\',\n    headers={\'Authorization\': \'Bearer YOUR_API_TOKEN\'},\n    files={\'file\': open(\'document.pdf\', \'rb\')},\n)\nprint(response.json())')"
                  class="absolute top-2 right-2 px-2 py-1 bg-gray-700 text-gray-300 rounded text-xs hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-indigo-500"
                  style="min-height:28px; min-width:28px;"
                  aria-label="Copy Python example to clipboard"
                >
                  <i class="fas fa-copy" aria-hidden="true"></i>
                </button>
              </div>
            </div>

            <div class="bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-3">
              <p class="text-xs text-yellow-800 dark:text-yellow-300">
                <i class="fas fa-shield-alt mr-1" aria-hidden="true"></i>
                {{ _("integrations.webhook_security_tip") }}
              </p>
            </div>
          </div>
        </template>

        <!-- Generic fallback for types without dedicated fields (excludes WEBHOOK) -->
        <template x-if="form.integration_type && !hasFormFields(form.integration_type) && form.integration_type !== 'WEBHOOK'">
          <div class="space-y-3 border-t border-gray-200 dark:border-gray-700 pt-3">
            <p class="text-xs font-semibold text-gray-400 uppercase tracking-wider" x-text="form.integration_type + ' Settings'"></p>
            <p class="text-sm text-gray-500 dark:text-gray-400">
              {{ _("integrations.generic_settings_hint") }}
            </p>
          </div>
        </template>

        <!-- Active toggle -->
        <div class="flex items-center gap-2 pt-2">
          <label class="inline-flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer">
            <input type="checkbox" x-model="form.is_active" class="rounded border-gray-300 text-indigo-600 focus:ring-indigo-500" />
            {{ _("integrations.active_label") }}
          </label>
        </div>

        <!-- Test Connection result -->
        <template x-if="testResult">
          <div
            class="border-l-4 p-3 rounded text-sm"
            :class="testResult.success ? 'bg-green-50 border-green-400 text-green-800 dark:bg-opacity-10' : 'bg-red-50 border-red-400 text-red-800 dark:bg-opacity-10'"
            role="status"
          >
            <p class="font-medium" x-text="testResult.success ? '{{ _('integrations.connection_success') }}' : '{{ _('integrations.connection_failed') }}'"></p>
            <p class="text-xs mt-0.5" x-text="testResult.message"></p>
          </div>
        </template>

        <!-- Form error -->
        <template x-if="formError">
          <div class="bg-red-50 border border-red-200 text-red-700 p-3 rounded text-sm" role="alert">
            <i class="fas fa-exclamation-triangle mr-1" aria-hidden="true"></i>
            <span x-text="formError"></span>
          </div>
        </template>

        <!-- Actions -->
        <div class="flex justify-between items-center pt-2 border-t border-gray-200 dark:border-gray-700">
          <button
            type="button"
            @click="testFromForm()"
            :disabled="testing || !form.integration_type"
            class="inline-flex items-center px-4 py-2 text-sm font-medium rounded border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-blue-500 disabled:opacity-50"
            style="min-height:40px;"
          >
            <template x-if="testing">
              <i class="fas fa-spinner fa-spin mr-2" aria-hidden="true"></i>
            </template>
            <template x-if="!testing">
              <i class="fas fa-plug mr-2" aria-hidden="true"></i>
            </template>
            {{ _("common.test_connection") }}
          </button>
          <div class="flex gap-2">
            <button
              type="button"
              @click="closeModal()"
              class="px-4 py-2 text-sm font-medium rounded border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500"
              style="min-height:40px;"
            >
              {{ _("common.cancel") }}
            </button>
            <button
              type="submit"
              :disabled="saving || !form.direction || !form.integration_type || !form.name"
              class="inline-flex items-center px-4 py-2 text-sm font-medium rounded bg-indigo-600 hover:bg-indigo-700 text-white focus:outline-none focus:ring-2 focus:ring-indigo-500 disabled:opacity-50"
              style="min-height:40px;"
            >
              <template x-if="saving">
                <i class="fas fa-spinner fa-spin mr-2" aria-hidden="true"></i>
              </template>
              <span x-text="editingIntegration ? '{{ _('common.update') }}' : '{{ _('common.save') }}'"></span>
            </button>
          </div>
        </div>
      </form>
    </div>
  </div>

  <!-- ── Delete confirmation modal ────────────────────────────────────────── -->
  <div
    x-show="deleteModalOpen"
    x-transition
    class="fixed inset-0 z-50 flex items-center justify-center bg-black/50 px-4"
    role="dialog"
    aria-modal="true"
    aria-labelledby="delete-modal-title"
    @keydown.escape.window="deleteModalOpen = false"
    style="display:none;"
  >
    <div class="bg-white dark:bg-gray-800 rounded-lg shadow-xl w-full max-w-sm p-6" @click.stop>
      <h2 id="delete-modal-title" class="text-lg font-semibold text-gray-900 dark:text-white mb-2">
        {{ _("integrations.delete_confirm_title") }}
      </h2>
      <p class="text-sm text-gray-600 dark:text-gray-300 mb-4">
        {{ _("integrations.delete_confirm_are_you_sure") }}
        <strong x-text="integrationToDelete ? integrationToDelete.name : ''"></strong>?
        {{ _("integrations.delete_confirm_undone") }}
      </p>
      <div class="flex justify-end gap-2">
        <button
          type="button"
          @click="deleteModalOpen = false; integrationToDelete = null"
          class="px-4 py-2 text-sm font-medium rounded border border-gray-300 dark:border-gray-600 text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 focus:outline-none focus:ring-2 focus:ring-gray-500"
          style="min-height:40px;"
        >
          {{ _("common.cancel") }}
        </button>
        <button
          type="button"
          @click="deleteIntegration()"
          :disabled="deleting"
          class="inline-flex items-center px-4 py-2 text-sm font-medium rounded bg-red-600 hover:bg-red-700 text-white focus:outline-none focus:ring-2 focus:ring-red-500 disabled:opacity-50"
          style="min-height:40px;"
        >
          <template x-if="deleting">
            <i class="fas fa-spinner fa-spin mr-2" aria-hidden="true"></i>
          </template>
          {{ _("common.delete") }}
        </button>
      </div>
    </div>
  </div>

</div>

<script>
function integrationsDashboard() {
  const SOURCE_TYPES = ['IMAP', 'WATCH_FOLDER', 'WEBHOOK'];
  const DEST_TYPES = ['S3', 'DROPBOX', 'GOOGLE_DRIVE', 'ONEDRIVE', 'WEBDAV', 'NEXTCLOUD', 'FTP', 'SFTP', 'EMAIL', 'PAPERLESS', 'RCLONE'];
  const TYPES_WITH_FORM_FIELDS = new Set(['IMAP', 'S3', 'WEBDAV', 'NEXTCLOUD', 'FTP', 'SFTP', 'DROPBOX', 'GOOGLE_DRIVE', 'ONEDRIVE', 'EMAIL', 'WATCH_FOLDER', 'PAPERLESS']);
  const OAUTH_TYPES = new Set(['DROPBOX', 'GOOGLE_DRIVE', 'ONEDRIVE']);

  const TYPE_LABELS = {
    IMAP: 'IMAP Email',
    WATCH_FOLDER: 'Watch Folder',
    WEBHOOK: 'Webhook',
    S3: 'Amazon S3',
    DROPBOX: 'Dropbox',
    GOOGLE_DRIVE: 'Google Drive',
    ONEDRIVE: 'OneDrive',
    WEBDAV: 'WebDAV',
    NEXTCLOUD: 'Nextcloud',
    FTP: 'FTP',
    SFTP: 'SFTP',
    EMAIL: 'Email Forward',
    PAPERLESS: 'Paperless NGX',
    RCLONE: 'Rclone',
  };

  const TYPE_ICONS = {
    IMAP: 'fa-inbox text-blue-500',
    WATCH_FOLDER: 'fa-folder-open text-yellow-500',
    WEBHOOK: 'fa-bolt text-purple-500',
    S3: 'fa-cube text-orange-500',
    DROPBOX: 'fa-dropbox text-blue-600',
    GOOGLE_DRIVE: 'fa-cloud text-green-500',
    ONEDRIVE: 'fa-cloud text-blue-400',
    WEBDAV: 'fa-cloud text-gray-500',
    NEXTCLOUD: 'fa-cloud text-blue-500',
    FTP: 'fa-server text-gray-600',
    SFTP: 'fa-server text-green-600',
    EMAIL: 'fa-paper-plane text-indigo-500',
    PAPERLESS: 'fa-file-pdf text-red-500',
    RCLONE: 'fa-sync text-teal-500',
  };

  return {
    integrations: [],
    quota: {
      dest_count: {{ dest_count }},
      src_count: {{ src_count }},
      max_destinations: {{ max_destinations | tojson }},
      max_sources: {{ max_sources | tojson }},
      can_add_destination: {{ 'true' if can_add_destination else 'false' }},
      can_add_source: {{ 'true' if can_add_source else 'false' }},
      tier_id: {{ tier_id | tojson }},
      tier_name: {{ tier_name | tojson }},
    },
    loading: true,
    alert: { show: false, type: '', title: '', message: '' },

    // Modal state
    modalOpen: false,
    editingIntegration: null,
    form: {
      direction: '',
      integration_type: '',
      name: '',
      config: {},
      credentials: {},
      is_active: true,
    },
    showPassword: false,
    saving: false,
    testing: false,
    testResult: null,
    formError: null,

    // Delete state
    deleteModalOpen: false,
    integrationToDelete: null,
    deleting: false,

    // Test saved
    testingId: null,

    get sources() {
      return this.integrations.filter(i => i.direction === 'SOURCE');
    },

    get destinations() {
      return this.integrations.filter(i => i.direction === 'DESTINATION');
    },

    get canAddAny() {
      return this.quota.can_add_destination || this.quota.can_add_source;
    },

    get availableTypes() {
      if (this.form.direction === 'SOURCE') return SOURCE_TYPES;
      if (this.form.direction === 'DESTINATION') return DEST_TYPES;
      return [];
    },

    typeLabel(t) { return TYPE_LABELS[t] || t; },
    typeIcon(t) { return TYPE_ICONS[t] || 'fa-plug text-gray-400'; },
    hasFormFields(t) { return TYPES_WITH_FORM_FIELDS.has(t); },
    _watchFolderOAuthSource(intg) {
      if (intg.integration_type !== 'WATCH_FOLDER') return null;
      const src = ((intg.config || {}).source_type || '').toLowerCase();
      if (src === 'dropbox' || src === 'onedrive' || src === 'google_drive') return src;
      return null;
    },

    isOAuthType(intg) {
      // Direct OAuth types: DROPBOX, GOOGLE_DRIVE, ONEDRIVE
      if (OAUTH_TYPES.has(intg.integration_type)) return true;
      // WATCH_FOLDER with an OAuth-backed source type
      return this._watchFolderOAuthSource(intg) !== null;
    },

    oauthLink(intg) {
      const t = intg.integration_type;
      if (t === 'DROPBOX') return '/dropbox-setup';
      if (t === 'GOOGLE_DRIVE') return '/google-drive-setup';
      if (t === 'ONEDRIVE') return '/onedrive-setup';
      const src = this._watchFolderOAuthSource(intg);
      if (src === 'dropbox') return '/dropbox-setup';
      if (src === 'onedrive') return '/onedrive-setup';
      if (src === 'google_drive') return '/google-drive-setup';
      return '#';
    },

    async init() {
      try {
        const resp = await fetch('/api/integrations/', {
          headers: { 'Accept': 'application/json' },
        });
        if (resp.ok) {
          this.integrations = await resp.json();
        }
      } catch (err) {
        console.error('Failed to load integrations', err);
      } finally {
        this.loading = false;
      }
    },

    showAlert(type, title, message) {
      this.alert = { show: true, type, title, message };
      setTimeout(() => { this.alert.show = false; }, 5000);
    },

    formatDate(iso) {
      if (!iso) return '';
      try { return new Date(iso).toLocaleString(); }
      catch (e) { return iso; }
    },

    onDirectionChange() {
      this.form.integration_type = '';
      this.form.config = {};
      this.form.credentials = {};
      this.testResult = null;
    },

    onTypeChange() {
      this.form.config = {};
      this.form.credentials = {};
      this.testResult = null;
      // Set sensible defaults
      if (this.form.integration_type === 'IMAP') {
        this.form.config = { host: '', port: 993, username: '', use_ssl: true, delete_after_process: false, gmail_apply_labels: true };
        this.form.credentials = { password: '' };
      } else if (this.form.integration_type === 'S3') {
        this.form.config = { bucket: '', region: 'us-east-1', folder_prefix: '', endpoint_url: '' };
        this.form.credentials = { access_key_id: '', secret_access_key: '' };
      } else if (this.form.integration_type === 'WEBDAV' || this.form.integration_type === 'NEXTCLOUD') {
        this.form.config = { url: '', folder: '' };
        this.form.credentials = { username: '', password: '' };
      } else if (this.form.integration_type === 'FTP' || this.form.integration_type === 'SFTP') {
        this.form.config = { host: '', port: this.form.integration_type === 'SFTP' ? 22 : 21, folder: '' };
        this.form.credentials = { username: '', password: '' };
      } else if (this.form.integration_type === 'DROPBOX' || this.form.integration_type === 'GOOGLE_DRIVE' || this.form.integration_type === 'ONEDRIVE') {
        this.form.config = { folder: '' };
        this.form.credentials = {};
      } else if (this.form.integration_type === 'EMAIL') {
        this.form.config = { recipient: '' };
        this.form.credentials = {};
      } else if (this.form.integration_type === 'WATCH_FOLDER') {
        this.form.config = { source_type: 'local', folder_path: '', delete_after_process: false };
        this.form.credentials = {};
      } else if (this.form.integration_type === 'PAPERLESS') {
        this.form.config = { url: '' };
        this.form.credentials = { api_token: '' };
      }
    },

    onWatchFolderSourceTypeChange() {
      const st = this.form.config.source_type;
      const dap = this.form.config.delete_after_process || false;
      this.form.credentials = {};
      if (st === 'local') {
        this.form.config = { source_type: st, folder_path: '', delete_after_process: dap };
      } else if (st === 's3') {
        this.form.config = { source_type: st, bucket: '', region: 'us-east-1', prefix: '', endpoint_url: '', delete_after_process: dap };
        this.form.credentials = { access_key_id: '', secret_access_key: '' };
      } else if (st === 'dropbox') {
        this.form.config = { source_type: st, folder_path: '', delete_after_process: dap };
        this.form.credentials = { refresh_token: '', app_key: '', app_secret: '' };
      } else if (st === 'google_drive') {
        this.form.config = { source_type: st, folder_id: '', delete_after_process: dap };
        this.form.credentials = { credentials_json: '' };
      } else if (st === 'onedrive') {
        this.form.config = { source_type: st, folder_path: '', delete_after_process: dap };
        this.form.credentials = { refresh_token: '', client_id: '', client_secret: '' };
      } else if (st === 'nextcloud') {
        this.form.config = { source_type: st, url: '', folder_path: '', delete_after_process: dap };
        this.form.credentials = { username: '', password: '' };
      } else if (st === 'webdav') {
        this.form.config = { source_type: st, url: '', folder_path: '', delete_after_process: dap };
        this.form.credentials = { username: '', password: '' };
      }
    },

    openCreateModal() {
      this.editingIntegration = null;
      this.form = {
        direction: '',
        integration_type: '',
        name: '',
        config: {},
        credentials: {},
        is_active: true,
      };
      this.showPassword = false;
      this.testResult = null;
      this.formError = null;
      this.modalOpen = true;
    },

    openEditModal(intg) {
      this.editingIntegration = intg;
      this.form = {
        direction: intg.direction,
        integration_type: intg.integration_type,
        name: intg.name,
        config: intg.config ? JSON.parse(JSON.stringify(intg.config)) : {},
        credentials: {},
        is_active: intg.is_active,
      };
      this.showPassword = false;
      this.testResult = null;
      this.formError = null;
      this.modalOpen = true;
    },

    closeModal() {
      this.modalOpen = false;
      this.editingIntegration = null;
      this.testResult = null;
      this.formError = null;
    },

    _buildPayload() {
      const payload = {
        direction: this.form.direction,
        integration_type: this.form.integration_type,
        name: this.form.name,
        is_active: this.form.is_active,
      };
      // Include config if non-empty
      const cfg = this.form.config;
      if (cfg && Object.keys(cfg).length > 0) {
        payload.config = cfg;
      }
      // Include credentials only if user entered values
      const creds = this.form.credentials;
      if (creds && Object.keys(creds).length > 0) {
        const hasValue = Object.values(creds).some(v => v !== '' && v !== null && v !== undefined);
        if (hasValue) payload.credentials = creds;
      }
      return payload;
    },

    async saveIntegration() {
      this.formError = null;
      this.saving = true;
      try {
        const payload = this._buildPayload();
        let resp;
        if (this.editingIntegration) {
          // For updates, only send updatable fields
          const update = { name: payload.name, is_active: payload.is_active };
          if (payload.config) update.config = payload.config;
          if (payload.credentials) update.credentials = payload.credentials;
          resp = await fetch(`/api/integrations/${this.editingIntegration.id}`, {
            method: 'PUT',
            headers: authHeaders(true),
            body: JSON.stringify(update),
          });
        } else {
          resp = await fetch('/api/integrations/', {
            method: 'POST',
            headers: authHeaders(true),
            body: JSON.stringify(payload),
          });
        }
        const data = await resp.json();
        if (!resp.ok) {
          this.formError = data.detail || 'Failed to save integration.';
          return;
        }
        // Update local list
        if (this.editingIntegration) {
          const idx = this.integrations.findIndex(i => i.id === data.id);
          if (idx !== -1) this.integrations.splice(idx, 1, data);
        } else {
          this.integrations.push(data);
          this._recalcQuota();
        }
        this.closeModal();
        this.showAlert('success', 'Saved', this.editingIntegration ? 'Integration updated.' : 'Integration added successfully.');
      } catch (err) {
        this.formError = `Network error: ${err.message || 'Unknown error'}. Please try again.`;
      } finally {
        this.saving = false;
      }
    },

    async testFromForm() {
      this.testing = true;
      this.testResult = null;
      try {
        const payload = {
          integration_type: this.form.integration_type,
          config: this.form.config,
          credentials: Object.keys(this.form.credentials).length > 0 ? this.form.credentials : null,
        };
        const resp = await fetch('/api/integrations/test', {
          method: 'POST',
          headers: authHeaders(true),
          body: JSON.stringify(payload),
        });
        this.testResult = await resp.json();
      } catch (err) {
        this.testResult = { success: false, message: `Network error: ${err.message || 'Unknown error'}` };
      } finally {
        this.testing = false;
      }
    },

    async testSavedIntegration(intg) {
      this.testingId = intg.id;
      try {
        // Retrieve saved credentials to test
        const credsResp = await fetch(`/api/integrations/${intg.id}/credentials`);
        if (!credsResp.ok) {
          this.showAlert('error', 'Test Failed', 'Could not retrieve saved credentials for testing.');
          return;
        }
        const creds = await credsResp.json();
        const resp = await fetch('/api/integrations/test', {
          method: 'POST',
          headers: authHeaders(true),
          body: JSON.stringify({
            integration_type: intg.integration_type,
            config: intg.config,
            credentials: creds.credentials,
          }),
        });
        const data = await resp.json();
        if (data.success) {
          this.showAlert('success', `${intg.name}: Connection OK`, data.message);
        } else {
          this.showAlert('error', `${intg.name}: Connection Failed`, data.message);
        }
      } catch (err) {
        this.showAlert('error', 'Test Failed', `Network error: ${err.message || 'Unknown error'}`);
      } finally {
        this.testingId = null;
      }
    },

    confirmDelete(intg) {
      this.integrationToDelete = intg;
      this.deleteModalOpen = true;
    },

    async deleteIntegration() {
      if (!this.integrationToDelete) return;
      this.deleting = true;
      try {
        const resp = await fetch(`/api/integrations/${this.integrationToDelete.id}`, {
          method: 'DELETE',
          headers: authHeaders(false),
        });
        if (resp.ok || resp.status === 204) {
          this.integrations = this.integrations.filter(i => i.id !== this.integrationToDelete.id);
          this._recalcQuota();
          this.showAlert('success', 'Deleted', `"${this.integrationToDelete.name}" has been removed.`);
          this.deleteModalOpen = false;
          this.integrationToDelete = null;
        } else {
          const data = await resp.json();
          this.showAlert('error', 'Delete Failed', data.detail || 'Could not delete integration.');
        }
      } catch (err) {
        this.showAlert('error', 'Delete Failed', `Network error: ${err.message || 'Unknown error'}`);
      } finally {
        this.deleting = false;
      }
    },

    _recalcQuota() {
      this.quota.dest_count = this.integrations.filter(i => i.direction === 'DESTINATION').length;
      this.quota.src_count = this.integrations.filter(i => i.direction === 'SOURCE' && i.integration_type === 'IMAP').length;
      if (this.quota.max_destinations !== null) {
        this.quota.can_add_destination = this.quota.dest_count < this.quota.max_destinations;
      }
      if (this.quota.max_sources !== null && this.quota.max_sources > 0) {
        this.quota.can_add_source = this.quota.src_count < this.quota.max_sources;
      }
    },
  };
}

function getCsrfToken() {
  const meta = document.querySelector('meta[name="csrf-token"]');
  if (meta) return meta.getAttribute('content');
  return '';
}

function authHeaders(json) {
  const h = { 'X-CSRF-Token': getCsrfToken() };
  if (json) h['Content-Type'] = 'application/json';
  return h;
}
</script>
{% endblock %}
