<!-- #region LaunchConfirmationPanel [C:3] [TYPE Component] [SEMANTICS dataset, review, launch, confirmation, gates] -->
<!-- @BRIEF Component component: lib/components/dataset-review/LaunchConfirmationPanel.svelte -->
<!-- @LAYER UI -->
<!-- @SEMANTICS: dataset-review, launch-confirmation, run-gates, sql-lab, audited-execution -->
<!-- @PURPOSE: Summarize final execution context, surface launch blockers explicitly, and confirm only a gate-complete SQL Lab launch request. -->
<!-- @LAYER UI -->
<!-- @RELATION BINDS_TO ->[EXT:frontend:api_module] -->
<!-- @RELATION BINDS_TO ->[DatasetReviewWorkspace] -->
<!-- @PRE: Session detail, mappings, findings, preview state, and latest run context belong to the current ownership-scoped session payload. -->
<!-- @POST: Users can see why launch is blocked or confirm a run-ready launch with explicit SQL Lab handoff evidence. -->
<!-- @SIDE_EFFECT: Submits the launch request through dataset orchestration APIs and updates the workspace with returned run context state. -->
<!-- @DATA_CONTRACT: Input -> Dataset review launch payload { sessionId, session, findings[], mappings[], preview, previewState, latestRunContext }; Output -> onupdated({ launch_result, preview_state }) workspace refresh payload and onjump({ target }) remediation navigation signal. -->
<!-- @UX_STATE: Blocked -> Explicit blocker list prevents hidden bypass of approvals, readiness, or preview-fingerprint gates. -->
<!-- @UX_STATE: Ready -> Final reviewed run context is visible before confirmation. -->
<!-- @UX_STATE: Submitted -> SQL Lab handoff and audited run context reference are shown after launch request succeeds. -->
<!-- @UX_FEEDBACK: Launch button, blocker list, and success state all reflect current gate truth instead of generic confirmation copy. -->
<!-- @UX_RECOVERY: Blocked launch state provides jump paths back to mapping review, preview generation, or validation remediation. -->
<!-- @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 = "",
    session = null,
    findings = [],
    mappings = [],
    preview = null,
    previewState = "",
    latestRunContext = null,
    disabled = false,
    sessionVersion = null,
    onupdated = () => {},
    onjump = () => {},
  } = $props();

  let launchStatus = $state("");
  let launchMessage = $state("");
  let launchResult = $state(null);

  const activeRunContext = $derived(launchResult?.run_context || latestRunContext || null);
  const effectivePreviewState = $derived(
    String(previewState || preview?.preview_status || "missing"),
  );
  const approvedMappingsCount = $derived(
    (mappings || []).filter((mapping) => mapping.approval_state === "approved").length,
  );
  const launchBlockers = $derived(buildLaunchBlockers());
  const panelState = $derived(
    activeRunContext ? "Submitted" : launchBlockers.length > 0 ? "Blocked" : "Ready",
  );
  const launchButtonLabel = $derived(
    launchStatus === "saving"
      ? $t.dataset_review?.launch?.launch_loading
      : $t.dataset_review?.launch?.launch_action,
  );

  function buildLaunchBlockers() {
    const blockers = [];

    for (const finding of findings || []) {
      if (
        finding.severity === "blocking" &&
        finding.resolution_state !== "resolved" &&
        finding.resolution_state !== "approved"
      ) {
        blockers.push({
          label:
            $t.dataset_review?.launch?.blockers?.blocking_finding ||
            "Blocking findings remain unresolved",
          detail: finding.title || finding.message || finding.code,
          target: "summary",
        });
      }
    }

    for (const mapping of mappings || []) {
      if (mapping.requires_explicit_approval && mapping.approval_state !== "approved") {
        blockers.push({
          label:
            $t.dataset_review?.launch?.blockers?.mapping_approval_required ||
            "Mapping approval is still required",
          detail: mapping.transformation_note || mapping.mapping_id,
          target: "mapping",
        });
      }
    }

    if (effectivePreviewState === "missing") {
      blockers.push({
        label:
          $t.dataset_review?.launch?.blockers?.preview_missing ||
          "Superset preview is required before launch",
        detail: "",
        target: "sql-preview",
      });
    } else if (effectivePreviewState === "pending") {
      blockers.push({
        label:
          $t.dataset_review?.launch?.blockers?.preview_pending ||
          "Preview generation is still in progress",
        detail: "",
        target: "sql-preview",
      });
    } else if (effectivePreviewState === "stale") {
      blockers.push({
        label:
          $t.dataset_review?.launch?.blockers?.preview_stale ||
          "Preview no longer matches the current execution inputs",
        detail: "",
        target: "sql-preview",
      });
    } else if (effectivePreviewState === "failed") {
      blockers.push({
        label:
          $t.dataset_review?.launch?.blockers?.preview_failed ||
          "Preview failed and launch remains blocked",
        detail: preview?.error_details || preview?.error_code || "",
        target: "sql-preview",
      });
    }

    if (!activeRunContext && String(session?.readiness_state || "") !== "run_ready") {
      blockers.push({
        label:
          $t.dataset_review?.launch?.blockers?.readiness_not_run_ready ||
          "Session is not yet in run-ready state",
        detail: session?.readiness_state || "",
        target: "next-action",
      });
    }

    if (!activeRunContext && !preview?.preview_fingerprint) {
      blockers.push({
        label:
          $t.dataset_review?.launch?.blockers?.preview_fingerprint_missing ||
          "Preview fingerprint is missing, so launch cannot be trusted",
        detail: "",
        target: "sql-preview",
      });
    }

    return blockers;
  }

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

  function getStateClass(state) {
    if (state === "Submitted") {
      return "bg-emerald-100 text-emerald-700";
    }
    if (state === "Ready") {
      return "bg-blue-100 text-blue-700";
    }
    return "bg-red-100 text-red-700";
  }

  function jumpTo(target) {
    onjump({ target });
  }

  async function confirmLaunch() {
    if (!sessionId || disabled || panelState !== "Ready" || launchStatus === "saving") {
      return;
    }

    launchStatus = "saving";
    launchMessage = "";

    try {
      const result = await requestDatasetReviewApi(
        `/dataset-orchestration/sessions/${sessionId}/launch`,
        "POST",
        null,
        sessionVersion,
      );
      launchResult = result;
      launchStatus = "success";
      launchMessage = $t.dataset_review?.launch?.messages?.launch_started;
      onupdated({
        launch_result: result,
        preview_state: "unchanged",
      });
    } catch (error) {
      launchStatus = "error";
      launchMessage =
        (Number(error?.status) === 409
          ? error?.message ||
            "This session changed before launch confirmation completed. Reload the latest reviewed state and confirm again."
          : error?.message) ||
        $t.dataset_review?.launch?.messages?.launch_failed ||
        $t.common?.error;
    }
  }
