<!-- #region ValidationTasksPage [C:3] [TYPE Page] [SEMANTICS validation,tasks,list,table] -->
<!-- @ingroup Routes -->
<!-- @BRIEF Validation tasks list page — renders ValidationTasksListModel state. -->
<!-- @LAYER Page -->
<!-- @RELATION BINDS_TO -> [ValidationTasksListModel] -->
<!-- @UX_STATE loading -> Skeleton table rows matching column layout -->
<!-- @UX_STATE loaded -> Data rows with all columns -->
<!-- @UX_STATE empty -> Centered empty card with CTA -->
<!-- @UX_STATE error -> Red banner with error and retry -->
<script lang="ts">
  import { onMount } from 'svelte';
  import { t } from '$lib/i18n/index.svelte.js';
  import { ValidationTasksListModel } from '$lib/models/ValidationTasksListModel.svelte';

  let { data } = $props();

  const m = new ValidationTasksListModel();
  m.initFromLoad(data);

  onMount(() => {
    return () => { m.destroy(); };
  });

  function formatSchedule(input: string | null | undefined): string {
    if (!input) return $t.validation?.manual || 'Manual';
    return input;
  }

  function formatTimestamp(ts: unknown): string {
    if (!ts) return '\u2014';
    try { return new Date(ts as string).toLocaleString(); }
    catch { return String(ts); }
  }

  function formatLastRunSummary(summary: { pass?: number; warn?: number; fail?: number } | null | undefined): string {
    if (!summary) return '\u2014';
    const parts: string[] = [];
    if (summary.pass) parts.push(`${summary.pass} PASS`);
    if (summary.warn) parts.push(`${summary.warn} WARN`);
    if (summary.fail) parts.push(`${summary.fail} FAIL`);
    return parts.join('\u2022') || '\u2014';
  }

  function getSummaryBadgeClass(summary: { fail?: number; warn?: number; pass?: number } | null | undefined): string {
    if (!summary) return 'bg-surface-muted text-text-muted';
    if (summary.fail && summary.fail > 0) return 'bg-destructive-light text-destructive';
    if (summary.warn && summary.warn > 0) return 'bg-warning-light text-warning';
    if (summary.pass && summary.pass > 0) return 'bg-success-light text-success';
    return 'bg-surface-muted text-text-muted';
  }

  function getEnvLabel(task: Record<string, unknown>): string {
    return String(task.environment_name || task.environment_id || '\u2014');
  }

  function pageBtnClass(p: number): string {
    const base = 'px-3 py-1.5 text-sm rounded-lg border transition-colors';
    if (p === m.currentPage) return `${base} bg-primary-light border-primary-ring text-primary`;
    return `${base} border-border text-text-muted hover:bg-surface-muted`;
  }
</script>

