<!-- #region CompiledSQLPreview [C:3] [TYPE Component] [SEMANTICS dataset, review, sql-preview, compilation, readiness] -->
<!-- @BRIEF Component component: lib/components/dataset-review/CompiledSQLPreview.svelte -->
<!-- @LAYER UI -->
<!-- @SEMANTICS: dataset-review, compiled-sql-preview, superset-preview, stale-state, diagnostics -->
<!-- @PURPOSE: Present the exact Superset-generated compiled SQL preview, expose readiness or staleness clearly, and preserve readable recovery paths when preview generation fails. -->
<!-- @LAYER UI -->
<!-- @RELATION BINDS_TO ->[EXT:frontend:api_module] -->
<!-- @RELATION BINDS_TO ->[DatasetReviewWorkspace] -->
<!-- @PRE: Session id is available and preview state comes from the current ownership-scoped session detail payload. -->
<!-- @POST: Users can distinguish missing, pending, ready, stale, and error preview states and can trigger only Superset-backed preview generation. -->
<!-- @SIDE_EFFECT: Requests preview generation through dataset orchestration APIs and updates route shell preview state when Superset responds. -->
<!-- @DATA_CONTRACT: Input -> Dataset review preview payload { sessionId, preview, previewState }; Output -> onupdated({ preview, preview_state }) route-shell refresh payload and onjump({ target }) recovery navigation signal. -->
<!-- @UX_STATE: Missing -> Prompt the user to generate a Superset preview before launch. -->
<!-- @UX_STATE: Pending -> Show generation-in-progress feedback without fabricating SQL. -->
<!-- @UX_STATE: Ready -> Render read-only SQL preview that is explicitly labeled as compiled by Superset. -->
<!-- @UX_STATE: Stale -> Mark the existing preview as outdated after mapping/input changes until regenerated. -->
<!-- @UX_STATE: Error -> Show readable Superset compilation diagnostics and preserve remediation action. -->
<!-- @UX_FEEDBACK: Preview refresh updates status pill, timestamps, and inline generation feedback. -->
<!-- @UX_RECOVERY: Users can retry preview generation and jump back to mapping review when diagnostics point to execution-input issues. -->
<!-- @UX_REACTIVITY: Uses $props, $state, and $derived only; no legacy reactive syntax. -->
<script lang="ts">
  import { t } from "$lib/i18n/index.svelte.js";
  import { requestDatasetReviewApi } from "$lib/api/datasetReview.js";

  let {
    sessionId = "",
    preview = null,
    previewState = "",
    disabled = false,
    sessionVersion = null,
    onupdated = () => {},
    onjump = () => {},
    onaskai = () => {},
  } = $props();

  let localStatus = $state("");
  let localMessage = $state("");
  let previewRequestedAt = $state(0);
  let lastExplicitRequestAt = $state(0);

  const PREVIEW_REGEN_DEBOUNCE_MS = 1200;

  const effectiveState = $derived(resolvePreviewState());
  const compiledBySuperset = $derived(String(preview?.compiled_by || "") === "superset");
  const hasSql = $derived(Boolean(String(preview?.compiled_sql || "").trim()));
  const previewTimestamp = $derived(preview?.compiled_at || preview?.created_at || "");
  const isReadOnlySnapshot = $derived(
    effectiveState === "stale" || effectiveState === "pending" || effectiveState === "failed",
  );

  function resolvePreviewState() {
    const explicit = String(previewState || "").trim();
    if (explicit) {
      return explicit;
    }

    const status = String(preview?.preview_status || "").trim();
    if (status === "ready" || status === "pending" || status === "failed" || status === "stale") {
      return status;
    }

    if (preview?.error_code || preview?.error_details) {
      return "failed";
    }

    return "missing";
  }

  function getStateLabel(state) {
    return $t.dataset_review?.preview?.state?.[state] || state;
  }

  function getStateTone(state) {
    if (state === "ready") {
      return "bg-emerald-100 text-emerald-700";
    }
    if (state === "stale") {
      return "bg-amber-100 text-amber-700";
    }
    if (state === "failed") {
      return "bg-red-100 text-red-700";
    }
    if (state === "pending") {
      return "bg-blue-100 text-blue-700";
    }
    return "bg-slate-100 text-slate-700";
  }

  function getCompilerLabel() {
    if (compiledBySuperset) {
      return $t.dataset_review?.preview?.compiled_by_superset;
    }
    return $t.dataset_review?.preview?.compiled_source_unknown;
  }

  function getPreviewBodyText() {
    if (effectiveState === "pending") {
      return $t.dataset_review?.preview?.pending_body;
    }
    if (effectiveState === "stale") {
      return $t.dataset_review?.preview?.stale_body;
    }
    if (effectiveState === "failed") {
      return $t.dataset_review?.preview?.error_body;
    }
    if (effectiveState === "missing") {
      return $t.dataset_review?.preview?.missing_body;
    }
    return $t.dataset_review?.preview?.ready_body;
  }

  function buildPreviewTechnicalDetails() {
    return [preview?.error_code, preview?.error_details].filter(Boolean).join("\n\n");
  }

  const previewTechnicalDetails = $derived(buildPreviewTechnicalDetails());
  const previewGenerationState = $derived(
    localStatus === "saving" ? "debouncing" : effectiveState === "stale" ? "stale" : effectiveState,
  );

  async function requestPreview() {
    if (!sessionId || disabled || localStatus === "saving") {
      return;
    }

    const now = Date.now();
    if (lastExplicitRequestAt && now - lastExplicitRequestAt < PREVIEW_REGEN_DEBOUNCE_MS) {
      localStatus = "error";
      localMessage =
        $t.dataset_review?.preview?.messages?.generate_debounced ||
        "Preview regeneration was requested very recently. Finish rapid edits, then explicitly regenerate once more.";
      return;
    }

    localStatus = "saving";
    localMessage = "";
    lastExplicitRequestAt = now;

    try {
      previewRequestedAt = Date.now();
      const response = await requestDatasetReviewApi(
        `/dataset-orchestration/sessions/${sessionId}/preview`,
        "POST",
        null,
        sessionVersion,
      );
      const nextPreview = response?.preview || response;
      onupdated({
        preview: nextPreview,
        preview_state: nextPreview?.preview_status || response?.preview_status || "pending",
      });
      localStatus = "success";
      localMessage = $t.dataset_review?.preview?.messages?.generated;
    } catch (error) {
      localStatus = "error";
      localMessage =
        (Number(error?.status) === 409
          ? error?.message ||
            "This session changed before preview generation completed. Reload and generate a fresh Superset preview."
          : error?.message) ||
        $t.dataset_review?.preview?.messages?.generate_failed ||
        $t.common?.error;
    }
  }

  function jumpToMapping() {
    onjump({ target: "mapping" });
  }

  function askAiAboutPreview() {
    onaskai({
      target: "preview",
      section: "preview",
      label: preview?.preview_id || "sql-preview",
      prompt:
        previewTechnicalDetails ||
        preview?.compiled_sql ||
        `Explain preview state ${effectiveState} and recommend the next safe action.`,
      preview,
    });
  }
