<!-- #region TranslateJobList [C:3] [TYPE Page] [SEMANTICS sveltekit, translate, job, list, schedule] -->
<script lang="ts">
  import { onMount } from 'svelte';
  import { goto } from '$app/navigation';
  import { t, _ } from '$lib/i18n/index.svelte.js';
  import { addToast } from '$lib/toasts.svelte.js';
  import { fetchJobs, deleteJob, duplicateJob } from '$lib/api/translate.js';

  /** @type {string} idle | loading | empty | populated | error */
  let uxState = $state('idle');
  let jobs = $state([]);
  let error = $state(null);
  let isLoading = $state(true);
  let showDeleteConfirm = $state(null);
  let statusFilter = $state('');
  let currentPage = $state(1);
  let pageSize = $state(20);

  // Count jobs by status for filter pills
  let statusCounts = $derived.by(() => {
    const counts = { DRAFT: 0, READY: 0, RUNNING: 0, COMPLETED: 0, FAILED: 0, CANCELLED: 0 };
    for (const job of jobs) {
      if (counts[job.status] !== undefined) counts[job.status]++;
    }
    return counts;
  });

  let statusPills = $derived([
    { label: 'All', value: '', count: jobs.length },
    { label: $t.translate?.jobs?.status_draft, value: 'DRAFT', count: statusCounts.DRAFT },
    { label: $t.translate?.jobs?.status_ready, value: 'READY', count: statusCounts.READY },
    { label: $t.translate?.jobs?.status_running, value: 'RUNNING', count: statusCounts.RUNNING },
    { label: $t.translate?.jobs?.status_completed, value: 'COMPLETED', count: statusCounts.COMPLETED },
    { label: $t.translate?.jobs?.status_failed, value: 'FAILED', count: statusCounts.FAILED },
  ]);

  onMount(() => {
    loadJobs();
  });

  /** @returns {Promise<void>} */
  async function loadJobs() {
    isLoading = true;
    uxState = 'loading';
    error = null;
    try {
      const result = await fetchJobs({ page: currentPage, page_size: pageSize, status: statusFilter || undefined });
      jobs = Array.isArray(result) ? result : (result?.results || result?.items || []);
      uxState = jobs.length === 0 ? 'empty' : 'populated';
    } catch (err) {
      error = err?.message || $t.translate?.jobs?.load_failed;
      uxState = 'error';
    } finally {
      isLoading = false;
    }
  }

  /** @param {string} status */
  function filterByStatus(status) {
    statusFilter = status;
    currentPage = 1;
    loadJobs();
  }

  /** @param {string} jobId */
  function navigateToConfig(jobId) {
    goto(`/translate/${jobId}`);
  }

  function navigateToCreate() {
    goto('/translate/new');
  }

  /** @param {string} jobId */
  async function handleDuplicate(jobId) {
    try {
      const result = await duplicateJob(jobId);
      addToast(`${_('translate.jobs.job_duplicated').replace('{name}', result.name)}`, 'success');
      loadJobs();
    } catch (err) {
      addToast(err?.message || _('translate.jobs.duplicate_failed'), 'error');
    }
  }

  /** @param {string} jobId */
  async function handleDelete(jobId) {
    try {
      await deleteJob(jobId);
      addToast(_('translate.jobs.job_deleted'), 'success');
      showDeleteConfirm = null;
      loadJobs();
    } catch (err) {
      addToast(err?.message || _('translate.jobs.delete_failed'), 'error');
      showDeleteConfirm = null;
    }
  }

  /** @param {string} status */
  function getStatusBadgeClass(status) {
    const map = {
      DRAFT: 'bg-gray-100 text-gray-700',
      READY: 'bg-blue-100 text-blue-700',
      RUNNING: 'bg-yellow-100 text-yellow-700',
      COMPLETED: 'bg-green-100 text-green-700',
      FAILED: 'bg-red-100 text-red-700',
      CANCELLED: 'bg-gray-100 text-gray-500',
    };
    return map[status] || 'bg-gray-100 text-gray-700';
  }
</script>

