<!-- #region DashboardGrid [C:3] [TYPE Component] [SEMANTICS dashboard, grid, pagination, sort, filter] -->
<!-- @ingroup Dashboard -->
<!-- @BRIEF Displays a grid of dashboards with selection and pagination. -->
<!-- @LAYER UI -->
<!--
@UX_STATE: Loading -> Default

@SEMANTICS: dashboard, grid, selection, pagination
@PURPOSE:   Displays a grid of dashboards with selection and pagination.
@LAYER     Component
@RELATION  USED_BY -> [frontend/src/routes/migration/+page.svelte]

@INVARIANT: Selected IDs must be a subset of available dashboards.
-->

<script lang="ts">
import { SvelteSet, SvelteDate } from "svelte/reactivity";
  // [SECTION: IMPORTS]
  import type { DashboardMetadata } from "../../types/dashboard";
  import { t } from '$lib/i18n/index.svelte.js';
  import { Button, Input } from "$lib/ui";
  import GitManager from "$lib/components/git/GitManager.svelte";
  import { api } from "$lib/api";
  import { addToast as toast } from "$lib/toasts.svelte.js";
  // [/SECTION]

  // [SECTION: PROPS]
  let { dashboards = [], selectedIds = [], environmentId = "ss1" } = $props();

  // [/SECTION]

  // [SECTION: STATE]
  let filterText = $state("");
  let currentPage = $state(0);
  let pageSize = $state(20);
  let sortColumn: keyof DashboardMetadata = $state("title");
  let sortDirection: "asc" | "desc" = $state("asc");
  // [/SECTION]

  // [SECTION: UI STATE]
  let showGitManager = $state(false);
  let gitDashboardId: string | null = $state(null);
  let gitDashboardTitle = $state("");
  let validatingIds = new SvelteSet<number>();
  // [/SECTION]

  // #region handleValidate:Function [TYPE Function]
// @ingroup Dashboard
  /**
   * @purpose Triggers dashboard validation task.
   */
  async function handleValidate(dashboard: DashboardMetadata) {
    if (validatingIds.has(dashboard.id)) return;

    validatingIds.add(dashboard.id);

    try {
      await api.postApi("/tasks", {
        plugin_id: "llm_dashboard_validation",
        params: {
          dashboard_id: dashboard.id.toString(),
          environment_id: environmentId,
        },
      });

      toast("Validation task started", "success");
    } catch (e: any) {
      toast(e.message || "Validation failed to start", "error");
    } finally {
      validatingIds.delete(dashboard.id);
    }
  }
  // #endregion handleValidate:Function

  // [SECTION: DERIVED]
  let filteredDashboards = $derived(
    dashboards.filter((d) =>
      d.title.toLowerCase().includes(filterText.toLowerCase()),
    ),
  );

  let sortedDashboards = $derived(
    [...filteredDashboards].sort((a, b) => {
      let aVal = a[sortColumn];
      let bVal = b[sortColumn];
      if (sortColumn === "id") {
        aVal = Number(aVal);
        bVal = Number(bVal);
      }
      if (aVal < bVal) return sortDirection === "asc" ? -1 : 1;
      if (aVal > bVal) return sortDirection === "asc" ? 1 : -1;
      return 0;
    }),
  );

  let paginatedDashboards = $derived(
    sortedDashboards.slice(
      currentPage * pageSize,
      (currentPage + 1) * pageSize,
    ),
  );

  let totalPages = $derived(Math.ceil(sortedDashboards.length / pageSize));

  let allSelected = $derived(
    paginatedDashboards.length > 0 &&
      paginatedDashboards.every((d) => selectedIds.includes(d.id)),
  );
  let someSelected = $derived(
    paginatedDashboards.some((d) => selectedIds.includes(d.id)),
  );
  // [/SECTION]

  // #region handleSort:Function [TYPE Function]
// @ingroup Dashboard
  // @PURPOSE: Toggles sort direction or changes sort column.
  // @PRE: column name is provided.
  // @POST: sortColumn and sortDirection state updated.
  function handleSort(column: keyof DashboardMetadata) {
    if (sortColumn === column) {
      sortDirection = sortDirection === "asc" ? "desc" : "asc";
    } else {
      sortColumn = column;
      sortDirection = "asc";
    }
  }
  // #endregion handleSort:Function

  // #region handleSelectionChange:Function [TYPE Function]
// @ingroup Dashboard
  // @PURPOSE: Handles individual checkbox changes.
  // @PRE: dashboard ID and checked status provided.
  // @POST: selectedIds array updated.
  function handleSelectionChange(id: number, checked: boolean) {
    let newSelected = [...selectedIds];
    if (checked) {
      if (!newSelected.includes(id)) newSelected.push(id);
    } else {
      newSelected = newSelected.filter((sid) => sid !== id);
    }
    selectedIds = newSelected;
  }
  // #endregion handleSelectionChange:Function

  // #region handleSelectAll:Function [TYPE Function]
// @ingroup Dashboard
  // @PURPOSE: Handles select all checkbox.
  // @PRE: checked status provided.
  // @POST: selectedIds array updated for all paginated items.
  function handleSelectAll(checked: boolean) {
    let newSelected = [...selectedIds];
    if (checked) {
      paginatedDashboards.forEach((d) => {
        if (!newSelected.includes(d.id)) newSelected.push(d.id);
      });
    } else {
      paginatedDashboards.forEach((d) => {
        newSelected = newSelected.filter((sid) => sid !== d.id);
      });
    }
    selectedIds = newSelected;
  }
  // #endregion handleSelectAll:Function

  // #region goToPage:Function [TYPE Function]