</script>

<section id="sql-preview" class="rounded-2xl border border-slate-200 bg-white p-5 shadow-sm">
  <div class="flex flex-col gap-3 md:flex-row md:items-start md:justify-between">
    <div>
      <p class="text-xs font-semibold uppercase tracking-wide text-slate-500">
        {$t.dataset_review?.preview?.eyebrow}
      </p>
      <h2 class="text-xl font-semibold text-slate-900">
        {$t.dataset_review?.preview?.title}
      </h2>
      <p class="mt-1 max-w-3xl text-sm text-slate-600">
        {$t.dataset_review?.preview?.description}
      </p>
    </div>

    <div class="flex flex-wrap items-center gap-2">
      <span class={`rounded-full px-3 py-1 text-xs font-medium ${getStateTone(effectiveState)}`}>
        {$t.dataset_review?.preview?.state_label}: {getStateLabel(effectiveState)}
      </span>
      <button
        type="button"
            class="inline-flex items-center justify-center rounded-xl bg-primary px-4 py-2 text-sm font-medium text-white transition hover:bg-primary-hover disabled:cursor-not-allowed disabled:bg-slate-300"
        onclick={requestPreview}
        disabled={disabled || localStatus === "saving"}
      >
        {localStatus === "saving"
          ? $t.dataset_review?.preview?.generate_loading
          : $t.dataset_review?.preview?.generate_action}
      </button>
      <button
        type="button"
        class="inline-flex items-center justify-center rounded-xl border border-violet-300 bg-violet-50 px-4 py-2 text-sm font-medium text-violet-700 transition hover:bg-violet-100 disabled:cursor-not-allowed disabled:opacity-50"
        onclick={askAiAboutPreview}
        disabled={disabled}
      >
        {$t.dataset_review?.assistant?.ask_ai_action || "✨ Ask AI"}
      </button>
    </div>
  </div>

  <div
    class={`mt-5 rounded-xl border px-4 py-4 text-sm ${
      effectiveState === "failed"
        ? "border-destructive-light bg-destructive-light text-red-700"
        : effectiveState === "stale"
          ? "border-amber-200 bg-amber-50 text-amber-800"
          : effectiveState === "pending"
            ? "border-primary-ring bg-primary-light text-primary"
            : "border-slate-200 bg-slate-50 text-slate-700"
    }`}
  >
    {getPreviewBodyText()}
  </div>

  {#if isReadOnlySnapshot}
    <div class="mt-3 rounded-xl border border-slate-200 bg-slate-50 px-4 py-3 text-xs text-slate-600">
      Текущее состояние preview рассматривайте как read-only snapshot. Для launch требуется актуальный статус <span class="font-semibold">ready</span>.
    </div>
  {/if}

  {#if previewGenerationState === "debouncing"}
    <div class="mt-3 rounded-xl border border-primary-ring bg-primary-light px-4 py-3 text-xs text-primary">
      Preview regeneration requested. Rapid mapping changes keep launch blocked until the current Superset-side preview finishes and returns <span class="font-semibold">ready</span>.
    </div>
  {/if}

  {#if previewRequestedAt}
    <div class="mt-3 text-xs text-slate-500">
      Last regeneration request: {new Date(previewRequestedAt).toLocaleTimeString()}
    </div>
  {/if}

  {#if preview}
    <div class="mt-4 flex flex-wrap gap-2 text-xs text-slate-600">
      <span class="rounded-full bg-slate-100 px-2 py-1">
        {$t.dataset_review?.preview?.compiler_label}: {getCompilerLabel()}
      </span>
      <span class="rounded-full bg-slate-100 px-2 py-1">
        {$t.dataset_review?.preview?.fingerprint_label}: {preview.preview_fingerprint}
      </span>
      {#if previewTimestamp}
        <span class="rounded-full bg-slate-100 px-2 py-1">
          {$t.dataset_review?.preview?.compiled_at_label}: {previewTimestamp}
        </span>
      {/if}
    </div>
  {/if}

  {#if effectiveState === "ready" && hasSql}
    <div class="mt-5 overflow-hidden rounded-2xl border border-slate-200 bg-slate-950">
      <div class="flex items-center justify-between border-b border-slate-800 px-4 py-3">
        <div class="text-sm font-medium text-slate-100">
          {$t.dataset_review?.preview?.sql_block_title}
        </div>
        <div class="text-xs text-slate-400">
          {$t.dataset_review?.preview?.compiled_truth_note}
        </div>
      </div>
      <pre class="overflow-x-auto px-4 py-4 text-sm leading-6 text-slate-100"><code>{preview.compiled_sql}</code></pre>
    </div>
  {:else if effectiveState === "failed"}
    {#if previewTechnicalDetails}
      <div class="mt-5 overflow-hidden rounded-2xl border border-destructive-light bg-red-950">
        <div class="border-b border-red-900 px-4 py-3 text-sm font-medium text-red-100">
          {$t.dataset_review?.preview?.error_details_title || "Compilation details"}
        </div>
        <pre class="overflow-x-auto px-4 py-4 text-sm leading-6 text-red-100"><code>{previewTechnicalDetails}</code></pre>
      </div>
    {/if}
    <div class="mt-5 flex flex-wrap gap-2">
      <button
        type="button"
        class="inline-flex items-center justify-center rounded-xl border border-slate-300 px-4 py-2 text-sm font-medium text-slate-700 transition hover:bg-slate-50"
        onclick={jumpToMapping}
      >
        {$t.dataset_review?.preview?.go_to_mapping_action}
      </button>
    </div>
  {:else if effectiveState === "stale"}
    <div class="mt-5 rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-xs text-amber-800">
      Inputs changed after the last trusted preview. Rapid mapping updates keep this snapshot stale until you explicitly regenerate a fresh Superset preview from this panel.
    </div>
    <div class="mt-5 flex flex-wrap gap-2">
      <button
        type="button"
        class="inline-flex items-center justify-center rounded-xl border border-slate-300 px-4 py-2 text-sm font-medium text-slate-700 transition hover:bg-slate-50"
        onclick={jumpToMapping}
      >
        {$t.dataset_review?.preview?.review_inputs_action}
      </button>
    </div>
  {/if}

  {#if localMessage}
    <div
      class={`mt-4 rounded-xl px-3 py-3 text-sm ${
        localStatus === "error"
          ? "border border-destructive-light bg-destructive-light text-red-700"
          : "border border-emerald-200 bg-emerald-50 text-emerald-800"
      }`}
    >
      {localMessage}
    </div>
  {/if}
</section>

<!-- #endregion CompiledSQLPreview -->