</script>

<section id="launch" 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?.launch?.eyebrow}
      </p>
      <h2 class="text-xl font-semibold text-slate-900">
        {$t.dataset_review?.launch?.title}
      </h2>
      <p class="mt-1 max-w-3xl text-sm text-slate-600">
        {$t.dataset_review?.launch?.description}
      </p>
    </div>

    <span class={`rounded-full px-3 py-1 text-xs font-medium ${getStateClass(panelState)}`}>
      {$t.dataset_review?.launch?.state_label}: {getStateLabel(panelState)}
    </span>
  </div>

  {#if panelState === "Blocked"}
    <div class="mt-5 rounded-xl border border-destructive-light bg-destructive-light p-4">
      <h3 class="text-sm font-semibold text-red-800">
        {$t.dataset_review?.launch?.blocked_title}
      </h3>
      <p class="mt-1 text-sm text-red-700">
        {$t.dataset_review?.launch?.blocked_body}
      </p>

      <div class="mt-4 space-y-3">
        {#each launchBlockers as blocker}
          <div class="rounded-xl border border-destructive-light bg-white p-3">
            <div class="text-sm font-medium leading-6 text-slate-900 break-words [overflow-wrap:anywhere]">
              {blocker.label}
            </div>
            {#if blocker.detail}
              <div class="mt-2 max-h-28 overflow-auto rounded-lg border border-slate-200 bg-slate-50 px-3 py-2">
                <div
                  data-testid="launch-blocker-detail"
                  class="text-xs leading-5 text-slate-600 whitespace-pre-wrap break-words [overflow-wrap:anywhere]"
                >
                  {blocker.detail}
                </div>
              </div>
            {/if}
            <button
              type="button"
              class="mt-3 inline-flex items-center justify-center rounded-lg border border-slate-300 bg-white px-3 py-2 text-sm font-medium text-slate-700 transition hover:bg-slate-50"
              onclick={() => jumpTo(blocker.target)}
            >
              {$t.dataset_review?.launch?.resolve_action}
            </button>
          </div>
        {/each}
      </div>
    </div>
  {/if}

  {#if panelState === "Ready"}
    <div class="mt-5 space-y-4">
      <div class="rounded-xl border border-slate-200 bg-slate-50 p-4">
        <div class="grid gap-3 md:grid-cols-2">
          <div>
            <div class="text-xs uppercase tracking-wide text-slate-500">
              {$t.dataset_review?.launch?.dataset_ref_label}
            </div>
            <div class="mt-1 text-sm font-medium text-slate-900 break-words [overflow-wrap:anywhere]">
              {session?.dataset_ref || ($t.common?.unknown || "unknown")}
            </div>
          </div>

          <div>
            <div class="text-xs uppercase tracking-wide text-slate-500">
              {$t.dataset_review?.launch?.readiness_label}
            </div>
            <div class="mt-1 text-sm font-medium text-slate-900">
              {session?.readiness_state || ($t.common?.unknown || "unknown")}
            </div>
          </div>

          <div>
            <div class="text-xs uppercase tracking-wide text-slate-500">
              {$t.dataset_review?.launch?.approved_mappings_label}
            </div>
            <div class="mt-1 text-sm font-medium text-slate-900">
              {approvedMappingsCount}
            </div>
          </div>

          <div>
            <div class="text-xs uppercase tracking-wide text-slate-500">
              {$t.dataset_review?.launch?.preview_fingerprint_label}
            </div>
            <div class="mt-1 break-all text-sm font-medium text-slate-900">
              {preview?.preview_fingerprint || ($t.common?.not_available || "N/A")}
            </div>
          </div>
        </div>
      </div>

      <div class="rounded-xl border border-slate-200 bg-slate-50 p-4">
        <h3 class="text-sm font-semibold text-slate-900">
          {$t.dataset_review?.launch?.sql_lab_target_title}
        </h3>
        <p class="mt-1 text-sm text-slate-600">
          {$t.dataset_review?.launch?.sql_lab_target_body}
        </p>
        <div class="mt-3 flex flex-wrap gap-2 text-xs text-slate-600">
          <span class="rounded-full bg-white px-2 py-1">
            {$t.dataset_review?.launch?.preview_status_label}: {preview?.preview_status}
          </span>
          <span class="rounded-full bg-white px-2 py-1">
            {$t.dataset_review?.launch?.compiled_by_label}: {preview?.compiled_by}
          </span>
        </div>
      </div>

      <button
        type="button"
        onclick={confirmLaunch}
        disabled={disabled || launchStatus === "saving"}
        class="inline-flex w-full items-center justify-center rounded-xl bg-primary px-4 py-3 text-sm font-medium text-white transition hover:bg-primary-hover disabled:cursor-not-allowed disabled:bg-slate-300"
      >
        {launchButtonLabel}
      </button>
    </div>
  {/if}

  {#if panelState === "Submitted"}
    <div class="mt-5 space-y-4 rounded-xl border border-emerald-200 bg-emerald-50 p-4">
      <div>
        <h3 class="text-sm font-semibold text-emerald-900">
          {$t.dataset_review?.launch?.submitted_title}
        </h3>
        <p class="mt-1 text-sm text-emerald-800">
          {$t.dataset_review?.launch?.submitted_body}
        </p>
      </div>

      <div class="grid gap-3 md:grid-cols-2">
        <div class="rounded-xl border border-emerald-200 bg-white p-3">
          <div class="text-xs uppercase tracking-wide text-slate-500">
            {$t.dataset_review?.launch?.run_context_label}
          </div>
          <div class="mt-1 break-all text-sm font-medium text-slate-900">
            {activeRunContext?.run_context_id}
          </div>
        </div>

        <div class="rounded-xl border border-emerald-200 bg-white p-3">
          <div class="text-xs uppercase tracking-wide text-slate-500">
            {$t.dataset_review?.launch?.sql_lab_session_label}
          </div>
          <div class="mt-1 break-all text-sm font-medium text-slate-900">
            {activeRunContext?.sql_lab_session_ref}
          </div>
        </div>

        <div class="rounded-xl border border-emerald-200 bg-white p-3">
          <div class="text-xs uppercase tracking-wide text-slate-500">
            {$t.dataset_review?.launch?.launch_status_label}
          </div>
          <div class="mt-1 text-sm font-medium text-slate-900">
            {activeRunContext?.launch_status}
          </div>
        </div>

        <div class="rounded-xl border border-emerald-200 bg-white p-3">
          <div class="text-xs uppercase tracking-wide text-slate-500">
            {$t.dataset_review?.launch?.preview_ref_label}
          </div>
          <div class="mt-1 break-all text-sm font-medium text-slate-900">
            {activeRunContext?.preview_id}
          </div>
        </div>
      </div>
    </div>
  {/if}

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

<!-- #endregion LaunchConfirmationPanel -->