// @ingroup Dashboard
  // @PURPOSE: Changes current page.
  // @PRE: page index is provided.
  // @POST: currentPage state updated if within valid range.
  function goToPage(page: number) {
    if (page >= 0 && page < totalPages) {
      currentPage = page;
    }
  }
  // #endregion goToPage:Function

  // #region openGit:Function [TYPE Function]
// @ingroup Dashboard
  /**
   * @purpose Opens the Git management modal for a dashboard.
   */
  function openGit(dashboard: DashboardMetadata) {
    gitDashboardId = String(dashboard.slug || dashboard.id);
    gitDashboardTitle = dashboard.title;
    showGitManager = true;
  }
  // #endregion openGit:Function
</script>

<!-- [SECTION: TEMPLATE] -->
<div class="dashboard-grid">
  <!-- Filter Input -->
  <div class="mb-6">
    <Input bind:value={filterText} placeholder={$t.dashboard.search} />
  </div>

  <!-- Grid/Table -->
  <div class="overflow-x-auto rounded-lg border border-border">
    <table class="min-w-full divide-y divide-border">
      <thead class="bg-surface-muted">
        <tr>
          <th class="px-6 py-3 text-left">
            <input
              type="checkbox"
              checked={allSelected}
              indeterminate={someSelected && !allSelected}
              onchange={(e) =>
                handleSelectAll((e.target as HTMLInputElement).checked)}
              class="h-4 w-4 text-primary border-border-strong rounded focus-visible:ring-primary-ring"
            />
          </th>
          <th
            class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider cursor-pointer hover:text-text transition-colors"
            onclick={() => handleSort("title")}
          >
            {$t.dashboard.title}
            {sortColumn === "title"
              ? sortDirection === "asc"
                ? "↑"
                : "↓"
              : ""}
          </th>
          <th
            class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider cursor-pointer hover:text-text transition-colors"
            onclick={() => handleSort("last_modified")}
          >
            {$t.dashboard.last_modified}
            {sortColumn === "last_modified"
              ? sortDirection === "asc"
                ? "↑"
                : "↓"
              : ""}
          </th>
          <th
            class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider cursor-pointer hover:text-text transition-colors"
            onclick={() => handleSort("status")}
          >
            {$t.dashboard.status}
            {sortColumn === "status"
              ? sortDirection === "asc"
                ? "↑"
                : "↓"
              : ""}
          </th>
          <th
            class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider"
            >{$t.dashboard.validation}</th
          >
          <th
            class="px-6 py-3 text-left text-xs font-medium text-text-muted uppercase tracking-wider"
            >{$t.dashboard.git}</th
          >
        </tr>
      </thead>
      <tbody class="bg-surface-card divide-y divide-border">
        {#each paginatedDashboards as dashboard (dashboard.id)}
          <tr class="hover:bg-surface-muted transition-colors">
            <td class="px-6 py-4 whitespace-nowrap">
              <input
                type="checkbox"
                checked={selectedIds.includes(dashboard.id)}
                onchange={(e) =>
                  handleSelectionChange(
                    dashboard.id,
                    (e.target as HTMLInputElement).checked,
                  )}
                class="h-4 w-4 text-primary border-border-strong rounded focus-visible:ring-primary-ring"
              />
            </td>
            <td
              class="px-6 py-4 whitespace-nowrap text-sm font-medium text-text"
              >{dashboard.title}</td
            >
            <td class="px-6 py-4 whitespace-nowrap text-sm text-text-muted"
              >{new SvelteDate(dashboard.last_modified).toLocaleDateString()}</td
            >
            <td class="px-6 py-4 whitespace-nowrap text-sm text-text-muted">
              <span
                class="px-2 py-1 text-xs font-medium rounded-full {dashboard.status ===
                'published'
                  ? 'bg-success-light text-success'
                  : 'bg-surface-muted text-text'}"
              >
                {dashboard.status}
              </span>
            </td>
            <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
              <Button
                variant="secondary"
                size="sm"
                onclick={() => handleValidate(dashboard)}
                disabled={validatingIds.has(dashboard.id)}
                class="text-info hover:text-info"
              >
                {validatingIds.has(dashboard.id) ? "Validating..." : "Validate"}
              </Button>
            </td>
            <td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
              <Button
                variant="ghost"
                size="sm"
                onclick={() => openGit(dashboard)}
                class="text-primary hover:text-primary"
              >
                {$t.git.manage}
              </Button>
            </td>
          </tr>
        {/each}
      </tbody>
    </table>
  </div>

  <!-- Pagination Controls -->
  <div class="flex items-center justify-between mt-6">
    <div class="text-sm text-text-muted">
      {($t.dashboard?.showing ?? '')
        .replace("{start}", (currentPage * pageSize + 1).toString())
        .replace(
          "{end}",
          Math.min(
            (currentPage + 1) * pageSize,
            sortedDashboards.length,
          ).toString(),
        )
        .replace("{total}", sortedDashboards.length.toString())}
    </div>
    <div class="flex gap-2">
      <Button
        variant="secondary"
        size="sm"
        disabled={currentPage === 0}
        onclick={() => goToPage(currentPage - 1)}
      >
        {$t.dashboard.previous}
      </Button>
      <Button
        variant="secondary"
        size="sm"
        disabled={currentPage >= totalPages - 1}
        onclick={() => goToPage(currentPage + 1)}
      >
        {$t.dashboard.next}
      </Button>
    </div>
  </div>
</div>

{#if showGitManager && gitDashboardId}
  <GitManager
    dashboardId={gitDashboardId}
    envId={environmentId}
    dashboardTitle={gitDashboardTitle}
    bind:show={showGitManager}
  />
{/if}

<!-- [/SECTION] -->

<!-- #endregion DashboardGrid -->
