<!-- #region ConfigTabForm [C:4] [TYPE Component] [SEMANTICS translate, config, datasource, llm, columns] -->
<!-- @BRIEF Configuration tab content for Translation Job — datasource selection with auto-detected
     DB dialect, column mapping, LLM provider, target languages (multi-select from LANGUAGES),
     dictionaries, disable reasoning toggle. -->
<!-- @LAYER UI -->
<!-- @RELATION DEPENDS_ON -> [EXT:frontend:fetchDatasources] -->
<!-- @RELATION DEPENDS_ON -> [EXT:frontend:fetchDatasourceColumns] -->
<!-- @RELATION DEPENDS_ON -> [MultiSelect] -->
<!-- @RELATION BINDS_TO -> [EXT:frontend:LANGUAGE_LABELS] -->
<!-- @UX_STATE Datasource searching -> Dropdown with filtered results, spinner on load -->
<!-- @UX_STATE Datasource selected -> Columns loaded, DB dialect detected, mapping ready -->
<!-- @UX_STATE Columns loading -> Skeleton pulse in column section -->
<!-- @UX_STATE Validation error -> Red border on invalid fields, inline error text -->
<!-- @UX_FEEDBACK Detected dialect badge (green pill) when datasource selected -->
<!-- @UX_FEEDBACK Spinner in datasource input while searching -->
<!-- @UX_FEEDBACK Virtual column warning (yellow bg + asterisk) -->
<!-- @UX_RECOVERY Datasource not found -> try different search term -->
<!-- @UX_RECOVERY Environment changed -> datasource search cleared, new DB list loaded -->
<!-- @UX_REACTIVITY Props -> $bindable() for all form fields, $props() for environment list -->
<!-- @UX_REACTIVITY LocalState -> datasourceList, datasourceLoading, showDatasourceDropdown -->
<script lang="ts">
  import { t } from '$lib/i18n/index.svelte.js';
  import { fetchDatasources, fetchDatasourceColumns } from '$lib/api/translate.js';
  import MultiSelect from '$lib/components/ui/MultiSelect.svelte';
  import HelpTooltip from '$lib/ui/HelpTooltip.svelte';

  const LANGUAGE_LABELS = {
    ru: 'Русский', en: 'English', de: 'Deutsch', fr: 'Français', es: 'Español',
    it: 'Italiano', pt: 'Português', zh: '中文', ja: '日本語', ko: '한국어',
    ar: 'العربية', tr: 'Türkçe', nl: 'Nederlands', pl: 'Polski', sv: 'Svenska',
    da: 'Dansk', fi: 'Suomi', cs: 'Čeština', hu: 'Magyar', ro: 'Română',
    vi: 'Tiếng Việt', th: 'ไทย', he: 'עברית', id: 'Bahasa Indonesia', ms: 'Bahasa Melayu',
  };
  const LANGUAGES = Object.entries(LANGUAGE_LABELS).map(([code, name]) => ({ code, name }));

  // ---- Bindable form state (parent-owned) ----
  let {
    name = $bindable(''),
    description = $bindable(''),
    environmentId = $bindable(''),
    environments = [],
    datasourceId = $bindable(''),
    datasourceSearch = $bindable(''),
    databaseDialect = $bindable(''),
    availableColumns = [],
    virtualColumns = $bindable([]),
    sourceKeyCols = $bindable([]),
    targetKeyCols = $bindable([]),
    translationColumn = $bindable(''),
    contextColumns = $bindable([]),
    targetLanguages = $bindable(['en']),
    targetLanguageColumn = $bindable(''),
    targetSourceColumn = $bindable(''),
    targetSourceLanguageColumn = $bindable(''),
    providerId = $bindable(''),
    llmProviders = [],
    dictionaryIds = $bindable([]),
    availableDictionaries = [],
    disableReasoning = $bindable(false),
    validationErrors = {},
    onEnvChange = () => {},
  } = $props();

  // ---- Local state ----
  let datasourceList = $state([]);
  let datasourceLoading = $state(false);
  let showDatasourceDropdown = $state(false);
  let isColumnsLoading = $state(false);
  let columnList = $derived(availableColumns);

  // ---- Derived ----
  let logicalColumns = $derived(availableColumns.filter(c => c.is_physical !== false));
  let virtualColumnNames = $derived(virtualColumns);

  function isVirtual(colName) {
    return (virtualColumns || []).includes(colName);
  }

  // Auto-load columns when datasourceId changes (from parent loadJob or user selection)
  $effect(() => {
    if (datasourceId && environmentId) {
      loadColumnsForDatasource();
    }
  });

  // ---- Datasource search ----
  let searchTimer = null;
  async function handleDatasourceSearch() {
    clearTimeout(searchTimer);
    searchTimer = setTimeout(() => searchDatasources(datasourceSearch), 300);
  }

  async function searchDatasources(searchTerm = '') {
    if (!environmentId) return;
    datasourceLoading = true;
    try {
      datasourceList = await fetchDatasources(environmentId, searchTerm);
      showDatasourceDropdown = true;
    } catch (_e) {
      datasourceList = [];
    } finally {
      datasourceLoading = false;
    }
  }

  /** Select a dataset from the dropdown */
  function selectDatasource(ds) {
    datasourceId = String(ds.id);
    datasourceSearch = `${ds.table_name} (${ds.database_name} · ${ds.database_dialect})`;
    showDatasourceDropdown = false;
    availableColumns = [];
    virtualColumns = [];
    sourceKeyCols = [];
    targetKeyCols = [];
    translationColumn = '';
    targetLanguageColumn = '';
    targetSourceColumn = '';
    targetSourceLanguageColumn = '';
    contextColumns = [];
    databaseDialect = ds.database_dialect || '';
  }

  async function loadColumnsForDatasource() {
    if (!datasourceId || !environmentId) return;
    isColumnsLoading = true;
    try {
      const response = await fetchDatasourceColumns(datasourceId, environmentId);
      availableColumns = response.columns || response || [];
      virtualColumns = response.virtual_columns || [];
    } catch (_e) {
      availableColumns = [];
      virtualColumns = [];
    } finally {
      isColumnsLoading = false;
    }
  }

  // ---- Key column helpers ----
  function toggleSourceKeyCol(colName) {
    if (sourceKeyCols.includes(colName)) {
      const idx = sourceKeyCols.indexOf(colName);
      sourceKeyCols = sourceKeyCols.filter((_, i) => i !== idx);
      targetKeyCols = targetKeyCols.filter((_, i) => i !== idx);
    } else {
      sourceKeyCols = [...sourceKeyCols, colName];
      targetKeyCols = [...targetKeyCols, colName];
    }
  }

  function updateTargetKeyCol(idx, value) {
    targetKeyCols[idx] = value;
    targetKeyCols = targetKeyCols; // trigger reactivity
  }

  function toggleContextColumn(col) {
    if (contextColumns.includes(col)) {
      contextColumns = contextColumns.filter(c => c !== col);
    } else {
      contextColumns = [...contextColumns, col];
    }
  }
