<script lang="ts">
  import type { BriefingBlock, Citation } from '$lib/types/claim';
  import Claim from './Claim.svelte';
  import Cite from './Cite.svelte';
  import SectionHead from './SectionHead.svelte';

  interface Props {
    blocks: BriefingBlock[];
    citations: Record<string, Citation>;
    streaming?: boolean;
    replayKey?: number;
  }

  let { blocks, citations: cites, streaming = false, replayKey = 0 }: Props = $props();

  let visibleCount = $state(blocks.length);
  let prefersReducedMotion = $state(false);

  $effect(() => {
    if (typeof window === 'undefined') return;
    prefersReducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
  });

  $effect(() => {
    // re-run when replayKey changes
    void replayKey;
    if (!streaming) {
      visibleCount = blocks.length;
      return;
    }
    if (prefersReducedMotion) {
      visibleCount = blocks.length;
      return;
    }
    visibleCount = 0;
    let i = 0;
    let timer: ReturnType<typeof setTimeout>;
    const tick = () => {
      i++;
      visibleCount = i;
      if (i < blocks.length) {
        timer = setTimeout(tick, i < 2 ? 280 : 420);
      }
    };
    timer = setTimeout(tick, 240);
    return () => clearTimeout(timer);
  });
</script>

<div
  class="briefing-prose"
  role="log"
  aria-live="polite"
  aria-atomic="false"
  aria-label="Streaming flood-exposure briefing"
>
  {#each blocks.slice(0, visibleCount) as block, i (i)}
    {#if block.kind === 'status'}
      <!-- briefing-status HTML comes from either:
           (a) the static sample fixture (lib/data/sample.ts, trusted), or
           (b) the parser's preamble fallback (currently disabled).
           No user-supplied input flows here.
        -->
      <!-- eslint-disable-next-line svelte/no-at-html-tags -->
      <div class="briefing-status briefing-fade-in">{@html block.html}</div>
    {:else if block.kind === 'head'}
      <div class="briefing-fade-in">
        <SectionHead n={block.n} label={block.label} tier={block.tier} title={block.title} />
      </div>
    {:else}
      <p class="briefing-para briefing-fade-in">
        {#each block.parts as part, j (j)}
          {#if part.tier}
            <Claim tier={part.tier}>{part.text}</Claim>{#if part.cite && cites[part.cite]}<Cite c={cites[part.cite]} />{/if}
          {:else}
            <span>{part.text}</span>
          {/if}
        {/each}
      </p>
    {/if}
  {/each}
</div>

<style>
  /* Each newly-revealed block fades in over 320ms instead of the
     blinking-cursor "typing" cadence. Citation-grounded paragraphs
     should land with authority, not chatter. Respects
     prefers-reduced-motion via the global rule in tokens.css. */
  .briefing-fade-in {
    animation: briefing-fade 320ms ease-out both;
  }
  @keyframes briefing-fade {
    from { opacity: 0; transform: translateY(2px); }
    to   { opacity: 1; transform: translateY(0); }
  }
</style>
