<!-- #region DatasetReviewWorkspaceEntry [C:3] [TYPE Page] [SEMANTICS sveltekit, dataset, review, session, source-intake] -->
<!-- @BRIEF Entry route for Dataset Review Workspace — start a new resumable review session or navigate to existing sessions. -->
<!-- @LAYER Page -->
<!-- @RELATION DEPENDS_ON -> [SourceIntakePanel] -->
<!-- @RELATION BINDS_TO -> [EXT:frontend:environmentContextStore] -->
<!-- @RELATION CALLS -> [EXT:frontend:api_module] -->
<!-- @UX_STATE Empty -> Source intake form for Superset link or dataset reference. -->
<!-- @UX_STATE ResumeList -> Existing resumable sessions listed with direct navigation. -->
<!-- @UX_STATE Submitting -> Controls disabled during session creation. -->
<!-- @UX_STATE Error -> Inline error shown while keeping intake editable. -->
<!-- @UX_RECOVERY User can correct invalid input and retry without losing environment selection. -->
<script lang="ts">
  import { goto } from "$app/navigation";
  import SourceIntakePanel from "$lib/components/dataset-review/SourceIntakePanel.svelte";
  import { t } from "$lib/i18n/index.svelte.js";
  import { api } from "$lib/api.js";
  import { requestDatasetReviewApi } from "$lib/api/datasetReview.js";
  import {
    environmentContextStore,
    initializeEnvironmentContext,
  } from "$lib/stores/environmentContext.svelte.js";

  let isBootstrapping = $state(true);
  let isSubmitting = $state(false);
  let submitError = $state("");
  let intakeAcknowledgment = $state("");
  let sessions = $state([]);
  let sessionsLoading = $state(false);
  let sessionsError = $state("");
  let searchQuery = $state("");
  let currentPage = $state(1);
  let pageSize = $state(5);
  let totalSessions = $state(0);
  let deleteConfirmSessionId = $state(null);

  const environments = $derived(environmentContextStore.value?.environments || []);
  const selectedEnvironmentId = $derived(
    environmentContextStore.value?.selectedEnvId || "",
  );
  const hasExistingSessions = $derived(sessions.length > 0);
  const totalPages = $derived(totalSessions > 0 ? Math.ceil(totalSessions / pageSize) : 1);
  
  const filteredSessions = $derived(() => {
    if (!searchQuery.trim()) return sessions;
    const query = searchQuery.toLowerCase();
    return sessions.filter(s =>
      (s.session_id?.toLowerCase().includes(query)) ||
      (s.dataset_ref?.toLowerCase().includes(query)) ||
      (s.environment_id?.toLowerCase().includes(query))
    );
  });

  function buildSessionUrl(sessionId) {
    return `/datasets/review/${encodeURIComponent(String(sessionId))}`;
  }

  function formatDateTime(value) {
    if (!value) {
      return $t.common?.not_available || "N/A";
    }
    const parsed = new Date(value);
    if (Number.isNaN(parsed.getTime())) {
      return String(value);
    }
    return parsed.toLocaleString();
  }

  function getSessionMetaValue(session, key, fallback = "") {
    const value = session?.[key];
    return value ? String(value) : fallback;
  }

  async function loadExistingSessions() {
    sessionsLoading = true;
    sessionsError = "";
    try {
      const params = new URLSearchParams();
      params.append("page", String(currentPage));
      params.append("page_size", String(pageSize));
      if (searchQuery.trim()) {
        params.append("search", searchQuery.trim());
      }
      const response = await api.fetchApi(`/dataset-orchestration/sessions?${params.toString()}`);
      sessions = Array.isArray(response?.items) ? response.items : [];
      totalSessions = response?.total || sessions.length;
    } catch (error) {
      sessions = [];
      totalSessions = 0;
      sessionsError = error?.message || $t.dataset_review?.workspace_entry?.resume_load_failed || $t.common?.error;
    } finally {
      sessionsLoading = false;
    }
  }

  async function deleteSession(sessionId, hardDelete = false) {
    const sessionSummary = sessions.find((item) => item.session_id === sessionId) || null;
    const sessionVersion = sessionSummary?.session_version ?? sessionSummary?.version ?? null;
    try {
      await requestDatasetReviewApi(
        `/dataset-orchestration/sessions/${sessionId}?hard_delete=${hardDelete}`,
        "DELETE",
        null,
        sessionVersion,
      );
      deleteConfirmSessionId = null;
      if (sessions.length === 1 && currentPage > 1) {
        currentPage = currentPage - 1;
      }
      await loadExistingSessions();
    } catch (error) {
      sessionsError = error?.message || $t.common?.error;
    }
  }

  function goToPage(page) {
    if (page >= 1 && page <= totalPages) {
      currentPage = page;
      loadExistingSessions();
    }
  }

  function handleSearch() {
    currentPage = 1;
    loadExistingSessions();
  }

  function truncateText(text, maxLength = 30) {
    if (!text || text.length <= maxLength) return text || "";
    return text.slice(0, maxLength) + "...";
  }

  function getReadinessTone(readinessState) {
    if (readinessState === "run_ready") return "bg-emerald-100 text-emerald-700";
    if (readinessState === "partially_ready" || readinessState === "recovery_required" || readinessState === "compiled_preview_ready") {
      return "bg-amber-100 text-amber-800";
    }
    if (readinessState === "importing") return "bg-blue-100 text-blue-700";
    return "bg-slate-100 text-slate-700";
  }

  function getReadinessHint(readinessState) {
    if (readinessState === "recovery_required") return "Контекст восстановлен частично: перед запуском проверьте фильтры, маппинг и превью SQL.";
    if (readinessState === "partially_ready") return "Сессия продолжает быть полезной, но запуск остаётся заблокирован до обновления превью и закрытия блокеров.";
    if (readinessState === "compiled_preview_ready") return "Превью собрано. Проверьте approvals и launch-блокеры перед запуском.";
    if (readinessState === "run_ready") return "Сессия готова к запуску после финальной проверки.";
    return "Откройте сессию, чтобы увидеть следующий рекомендуемый шаг.";
  }

  async function bootstrap() {
    isBootstrapping = true;
    try {
      await initializeEnvironmentContext();
      await loadExistingSessions();
    } finally {
      isBootstrapping = false;
    }
  }

  async function handleSourceSubmit(payload) {
    isSubmitting = true;
    submitError = "";
    intakeAcknowledgment = payload.source_kind === "superset_link"
      ? $t.dataset_review?.source?.recognized_link_hint
      : $t.dataset_review?.source?.dataset_selection_acknowledged;
    try {
      const summary = await api.postApi("/dataset-orchestration/sessions", payload);
      if (!summary?.session_id) {
        throw new Error($t.dataset_review?.source?.submit_failed || "Failed to start review");
      }
      await goto(buildSessionUrl(summary.session_id));
    } catch (error) {
      submitError = error?.message || $t.dataset_review?.source?.submit_failed || $t.common?.error;
      throw error;
    } finally {
      isSubmitting = false;
    }
  }

  bootstrap();