</script>

<div class="space-y-6">
  <!-- Basic Info -->
  <section class="bg-white border border-gray-200 rounded-lg p-6">
    <h2 class="text-lg font-semibold text-gray-900 mb-4">{$t.translate?.config?.basic_info}</h2>
    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
      <div class="md:col-span-2">
        <label class="block text-sm font-medium text-gray-700 mb-1 flex items-center gap-1">
          {$t.translate?.config?.name} <span class="text-red-500">*</span>
          <HelpTooltip text={$t.translate?.config?.help_name || ''} />
        </label>
        <input
          type="text"
          bind:value={name}
          class="w-full px-3 py-2 border rounded-lg text-sm {validationErrors.name ? 'border-red-300 bg-destructive-light' : 'border-gray-300'} focus-visible:ring-2 focus-visible:ring-primary-ring focus-visible:border-primary-ring"
          placeholder={$t.translate?.config?.name_placeholder}
        />
        {#if validationErrors.name}
          <p class="text-xs text-red-600 mt-1">{validationErrors.name}</p>
        {/if}
      </div>
      <div class="md:col-span-2">
        <label class="block text-sm font-medium text-gray-700 mb-1 flex items-center gap-1">
          {$t.translate?.config?.description}
          <HelpTooltip text={$t.translate?.config?.help_description || ''} />
        </label>
        <textarea
          bind:value={description}
          rows="2"
          class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus-visible:ring-2 focus-visible:ring-primary-ring focus-visible:border-primary-ring"
          placeholder={$t.translate?.config?.description_placeholder}
        />
      </div>
    </div>
  </section>

  <!-- Datasource & Environment -->
  <section class="bg-white border border-gray-200 rounded-lg p-6">
    <h2 class="text-lg font-semibold text-gray-900 mb-4">{$t.translate?.config?.datasource}</h2>
    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
      <div>
        <label class="block text-sm font-medium text-gray-700 mb-1 flex items-center gap-1">
          {$t.translate?.config?.environment}
          <HelpTooltip text={$t.translate?.config?.help_environment || ''} />
        </label>
        <select
          bind:value={environmentId}
          onchange={onEnvChange}
          class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus-visible:ring-2 focus-visible:ring-primary-ring focus-visible:border-primary-ring"
        >
          <option value="">{$t.translate?.config?.select_environment}</option>
          {#each environments as env}
            <option value={env.id}>{env.name} ({env.id})</option>
          {/each}
        </select>
      </div>
      <div class="relative">
        <label class="block text-sm font-medium text-gray-700 mb-1 flex items-center gap-1">
          {$t.translate?.config?.datasource_id}
          <HelpTooltip text={$t.translate?.config?.help_datasource || ''} />
        </label>
        <input
          type="text"
          bind:value={datasourceSearch}
          oninput={handleDatasourceSearch}
          onfocus={() => searchDatasources('')}
          onblur={() => setTimeout(() => (showDatasourceDropdown = false), 150)}
          class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm focus-visible:ring-2 focus-visible:ring-primary-ring focus-visible:border-primary-ring"
          placeholder={$t.translate?.config?.datasource_search_placeholder || 'Search datasets...'}
        />
        {#if datasourceLoading}
          <div class="absolute right-3 top-9 animate-spin h-4 w-4 border-2 border-blue-500 border-t-transparent rounded-full"></div>
        {/if}
        {#if showDatasourceDropdown}
          <div class="absolute z-10 mt-1 w-full bg-white border border-gray-200 rounded-lg shadow-lg max-h-60 overflow-y-auto">
            {#each datasourceList as ds}
              <button
                type="button"
                onmousedown={() => selectDatasource(ds)}
                class="w-full text-left px-3 py-2 text-sm hover:bg-blue-50 border-b border-gray-100 last:border-b-0"
              >
                <span class="font-medium">{ds.table_name}</span>
                <span class="text-gray-400 ml-2">{ds.schema}</span>
                <span class="float-right text-xs text-gray-400">{ds.database_name} · {ds.database_dialect}</span>
              </button>
            {/each}
          </div>
        {/if}
      </div>
      {#if databaseDialect}
        <div class="md:col-span-2">
          <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-700">
            {$t.translate?.config?.detected_dialect.replace('{dialect}', databaseDialect)}
          </span>
        </div>
      {/if}
    </div>

    {#if isColumnsLoading}
      <div class="mt-4 h-8 bg-gray-100 rounded animate-pulse" />
    {/if}

    {#if columnList.length > 0}
      <div class="mt-4">
        <label class="block text-sm font-medium text-gray-700 mb-2">
          {$t.translate?.config?.available_columns.replace('{count}', columnList.length)}
        </label>
        <div class="max-h-40 overflow-y-auto border border-gray-200 rounded-lg divide-y divide-gray-100">
          {#each columnList as col}
            <div class="px-3 py-1.5 text-sm flex items-center gap-2 {isVirtual(col.name) ? 'bg-yellow-50' : ''}">
              <span class="font-mono text-xs">{col.name}</span>
              {#if col.type}
                <span class="text-xs text-gray-400">({col.type})</span>
              {/if}
              {#if isVirtual(col.name)}
                <span class="text-xs text-yellow-600 italic">{$t.translate?.config?.virtual}</span>
              {/if}
            </div>
          {/each}
        </div>
      </div>
    {/if}
  </section>

  <!-- Column Mapping -->
  <section class="bg-white border border-gray-200 rounded-lg p-6">
    <h2 class="text-lg font-semibold text-gray-900 mb-4">{$t.translate?.config?.column_mapping}</h2>

    <!-- Translation Column -->
    <div class="mb-4">
      <label class="block text-sm font-medium text-gray-700 mb-1 flex items-center gap-1">
        {$t.translate?.config?.translation_column} <span class="text-red-500">*</span>
        <HelpTooltip text={$t.translate?.config?.help_translation_column || ''} />
      </label>
      <select
        bind:value={translationColumn}
        class="w-full px-3 py-2 border rounded-lg text-sm {validationErrors.translationColumn ? 'border-red-300 bg-destructive-light' : 'border-gray-300'} focus-visible:ring-2 focus-visible:ring-primary-ring focus-visible:border-primary-ring"
      >
        <option value="">{$t.translate?.config?.select_column}</option>
        {#each columnList as col}
          <option value={col.name}>{col.name}{isVirtual(col.name) ? ` (${$t.translate?.config?.virtual})` : ''}</option>
        {/each}
      </select>
      {#if validationErrors.translationColumn}
        <p class="text-xs text-red-600 mt-1">{validationErrors.translationColumn}</p>
      {/if}
    </div>

    <!-- Key Mapping (source -> target pairs) -->
    <div class="mb-4">
      <div class="flex items-center justify-between mb-2">
        <label class="block text-sm font-medium text-gray-700 flex items-center gap-1">
          {$t.translate?.config?.key_columns}
          <HelpTooltip text={$t.translate?.config?.help_key_columns || ''} />
        </label>
        {#if sourceKeyCols.length > 0}
          <button
            onclick={() => { sourceKeyCols = []; targetKeyCols = []; }}
            class="text-xs text-red-600 hover:text-red-700"
          >
            {$t.translate?.config?.clear_all}
          </button>
        {/if}
      </div>

      {#if columnList.length === 0}
        <div class="flex flex-wrap gap-2 mb-3">
          <button
            onclick={() => {
              sourceKeyCols = [...sourceKeyCols, ''];
              targetKeyCols = [...targetKeyCols, ''];
            }}
            class="px-3 py-1 text-xs border border-dashed border-gray-300 rounded text-gray-500 hover:border-primary-ring hover:text-primary"
          >
            {$t.translate?.config?.add_key_column}
          </button>
        </div>
      {:else}
        <div class="flex flex-wrap gap-2 mb-3">
          {#each columnList as col}
            <button
              onclick={() => toggleSourceKeyCol(col.name)}
              class="px-2.5 py-1 text-xs rounded-full border transition-colors
                {sourceKeyCols.includes(col.name)
                  ? 'bg-blue-100 border-blue-300 text-blue-700'
                  : 'bg-white border-gray-200 text-gray-600 hover:border-gray-300'}"
              title={isVirtual(col.name) ? $t.translate?.config?.virtual_column_warning.replace('{col}', col.name) : ''}
            >
              {col.name}
              {#if isVirtual(col.name)}
                <span class="text-yellow-500">*</span>
              {/if}
            </button>
          {/each}
        </div>
      {/if}

      {#if sourceKeyCols.length > 0}
        <div class="space-y-2">
          {#each sourceKeyCols as srcCol, idx}
            <div class="flex items-center gap-2">
              <input
                type="text"
                value={srcCol}
                disabled
                class="flex-1 px-3 py-1.5 border border-gray-200 bg-gray-50 rounded text-sm font-mono"
              />
              <span class="text-gray-400 text-sm">&rarr;</span>
              <input
                type="text"
                value={targetKeyCols[idx] || ''}
                placeholder={$t.translate?.config?.target_column_placeholder}
                oninput={(e) => updateTargetKeyCol(idx, e.target.value)}
                class="flex-1 px-3 py-1.5 border border-gray-300 rounded text-sm font-mono focus-visible:ring-2 focus-visible:ring-primary-ring"
              />
              <button
                onclick={() => {
                  sourceKeyCols = sourceKeyCols.filter((_, i) => i !== idx);
                  targetKeyCols = targetKeyCols.filter((_, i) => i !== idx);
                }}
                class="p-1 text-gray-400 hover:text-red-500"
              >
                <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                </svg>
              </button>
            </div>
          {/each}
        </div>
      {/if}
      {#if validationErrors.targetKeyCols}
        <p class="text-xs text-red-600 mt-1">{validationErrors.targetKeyCols}</p>
      {/if}
    </div>

    <!-- Context Columns -->
    <div>
      <label class="block text-sm font-medium text-gray-700 mb-2 flex items-center gap-1">
        {$t.translate?.config?.context_columns}
        <HelpTooltip text={$t.translate?.config?.help_context_columns || ''} />
      </label>
      {#if columnList.length === 0}
        <p class="text-xs text-gray-400">{$t.translate?.config?.select_datasource_hint}</p>
      {:else}
        <div class="flex flex-wrap gap-2">
          {#each columnList as col}
            <button
              onclick={() => toggleContextColumn(col.name)}
              class="px-2.5 py-1 text-xs rounded-full border transition-colors
                {contextColumns.includes(col.name)
                  ? 'bg-purple-100 border-purple-300 text-purple-700'
                  : 'bg-white border-gray-200 text-gray-600 hover:border-gray-300'}"
            >
              {col.name}
              {#if isVirtual(col.name)}
                <span class="text-yellow-500">*</span>
              {/if}
            </button>
          {/each}
        </div>
      {/if}
    </div>
  </section>

  <!-- LLM Settings -->
  <section class="bg-white border border-gray-200 rounded-lg p-6">
    <h2 class="text-lg font-semibold text-gray-900 mb-4">{$t.translate?.config?.llm_settings}</h2>
    <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
      <div>
        <label class="block text-sm font-medium text-gray-700 mb-1 flex items-center gap-1">
          {$t.translate?.config?.provider}
          <HelpTooltip text={$t.translate?.config?.help_provider || ''} />
        </label>
        <select bind:value={providerId} class="w-full px-3 py-2 border border-gray-300 rounded-lg text-sm">
          <option value="">{$t.translate?.config?.select_provider}</option>
          {#each llmProviders as provider}
            <option value={provider.id}>{provider.name || provider.provider_type}</option>
          {/each}
        </select>
      </div>
      <div>
        <div class="flex items-center gap-1 mb-1">
          <span class="text-sm font-medium text-gray-700">{$t.translate?.config?.target_language}</span>
          <span class="text-red-500">*</span>
          <HelpTooltip text={$t.translate?.config?.help_target_language || ''} />
        </div>
        <MultiSelect
          label=""
          options={LANGUAGES}
          bind:selected={targetLanguages}
          searchable={true}
          placeholder={$t.translate?.config?.target_language_search_placeholder || 'Search languages...'}
          required={false}
        />
        {#if targetLanguages.length === 0}
          <p class="text-xs text-amber-600 mt-1">{$t.translate?.config?.target_language_required || 'Select at least one target language'}</p>
        {/if}
      </div>
    </div>

    <!-- Disable reasoning toggle -->
    <div class="mt-3">
      <label class="flex items-start gap-3 cursor-pointer">
        <input
          type="checkbox"
          bind:checked={disableReasoning}
          class="mt-0.5 rounded border-gray-300 text-primary focus-visible:ring-primary-ring"
        />
        <div>
          <span class="text-sm font-medium text-gray-700 flex items-center gap-1">
            {$t.translate?.config?.disable_reasoning || 'Disable reasoning (save tokens)'}
            <HelpTooltip text={$t.translate?.config?.help_disable_reasoning || ''} />
          </span>
          <p class="text-xs text-gray-400 mt-0.5">
            {$t.translate?.config?.disable_reasoning_hint || 'Saves output tokens by suppressing Chain of Thought reasoning'}
          </p>
        </div>
      </label>
    </div>
  </section>

  <!-- Dictionary Attachment -->
  <section class="bg-white border border-gray-200 rounded-lg p-6">
    <h2 class="text-lg font-semibold text-gray-900 mb-4 flex items-center gap-2">
      {$t.translate?.config?.terminology_dictionaries}
      <HelpTooltip text={$t.translate?.config?.help_dictionaries || ''} />
    </h2>
    {#if availableDictionaries.length === 0}
      <p class="text-sm text-gray-400">
        {$t.translate?.config?.no_dictionaries}
      </p>
    {:else}
      <div class="space-y-2">
        {#each availableDictionaries as dict}
          <label class="flex items-center gap-3 p-3 border border-gray-200 rounded-lg hover:bg-gray-50 cursor-pointer">
            <input
              type="checkbox"
              checked={dictionaryIds.includes(dict.id)}
              onchange={() => {
                if (dictionaryIds.includes(dict.id)) {
                  dictionaryIds = dictionaryIds.filter(d => d !== dict.id);
                } else {
                  dictionaryIds = [...dictionaryIds, dict.id];
                }
              }}
              class="rounded border-gray-300 text-primary focus-visible:ring-primary-ring"
            />
            <div>
              <span class="text-sm font-medium text-gray-900">{dict.name}</span>
              {#if dict.description}
                <p class="text-xs text-gray-500">{dict.description}</p>
              {/if}
              {#if dict.source_dialect || dict.target_dialect}
                <p class="text-xs text-gray-400">
                  {dict.source_dialect} &rarr; {dict.target_dialect}
                </p>
              {/if}
            </div>
          </label>
        {/each}
      </div>
    {/if}
  </section>
</div>
<!-- #endregion ConfigTabForm -->