<div class="max-w-7xl mx-auto px-4 py-6">
  <!-- Header -->
  <div class="flex items-center justify-between mb-6">
    <h1 class="text-2xl font-bold text-text">{$t.validation?.title || 'Validation Tasks'}</h1>
    <button onclick={() => m.navToNew()} class="inline-flex items-center px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-hover transition-colors font-medium text-sm">
      <svg class="w-5 h-5 mr-1.5" 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.validation?.new_task || '+ New Task'}
    </button>
  </div>

  <!-- Search -->
  <div class="mb-4">
    <div class="relative max-w-sm">
      <svg class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-text-subtle" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" /></svg>
      <input type="text" placeholder={$t.common?.search || 'Search tasks...'} value={m.searchQuery} oninput={(e) => m.handleSearchInput((e.target as HTMLInputElement).value)} class="w-full pl-10 pr-4 py-2 border border-border-strong rounded-lg text-sm focus:ring-2 focus:ring-primary-ring focus:border-primary-ring outline-none" aria-label={$t.common?.search} />
    </div>
  </div>

  <!-- Error -->
  {#if m.error && !m.isLoading}
    <div class="bg-destructive-light border border-destructive-ring rounded-lg p-4 mb-6 flex items-center justify-between" role="alert">
      <div class="flex items-center gap-2 text-destructive">
        <svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
        <span class="text-sm">{m.error}</span>
      </div>
      <button onclick={() => m.loadTasks()} class="px-3 py-1.5 text-sm bg-destructive text-white rounded-lg hover:bg-destructive transition-colors">{$t.validation?.retry}</button>
    </div>
  {/if}

  <!-- Loading -->
  {#if m.isLoading}
    <div class="bg-surface-card border border-border rounded-lg overflow-hidden">
      <table class="min-w-full divide-y divide-border">
        <thead class="bg-surface-muted"><tr>
          <th class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.task_name}</th>
          <th class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.environment}</th>
          <th class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.schedule}</th>
          <th class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.last_run}</th>
          <th class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.status}</th>
          <th class="px-6 py-3 text-right text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.actions}</th>
        </tr></thead>
        <tbody class="bg-surface-card divide-y divide-border">
          {#each Array(5) as _, i (i)}<tr class="animate-pulse"><td class="px-6 py-4"><div class="h-4 w-40 bg-surface-muted rounded"></div></td><td class="px-6 py-4"><div class="h-4 w-24 bg-surface-muted rounded"></div></td><td class="px-6 py-4"><div class="h-4 w-20 bg-surface-muted rounded"></div></td><td class="px-6 py-4"><div class="h-4 w-32 bg-surface-muted rounded"></div></td><td class="px-6 py-4"><div class="h-5 w-14 bg-surface-muted rounded-full"></div></td><td class="px-6 py-4"><div class="h-4 w-24 bg-surface-muted rounded ml-auto"></div></td></tr>{/each}
        </tbody>
      </table>
    </div>

  <!-- Empty -->
  {:else if !m.error && m.tasks.length === 0}
    <div class="bg-surface-muted border border-dashed border-border-strong rounded-lg p-12 text-center">
      <svg class="w-16 h-16 mx-auto text-text-subtle 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>
      <p class="text-text-muted text-sm mb-1">{$t.validation?.no_tasks || 'No validation tasks yet'}</p>
      <p class="text-text-subtle text-sm mb-4">{$t.validation?.create_first || 'Create your first task'}</p>
      <button onclick={() => m.navToNew()} class="inline-flex items-center px-4 py-2 bg-primary text-white rounded-lg hover:bg-primary-hover transition-colors text-sm font-medium">{$t.validation?.new_task}</button>
    </div>

  <!-- Loaded: table -->
  {:else}
    <div class="bg-surface-card border border-border rounded-lg overflow-hidden shadow-sm">
      <div class="overflow-x-auto">
        <table class="min-w-full divide-y divide-border">
          <thead class="bg-surface-muted"><tr>
            <th class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.task_name}</th>
            <th class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.environment}</th>
            <th class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.schedule}</th>
            <th class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.last_run}</th>
            <th class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.status}</th>
            <th class="px-6 py-3 text-right text-xs font-medium text-text-muted uppercase tracking-wider">{$t.validation?.actions}</th>
          </tr></thead>
          <tbody class="bg-surface-card divide-y divide-border">
            {#each m.tasks as task (task.id)}
              <tr class="hover:bg-surface-muted transition-colors">
                <td class="px-6 py-4 whitespace-nowrap">
                  <button onclick={() => m.navToDetail(task.id)} class="text-sm font-medium text-primary hover:text-primary hover:underline text-left">{task.name || '\u2014'}</button>
                </td>
                <td class="px-6 py-4 whitespace-nowrap"><span class="text-sm text-text">{getEnvLabel(task)}</span></td>
                <td class="px-6 py-4 whitespace-nowrap">
                  {#if task.schedule}
                    <span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-primary-light text-primary">{formatSchedule((task as Record<string,unknown>).schedule_description as string || task.schedule)}</span>
                  {:else}
                    <span class="text-sm text-text-subtle">{$t.validation?.manual || 'Manual'}</span>
                  {/if}
                </td>
                <td class="px-6 py-4 whitespace-nowrap">
                  {#if task.last_run_at || task.last_run_summary}
                    <div class="flex flex-col gap-0.5">
                      {#if task.last_run_at}<span class="text-xs text-text-muted">{formatTimestamp(task.last_run_at)}</span>{/if}
                      {#if task.last_run_summary}<span class="inline-flex items-center px-2 py-0.5 rounded text-xs font-medium {getSummaryBadgeClass(task.last_run_summary as { pass?: number; warn?: number; fail?: number } | null)}">{formatLastRunSummary(task.last_run_summary as { pass?: number; warn?: number; fail?: number } | null)}</span>{/if}
                    </div>
                  {:else}<span class="text-sm text-text-subtle">\u2014</span>{/if}
                </td>
                <td class="px-6 py-4 whitespace-nowrap">
                  <button onclick={() => m.handleToggleStatus(task)} class="relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus:outline-none focus:ring-2 focus:ring-primary-ring focus:ring-offset-2" class:bg-primary={task.is_active !== false} class:bg-surface-muted={task.is_active === false} role="switch" aria-checked={task.is_active !== false}>
                    <span class="inline-block h-4 w-4 transform rounded-full bg-surface-card transition-transform" class:translate-x-6={task.is_active !== false} class:translate-x-1={task.is_active === false}></span>
                  </button>
                </td>
                <td class="px-6 py-4 whitespace-nowrap text-right">
                  <div class="flex items-center justify-end gap-1">
                    <button onclick={() => m.handleRunNow(task.id)} disabled={m.runningTasks[task.id]} class="p-2 text-text-subtle hover:text-primary rounded-lg hover:bg-primary-light transition-colors disabled:opacity-40 disabled:cursor-not-allowed" title={$t.validation?.run_now}>
                      {#if m.runningTasks[task.id]}
                        <svg class="w-4 h-4 animate-spin" fill="none" viewBox="0 0 24 24"><circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"/><path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z"/></svg>
                      {:else}
                        <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="M14.752 11.168l-3.197-2.132A1 1 0 0010 9.87v4.263a1 1 0 001.555.832l3.197-2.132a1 1 0 000-1.664z"/><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/></svg>
                      {/if}
                    </button>
                    <button onclick={() => m.navToEdit(task.id)} class="p-2 text-text-subtle hover:text-primary rounded-lg hover:bg-primary-light transition-colors" title={$t.validation?.edit}>
                      <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="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/></svg>
                    </button>
                    {#if m.deleteConfirmId === task.id}
                      <div class="flex items-center gap-1">
                        <button onclick={() => m.handleDelete(task.id)} class="px-2 py-1 text-xs bg-destructive text-white rounded hover:bg-destructive transition-colors">{$t.validation?.confirm_delete}</button>
                        <button onclick={() => { m.deleteConfirmId = null; }} class="px-2 py-1 text-xs bg-surface-muted text-text rounded hover:bg-surface-muted transition-colors">{$t.common?.cancel}</button>
                      </div>
                    {:else}
                      <button onclick={() => { m.deleteConfirmId = task.id; }} class="p-2 text-text-subtle hover:text-destructive rounded-lg hover:bg-destructive-light transition-colors" title={$t.validation?.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>
                </td>
              </tr>
            {/each}
          </tbody>
        </table>
      </div>
    </div>

    <!-- Pagination -->
    {#if m.totalPages > 1}
      <div class="flex items-center justify-between mt-4">
        <p class="text-sm text-text-muted">{($t.validation?.showing || 'Showing {count} of {total}').replace('{count}', String(m.tasks.length)).replace('{total}', String(m.total))}</p>
        <nav class="flex items-center gap-1" aria-label="Pagination">
          <button onclick={() => m.goToPage(m.currentPage - 1)} disabled={m.currentPage <= 1} class="px-3 py-1.5 text-sm border border-border rounded-lg disabled:opacity-40 disabled:cursor-not-allowed hover:bg-surface-muted text-text-muted transition-colors">{$t.validation?.previous}</button>
          {#each Array.from({ length: Math.min(m.totalPages, 7) }, (_, i) => { if (m.totalPages <= 7) return i + 1; const half = 3; const start = Math.max(1, m.currentPage - half); const end = Math.min(m.totalPages, start + 6); const adj = Math.max(1, end - 6); return adj + i; }) as p (p)}
            <button onclick={() => m.goToPage(p)} class={pageBtnClass(p)}>{p}</button>
          {/each}
          <button onclick={() => m.goToPage(m.currentPage + 1)} disabled={m.currentPage >= m.totalPages} class="px-3 py-1.5 text-sm border border-border rounded-lg disabled:opacity-40 disabled:cursor-not-allowed hover:bg-surface-muted text-text-muted transition-colors">{$t.validation?.next}</button>
        </nav>
      </div>
    {/if}
  {/if}
</div>
<!-- #endregion ValidationTasksPage -->
