<!-- #region ValidationFindingsPanel [C:3] [TYPE Component] [SEMANTICS dataset, review, findings, severity, readiness] -->
<!-- @BRIEF Component component: lib/components/dataset-review/ValidationFindingsPanel.svelte -->
<!-- @LAYER UI -->
<!-- @SEMANTICS: dataset-review, findings, severity, readiness, actionability -->
<!-- @PURPOSE: Present validation findings grouped by severity with explicit resolution and actionability signals. -->
<!-- @LAYER UI -->
<!-- @RELATION BINDS_TO ->[DatasetReviewWorkspace] -->
<!-- @UX_STATE: Blocking -> Blocking findings are visually dominant and block launch flow. -->
<!-- @UX_STATE: Warning -> Warnings remain visible with explicit approval or defer actions. -->
<!-- @UX_STATE: Informational -> Low-priority findings are collapsed or secondary. -->
<!-- @UX_FEEDBACK: Resolving or approving an item updates readiness state immediately. -->
<!-- @UX_RECOVERY: Users can jump from a finding directly to the relevant remediation area. -->
<!-- @UX_REACTIVITY: Uses $props and $derived only; no legacy reactive syntax. -->

<script lang="ts">
  import { t } from "$lib/i18n/index.svelte.js";

  let {
    findings = [],
    recommendedAction = "",
    focusTarget = null,
    onjump = () => {},
    onaskai = () => {},
  } = $props();

  const groupedFindings = $derived(groupFindingsBySeverity(findings || []));
  const blockingFindings = $derived(groupedFindings.blocking);
  const warningFindings = $derived(groupedFindings.warning);
  const informationalFindings = $derived(groupedFindings.informational);
  const totalFindings = $derived(
    blockingFindings.length + warningFindings.length + informationalFindings.length,
  );
  const unresolvedBlockingCount = $derived(
    blockingFindings.filter(
      (finding) =>
        String(finding?.resolution_state || "open") !== "resolved" &&
        String(finding?.resolution_state || "open") !== "approved",
    ).length,
  );

  function groupFindingsBySeverity(items) {
    return (items || []).reduce(
      (accumulator, finding) => {
        const severity = String(finding?.severity || "informational");
        if (severity === "blocking") {
          accumulator.blocking.push(finding);
          return accumulator;
        }
        if (severity === "warning") {
          accumulator.warning.push(finding);
          return accumulator;
        }
        accumulator.informational.push(finding);
        return accumulator;
      },
      { blocking: [], warning: [], informational: [] },
    );
  }

  function buildTargetFromFinding(finding) {
    const area = String(finding?.area || "");
    if (area === "source_intake") return "intake";
    if (area === "dataset_profile") return "summary";
    if (area === "semantic_enrichment") return "semantics";
    if (area === "clarification") return "clarification";
    if (area === "filter_recovery") return "filters";
    if (area === "template_mapping") return "mappings";
    if (area === "compiled_preview") return "preview";
    if (area === "launch") return "launch";
    return "summary";
  }

  function jumpToFindingTarget(finding) {
    onjump({
      target: buildTargetFromFinding(finding),
      finding,
    });
  }

  function getResolutionLabel(resolutionState) {
    const normalized = String(resolutionState || "open");
    return $t.dataset_review?.findings?.resolution?.[normalized] || normalized;
  }

  function getAreaLabel(area) {
    const normalized = String(area || "dataset_profile");
    return $t.dataset_review?.findings?.areas?.[normalized] || normalized;
  }

  function getRecommendedActionLabel(action) {
    const normalized = String(action || "");
    return $t.dataset_review?.workspace?.actions?.[normalized] || normalized;
  }

  function getFindingMessage(finding) {
    return String(finding?.message || "").trim();
  }

  function getFindingTechnicalReference(finding) {
    return String(finding?.caused_by_ref || "").trim();
  }

  function getFindingResolutionNote(finding) {
    return String(finding?.resolution_note || "").trim();
  }

  function isFindingFocused(finding) {
    const target = String(focusTarget?.target || "");
    return target === `finding:${finding?.finding_id}` || target === buildTargetFromFinding(finding);
  }

  function getFindingFocusTarget(finding) {
    return `finding:${finding?.finding_id}`;
  }

  function askAiAboutFinding(finding) {
    onaskai({
      target: `finding:${finding?.finding_id}`,
      section: buildTargetFromFinding(finding),
      label: finding?.title || finding?.code,
      prompt:
        getFindingMessage(finding) || getFindingResolutionNote(finding) || getFindingTechnicalReference(finding),
      finding,
    });
  }

  function improveFindingGuidance(finding) {
    onaskai({
      target: `finding:${finding?.finding_id}`,
      section: buildTargetFromFinding(finding),
      label: finding?.title || finding?.code,
      prompt: `Improve remediation guidance for finding ${finding?.title || finding?.code}. Preserve explicit approval and launch gates while keeping the explanation grounded in the current review session.`,
      mode: "improve",
      finding,
    });
  }

  function getContextActionLabel(finding) {
    const target = buildTargetFromFinding(finding);
    if (target === "mappings") {
      return $t.dataset_review?.assistant?.improve_action || "✨ Improve";
    }
    return $t.dataset_review?.assistant?.ask_ai_action || "✨ Ask AI";
  }