<div class="container mx-auto px-4 py-6">
  <div class="flex items-center justify-between mb-6">
    <div>
      <h1 class="text-2xl font-bold text-gray-900">{$t.translate?.jobs?.title}</h1>
      <p class="text-sm text-gray-500 mt-1">
        {$t.translate?.jobs?.subtitle}
      </p>
    </div>
    <button
      onclick={navigateToCreate}
      class="inline-flex items-center px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-hover transition-colors"
    >
      <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4" />
      </svg>
      {$t.translate?.jobs?.new_job}
    </button>
  </div>

  <!-- Flow hint -->
  <div class="bg-blue-50 border border-blue-100 rounded-lg p-3 mb-4 flex items-start gap-2">
    <svg class="w-5 h-5 text-blue-500 shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
      <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
    </svg>
    <p class="text-sm text-blue-700">{$t.translate?.jobs?.jobs_flow_hint || ''}</p>
  </div>

  <!-- Filter Pills -->
  <div class="flex flex-wrap gap-2 mb-4">
    {#each statusPills as pill}
      <button
        onclick={() => filterByStatus(pill.value)}
        class="px-3 py-1.5 text-sm rounded-full border transition-colors
          {statusFilter === pill.value
            ? 'bg-primary-light border-blue-300 text-blue-700'
            : 'bg-white border-gray-200 text-gray-600 hover:border-gray-300'}"
      >
        {pill.label}
        <span class="ml-1 text-xs opacity-70">({pill.count})</span>
      </button>
    {/each}
  </div>

  <!-- Loading State -->
  {#if isLoading}
    <div class="space-y-3">
      {#each Array(5) as _}
        <div class="h-20 bg-gray-100 rounded-lg animate-pulse" />
      {/each}
    </div>

  <!-- Error State -->
  {:else if uxState === 'error'}
    <div class="bg-destructive-light border border-destructive-light rounded-lg p-6 text-center">
      <p class="text-red-700 mb-3">{error || $t.translate?.jobs?.an_error_occurred}</p>
      <button
        onclick={loadJobs}
        class="px-4 py-2 bg-destructive text-white rounded-lg hover:bg-destructive-hover transition-colors"
      >
        {$t.translate?.common?.retry}
      </button>
    </div>

  <!-- Empty State -->
  {:else if uxState === 'empty'}
    <div class="bg-gray-50 border border-dashed border-gray-300 rounded-lg p-12 text-center">
      <svg class="w-16 h-16 mx-auto text-gray-300 mb-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
      </svg>
      {#if statusFilter}
        <p class="text-gray-500 mb-2">{$t.translate?.jobs?.no_jobs_filtered.replace('{status}', statusFilter)}</p>
        <button
          onclick={() => filterByStatus('')}
          class="text-primary hover:text-primary-hover text-sm"
        >
          {$t.translate?.jobs?.clear_filter}
        </button>
      {:else}
        <p class="text-gray-500 mb-4">{$t.translate?.jobs?.no_jobs}</p>
        <button
          onclick={navigateToCreate}
          class="px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-hover transition-colors"
        >
          {$t.translate?.jobs?.create_job}
        </button>
      {/if}
    </div>

  <!-- Populated State -->
  {:else if uxState === 'populated'}
    <div class="grid gap-4">
      {#each jobs as job}
        <div
          onclick={() => navigateToConfig(job.id)}
          class="bg-white border border-gray-200 rounded-lg p-4 hover:shadow-md hover:border-gray-300 transition-all cursor-pointer"
        >
          <div class="flex items-start justify-between">
            <div class="flex-1 min-w-0">
              <div class="flex items-center gap-3 mb-1">
                <h3 class="text-lg font-semibold text-gray-900 truncate">{job.name}</h3>
                <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {getStatusBadgeClass(job.status)}">
                  {job.status}
                </span>
              </div>
              {#if job.description}
                <p class="text-sm text-gray-500 truncate mb-2">{job.description}</p>
              {/if}
              <div class="flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-gray-400">
                {#if job.source_dialect && job.target_dialect}
                  <span>{job.source_dialect} &rarr; {job.target_dialect}</span>
                {/if}
				{#if job.target_languages?.length > 0}
				  <div class="flex gap-1 flex-wrap">
				    {#each job.target_languages as lang}
				      <span class="inline-flex px-1.5 py-0.5 text-xs rounded bg-blue-100 text-blue-700 font-medium">{lang}</span>
				    {/each}
				  </div>
				{:else if job.target_language}
				  <span class="inline-flex px-1.5 py-0.5 text-xs rounded bg-blue-100 text-blue-700 font-medium">{job.target_language}</span>
				{/if}
                {#if job.translation_column}
                  <span>{$t.translate?.jobs?.column_label.replace('{column}', job.translation_column)}</span>
                {/if}
                {#if job.created_by}
                  <span>{$t.translate?.jobs?.by_label.replace('{by}', job.created_by)}</span>
                {/if}
                {#if job.updated_at}
                  <span>{$t.translate?.jobs?.updated_label.replace('{date}', new Date(job.updated_at).toLocaleDateString())}</span>
                {/if}
              </div>
            </div>
            <div class="flex items-center gap-2 ml-4" onclick={(e) => e.stopPropagation()}>
              <button
                onclick={() => handleDuplicate(job.id)}
                class="p-2 text-gray-400 hover:text-blue-600 rounded-lg hover:bg-blue-50 transition-colors"
                title={$t.translate?.jobs?.duplicate}
              >
                <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="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
                </svg>
              </button>
              {#if showDeleteConfirm === job.id}
                <div class="flex items-center gap-1">
                  <button
                    onclick={() => handleDelete(job.id)}
                    class="px-2 py-1 text-xs bg-destructive text-white rounded hover:bg-destructive-hover"
                  >
                    {$t.translate?.jobs?.confirm_delete}
                    </button>
                    <button
                      onclick={() => (showDeleteConfirm = null)}
                      class="px-2 py-1 text-xs bg-gray-200 text-gray-700 rounded hover:bg-gray-300"
                    >
                      {$t.translate?.jobs?.cancel_delete}
                    </button>
                </div>
              {:else}
                <button
                  onclick={() => (showDeleteConfirm = job.id)}
                  class="p-2 text-gray-400 hover:text-red-600 rounded-lg hover:bg-red-50 transition-colors"
                  title={$t.translate?.common?.delete}
                >
                  <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="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
                  </svg>
                </button>
              {/if}
            </div>
          </div>
        </div>
      {/each}
    </div>
  {/if}
</div>

<!-- #endregion TranslateJobList -->