</script>

<div class="mx-auto w-full max-w-7xl space-y-5 px-4 py-6">
  <div class="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
    <div>
      <p class="text-xs font-semibold uppercase tracking-[0.2em] text-blue-700">
        {$t.dataset_review?.workspace?.eyebrow}
      </p>
      <h1 class="text-2xl font-bold text-slate-900">
        {$t.dataset_review?.workspace?.title}
      </h1>
      <p class="mt-1 max-w-3xl text-sm text-slate-600">
        {$t.dataset_review?.workspace?.description}
      </p>
    </div>
    <div class="flex flex-wrap items-center gap-2">
      <span class="rounded-full bg-slate-100 px-3 py-1 text-xs font-medium text-slate-700">
        {$t.dataset_review?.workspace?.state_label}: {$t.dataset_review?.workspace?.state?.empty || "Empty"}
      </span>
      {#if hasExistingSessions}
        <span class="rounded-full bg-primary-light px-3 py-1 text-xs font-medium text-blue-700">
          {$t.dataset_review?.workspace_entry?.resume_available_badge}: {sessions.length}
        </span>
      {/if}
    </div>
  </div>

  {#if isBootstrapping}
    <div class="rounded-2xl border border-slate-200 bg-white p-6 text-sm text-slate-500 shadow-sm">
      {$t.dataset_review?.workspace?.loading}
    </div>
  {:else}
    <div class="grid gap-5 xl:grid-cols-[minmax(0,1fr)_minmax(0,1.2fr)]">
      <section class="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
        <div class="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
          <div>
            <p class="text-xs font-semibold uppercase tracking-wide text-blue-700">
              {$t.dataset_review?.workspace_entry?.resume_eyebrow}
            </p>
            <h2 class="text-xl font-semibold text-slate-900">
              {$t.dataset_review?.workspace_entry?.resume_title}
            </h2>
            <p class="mt-1 max-w-2xl text-sm text-slate-600">
              {$t.dataset_review?.workspace_entry?.resume_description}
            </p>
          </div>
          <button
            type="button"
            class="inline-flex items-center justify-center rounded-xl border border-slate-300 bg-white px-4 py-2 text-sm font-medium text-slate-700 transition hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-50"
            onclick={loadExistingSessions}
            disabled={sessionsLoading}
          >
            {#if sessionsLoading}
              <svg class="mr-2 h-4 w-4 animate-spin" viewBox="0 0 24 24" fill="none">
                <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
              </svg>
              {$t.dataset_review?.workspace_entry?.resume_loading}
            {:else}
              <svg class="mr-2 h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
              </svg>
              {$t.common?.refresh}
            {/if}
          </button>
        </div>
        <!-- Search and session listing continues... -->
      </section>
      <div class="space-y-5">
        <SourceIntakePanel
          environments={environments}
          selectedEnvironmentId={selectedEnvironmentId}
          submitting={isSubmitting}
          acknowledgment={intakeAcknowledgment}
          onsubmit={handleSourceSubmit}
        />
        {#if submitError}
          <div class="rounded-2xl border border-destructive-light bg-destructive-light px-4 py-4 text-sm text-red-700">
            {submitError}
          </div>
        {/if}
      </div>
    </div>
  {/if}
</div>
<!-- #endregion DatasetReviewWorkspaceEntry -->