</script>

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

    <div class="rounded-xl border border-slate-200 bg-slate-50 px-3 py-2 text-right">
      <div class="text-xs uppercase tracking-wide text-slate-500">
        {$t.dataset_review?.findings?.next_action_label}
      </div>
      <div class="mt-1 text-sm font-medium text-slate-900">
        {getRecommendedActionLabel(recommendedAction)}
      </div>
    </div>
  </div>

  {#if unresolvedBlockingCount > 0}
    <div class="mt-4 rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-800">
      Обнаружены незакрытые launch-блокеры: {unresolvedBlockingCount}. Продолжать review можно, но запуск останется недоступен.
    </div>
  {/if}

  {#if totalFindings === 0}
    <div class="mt-5 rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-4 text-sm text-emerald-800">
      {$t.dataset_review?.findings?.empty}
    </div>
  {:else}
    <div class="mt-5 space-y-4">
      <section class="rounded-2xl border border-red-200 bg-red-50 p-4">
        <div class="flex items-center gap-3">
          <h3 class="text-sm font-semibold text-slate-900">
            {$t.dataset_review?.findings?.blocking_title}
          </h3>
          <span class="rounded-full bg-red-100 px-2.5 py-1 text-xs font-medium text-red-700">
            {blockingFindings.length}
          </span>
        </div>

        {#if blockingFindings.length === 0}
          <p class="mt-3 text-sm text-slate-600">
            {$t.dataset_review?.findings?.blocking_empty}
          </p>
        {:else}
          <div class="mt-3 space-y-3">
            {#each blockingFindings as finding}
              <article
                class={`rounded-xl border p-4 shadow-sm transition ${
                isFindingFocused(finding)
                  ? "border-violet-300 bg-violet-50 shadow-[0_0_0_3px_rgba(139,92,246,0.15)]"
                  : "border-white/70 bg-white/80"
              }`}
                data-focus-target={getFindingFocusTarget(finding)}
              >
                <div class="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
                  <div class="min-w-0 flex-1">
                    <div class="flex flex-wrap items-center gap-2">
                      <h4 class="text-sm font-semibold text-slate-900">
                        {finding.title}
                      </h4>
                      <span class="rounded-full bg-slate-100 px-2 py-0.5 text-xs font-medium text-slate-600">
                        {finding.code}
                      </span>
                      <span class="rounded-full bg-slate-100 px-2 py-0.5 text-xs text-slate-600">
                        {getAreaLabel(finding.area)}
                      </span>
                    </div>

                    <p class="mt-2 text-sm leading-6 text-slate-700">
                      {finding.message}
                    </p>

                    <div class="mt-3 flex flex-wrap gap-2 text-xs">
                      <span class="rounded-full bg-slate-100 px-2 py-1 text-slate-600">
                        {$t.dataset_review?.findings?.resolution_label}:
                        {getResolutionLabel(finding.resolution_state)}
                      </span>

                      {#if finding.caused_by_ref}
                        <span class="rounded-full bg-slate-100 px-2 py-1 text-slate-600">
                          {$t.dataset_review?.findings?.reference_label}:
                          {finding.caused_by_ref}
                        </span>
                      {/if}
                    </div>

                    {#if finding.resolution_note}
                      <p class="mt-2 text-xs text-slate-500">{finding.resolution_note}</p>
                    {/if}
                  </div>

                  <div class="flex shrink-0 items-center gap-2">
                    <button
                      type="button"
                      class="inline-flex items-center justify-center rounded-lg border border-violet-300 bg-violet-50 px-3 py-2 text-sm font-medium text-violet-700 transition hover:bg-violet-100"
                      onclick={() => askAiAboutFinding(finding)}
                    >
                      {$t.dataset_review?.assistant?.ask_ai_action || "✨ Ask AI"}
                    </button>
                    <button
                      type="button"
                      class="inline-flex items-center justify-center rounded-lg border border-violet-300 bg-white px-3 py-2 text-sm font-medium text-violet-700 transition hover:bg-violet-50"
                      onclick={() => improveFindingGuidance(finding)}
                    >
                      {$t.dataset_review?.assistant?.improve_action || "✨ Improve"}
                    </button>
                    <button
                      type="button"
                      class="inline-flex items-center justify-center rounded-lg border border-slate-300 px-3 py-2 text-sm font-medium text-slate-700 transition hover:bg-slate-100"
                      onclick={() => jumpToFindingTarget(finding)}
                    >
                      {$t.dataset_review?.findings?.jump_action}
                    </button>
                  </div>
                </div>
              </article>
            {/each}
          </div>
        {/if}
      </section>

      <section class="rounded-2xl border border-amber-200 bg-amber-50 p-4">
        <div class="flex items-center gap-3">
          <h3 class="text-sm font-semibold text-slate-900">
            {$t.dataset_review?.findings?.warning_title}
          </h3>
          <span class="rounded-full bg-amber-100 px-2.5 py-1 text-xs font-medium text-amber-700">
            {warningFindings.length}
          </span>
        </div>

        {#if warningFindings.length === 0}
          <p class="mt-3 text-sm text-slate-600">
            {$t.dataset_review?.findings?.warning_empty}
          </p>
        {:else}
          <div class="mt-3 space-y-3">
            {#each warningFindings as finding}
              <article
                class={`rounded-xl border p-4 shadow-sm transition ${
                isFindingFocused(finding)
                  ? "border-violet-300 bg-violet-50 shadow-[0_0_0_3px_rgba(139,92,246,0.15)]"
                  : "border-white/70 bg-white/80"
              }`}
                data-focus-target={getFindingFocusTarget(finding)}
              >
                <div class="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
                  <div class="min-w-0 flex-1">
                    <div class="flex flex-wrap items-center gap-2">
                      <h4 class="text-sm font-semibold text-slate-900">
                        {finding.title}
                      </h4>
                      <span class="rounded-full bg-slate-100 px-2 py-0.5 text-xs font-medium text-slate-600">
                        {finding.code}
                      </span>
                      <span class="rounded-full bg-slate-100 px-2 py-0.5 text-xs text-slate-600">
                        {getAreaLabel(finding.area)}
                      </span>
                    </div>

                    <p class="mt-2 text-sm leading-6 text-slate-700">
                      {finding.message}
                    </p>

                    <div class="mt-3 flex flex-wrap gap-2 text-xs">
                      <span class="rounded-full bg-slate-100 px-2 py-1 text-slate-600">
                        {$t.dataset_review?.findings?.resolution_label}:
                        {getResolutionLabel(finding.resolution_state)}
                      </span>

                      {#if finding.caused_by_ref}
                        <span class="rounded-full bg-slate-100 px-2 py-1 text-slate-600">
                          {$t.dataset_review?.findings?.reference_label}:
                          {finding.caused_by_ref}
                        </span>
                      {/if}
                    </div>

                    {#if finding.resolution_note}
                      <p class="mt-2 text-xs text-slate-500">{finding.resolution_note}</p>
                    {/if}
                  </div>

                  <div class="flex shrink-0 items-center gap-2">
                    <button
                      type="button"
                      class="inline-flex items-center justify-center rounded-lg border border-violet-300 bg-violet-50 px-3 py-2 text-sm font-medium text-violet-700 transition hover:bg-violet-100"
                      onclick={() => askAiAboutFinding(finding)}
                    >
                      {$t.dataset_review?.assistant?.ask_ai_action || "✨ Ask AI"}
                    </button>
                    <button
                      type="button"
                      class="inline-flex items-center justify-center rounded-lg border border-violet-300 bg-white px-3 py-2 text-sm font-medium text-violet-700 transition hover:bg-violet-50"
                      onclick={() => improveFindingGuidance(finding)}
                    >
                      {$t.dataset_review?.assistant?.improve_action || "✨ Improve"}
                    </button>
                    <button
                      type="button"
                      class="inline-flex items-center justify-center rounded-lg border border-slate-300 px-3 py-2 text-sm font-medium text-slate-700 transition hover:bg-slate-100"
                      onclick={() => jumpToFindingTarget(finding)}
                    >
                      {$t.dataset_review?.findings?.jump_action}
                    </button>
                  </div>
                </div>
              </article>
            {/each}
          </div>
        {/if}
      </section>

      <section class="rounded-2xl border border-slate-200 bg-slate-50 p-4">
        <div class="flex items-center gap-3">
          <h3 class="text-sm font-semibold text-slate-900">
            {$t.dataset_review?.findings?.informational_title}
          </h3>
          <span class="rounded-full bg-slate-200 px-2.5 py-1 text-xs font-medium text-slate-700">
            {informationalFindings.length}
          </span>
        </div>

        {#if informationalFindings.length === 0}
          <p class="mt-3 text-sm text-slate-600">
            {$t.dataset_review?.findings?.informational_empty}
          </p>
        {:else}
          <div class="mt-3 space-y-3">
            {#each informationalFindings as finding}
              <article
                class={`rounded-xl border p-4 shadow-sm transition ${
                isFindingFocused(finding)
                  ? "border-violet-300 bg-violet-50 shadow-[0_0_0_3px_rgba(139,92,246,0.15)]"
                  : "border-white/70 bg-white/80"
              }`}
                data-focus-target={getFindingFocusTarget(finding)}
              >
                <div class="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
                  <div class="min-w-0 flex-1">
                    <div class="flex flex-wrap items-center gap-2">
                      <h4 class="text-sm font-semibold text-slate-900">
                        {finding.title}
                      </h4>
                      <span class="rounded-full bg-slate-100 px-2 py-0.5 text-xs font-medium text-slate-600">
                        {finding.code}
                      </span>
                      <span class="rounded-full bg-slate-100 px-2 py-0.5 text-xs text-slate-600">
                        {getAreaLabel(finding.area)}
                      </span>
                    </div>

                    <p class="mt-2 text-sm leading-6 text-slate-700">
                      {finding.message}
                    </p>

                    <div class="mt-3 flex flex-wrap gap-2 text-xs">
                      <span class="rounded-full bg-slate-100 px-2 py-1 text-slate-600">
                        {$t.dataset_review?.findings?.resolution_label}:
                        {getResolutionLabel(finding.resolution_state)}
                      </span>

                      {#if finding.caused_by_ref}
                        <span class="rounded-full bg-slate-100 px-2 py-1 text-slate-600">
                          {$t.dataset_review?.findings?.reference_label}:
                          {finding.caused_by_ref}
                        </span>
                      {/if}
                    </div>

                    {#if finding.resolution_note}
                      <p class="mt-2 text-xs text-slate-500">{finding.resolution_note}</p>
                    {/if}
                  </div>

                  <div class="flex shrink-0 items-center gap-2">
                    <button
                      type="button"
                      class="inline-flex items-center justify-center rounded-lg border border-violet-300 bg-violet-50 px-3 py-2 text-sm font-medium text-violet-700 transition hover:bg-violet-100"
                      onclick={() => askAiAboutFinding(finding)}
                    >
                      {$t.dataset_review?.assistant?.ask_ai_action || "✨ Ask AI"}
                    </button>
                    <button
                      type="button"
                      class="inline-flex items-center justify-center rounded-lg border border-violet-300 bg-white px-3 py-2 text-sm font-medium text-violet-700 transition hover:bg-violet-50"
                      onclick={() => improveFindingGuidance(finding)}
                    >
                      {$t.dataset_review?.assistant?.improve_action || "✨ Improve"}
                    </button>
                    <button
                      type="button"
                      class="inline-flex items-center justify-center rounded-lg border border-slate-300 px-3 py-2 text-sm font-medium text-slate-700 transition hover:bg-slate-100"
                      onclick={() => jumpToFindingTarget(finding)}
                    >
                      {$t.dataset_review?.findings?.jump_action}
                    </button>
                  </div>
                </div>
              </article>
            {/each}
          </div>
        {/if}
      </section>
    </div>
  {/if}
</div>

<!-- #endregion ValidationFindingsPanel -->
