/* SEL.IA — SourceProcessor
   Step-driven ingestion visualization:
   - Progress advances in discrete steps (one per source, top to bottom).
   - At each step, exactly ONE source is "processing": a paper-document
     walks along its dashed circuit line toward the core, then shrinks
     before touching it ("being consumed").
   - The other sources sit as Pending or Done.
*/

const SP_PHASES = [
  "INGESTION INITIALIZATION",
  "FETCHING OFFICIAL SOURCES",
  "PARSING REGULATORY DOCUMENTS",
  "CROSS-REFERENCING ENTITIES",
  "INDEXING FOR DEEP SEARCH",
  "READY FOR QUERY",
];

const SP_SOURCES = [
  { id: "ANEEL", file: "REH_3421-2026_Revisao_Tarifaria.pdf",     ext: "pdf",  type: "Norma" },
  { id: "DOU",   file: "DOU_Secao1_Edicao_Extra_28-04.xml",       ext: "xml",  type: "Publicação" },
  { id: "SEI",   file: "SEI_48500.001234-2026-77_movs.json",      ext: "json", type: "Processo" },
  { id: "BDGD",  file: "BDGD_2026Q1_SECO_carga_residencial.csv",  ext: "csv",  type: "Geo" },
  { id: "Part.", file: "CP_089-2026_contribuicoes.zip",           ext: "zip",  type: "Consulta" },
  { id: "ANEEL", file: "Pauta_Sessao_Publica_12-04.docx",         ext: "docx", type: "Pauta" },
  { id: "SEI",   file: "Voto_Vista_Diretora_Agnes.pdf",           ext: "pdf",  type: "Voto" },
  { id: "DOU",   file: "Despacho_ANEEL_2118_2026.pdf",            ext: "pdf",  type: "Despacho" },
];

// Map each file row (top→bottom) to one of the 5 visual circuit lines (active sources only).
// Index: which NODE in NODES below should light up + show the moving doc.
const ROW_TO_NODE = [0, 1, 2, 3, 4, 0, 2, 1]; // ANEEL,DOU,SEI,BDGD,PART, then ANEEL,SEI,DOU again

const STEP_MS = 1600; // duration of one source ingestion
const PAUSE_MS = 250; // small pause between steps

const SourceProcessor = () => {
  const [step, setStep] = React.useState(0);   // 0..N (when step===N, all done; auto-resets)
  const [tProg, setTProg] = React.useState(0); // 0..1 progress within the current step

  React.useEffect(() => {
    let raf, t0;
    const total = STEP_MS + PAUSE_MS;
    const loop = (now) => {
      if (!t0) t0 = now;
      const elapsed = now - t0;
      const cycle = SP_SOURCES.length * total + 1200; // small final hold
      const inCycle = elapsed % cycle;
      const idx = Math.min(SP_SOURCES.length, Math.floor(inCycle / total));
      const within = (inCycle - idx * total) / STEP_MS; // 0..>1
      setStep(idx);
      setTProg(Math.max(0, Math.min(1, within)));
      raf = requestAnimationFrame(loop);
    };
    raf = requestAnimationFrame(loop);
    return () => cancelAnimationFrame(raf);
  }, []);

  // Discrete progress: each completed step adds (100/N) %.
  // Add the in-step fraction (eased) so the bar fills smoothly during the active step.
  const N = SP_SOURCES.length;
  const stepPct = 100 / N;
  const ease = (x) => 1 - Math.pow(1 - x, 3);
  const progress = Math.min(100, step * stepPct + (step < N ? ease(tProg) * stepPct : 0));

  const phaseIdx = Math.min(SP_PHASES.length - 1, Math.floor((progress / 100) * SP_PHASES.length));

  const stateOf = (i) => {
    if (i < step) return "done";
    if (i === step && step < N) return "processing";
    return "ready";
  };

  // 6 source nodes around the core (last is "soon", no doc travels)
  const NODES = [
    { id: "ANEEL", x: 12, y: 18, side: "L" },
    { id: "DOU",   x: 88, y: 18, side: "R" },
    { id: "SEI",   x: 8,  y: 50, side: "L" },
    { id: "BDGD",  x: 92, y: 50, side: "R" },
    { id: "Participação Pública", x: 14, y: 82, side: "L" },
    { id: "Reuniões Ordinárias",  x: 88, y: 82, side: "R" },
  ];

  // Orthogonal "circuit" path: node → shared midX (per side) → center.
  // Using a SHARED midX per side ensures all L-paths share the same vertical
  // segment, so the joins land on the same column instead of slightly offset.
  const MID_X_L = 32;
  const MID_X_R = 68;
  const orthoPath = (nx, ny) => {
    const cx = 50, cy = 50;
    const midX = nx < cx ? MID_X_L : MID_X_R;
    return `M ${nx} ${ny} H ${midX} V ${cy} H ${cx}`;
  };

  // Active node for the current step.
  const activeNodeIdx = step < N ? ROW_TO_NODE[step] : -1;
  const activeNode = activeNodeIdx >= 0 ? NODES[activeNodeIdx] : null;

  // Compute the doc position along its L-shaped path.
  // Phase 1 (0..0.55): travel horizontally from node.x to midX at row y.
  // Phase 2 (0.55..0.85): travel vertically from row y to center y, at midX.
  // Phase 3 (0.85..1):   travel horizontally toward center but STOP before
  //                       touching the core (we cap at 80% of the way) and
  //                       shrink to 0 — the "consumed" effect.
  let docStyle = null;
  if (activeNode) {
    const nx = activeNode.x, ny = activeNode.y;
    const cx = 50, cy = 50;
    const midX = nx < cx ? MID_X_L : MID_X_R;
    const stopX = nx < cx ? cx - 6 : cx + 6; // stop before the core
    const t = tProg;
    let x, y, scale = 1, opacity = 1;
    if (t < 0.55) {
      const k = t / 0.55;
      x = nx + (midX - nx) * k;
      y = ny;
    } else if (t < 0.82) {
      const k = (t - 0.55) / 0.27;
      x = midX;
      y = ny + (cy - ny) * k;
    } else {
      const k = (t - 0.82) / 0.18;
      x = midX + (stopX - midX) * k;
      y = cy;
      scale = 1 - k * 0.95; // shrink to ~5%
      opacity = 1 - k;
    }
    // Fade in at the very start.
    if (t < 0.06) opacity = t / 0.06;

    docStyle = {
      left: `${x}%`,
      top:  `${y}%`,
      transform: `translate(-50%, -50%) scale(${scale.toFixed(3)})`,
      opacity: opacity.toFixed(3),
    };
  }

  return (
    <div className="sp reveal">
      {/* terminal-style header */}
      <div className="sp-head">
        <span className="sp-head-id">0</span>
        <span className="sp-head-mid">SEL.IA · INGESTION ENGINE</span>
        <span className="sp-head-end">//</span>
      </div>

      {/* main canvas */}
      <div className="sp-canvas">
        <div className="sp-grid" aria-hidden="true"/>

        {/* circuit lines */}
        <svg className="sp-svg" viewBox="0 0 100 100" preserveAspectRatio="none" aria-hidden="true">
          {NODES.map((n, i) => (
            <path
              key={i}
              d={orthoPath(n.x, n.y)}
              className={`sp-line ${n.soon ? 'soon' : ''} ${i === activeNodeIdx ? 'live' : ''}`}
              vectorEffect="non-scaling-stroke"
            />
          ))}
        </svg>

        {/* the single moving document for the current step */}
        {activeNode && docStyle && (
          <div className="sp-doc" style={docStyle}>
            <div className="sp-doc-paper">
              <span className="sp-doc-tab"/>
              <span className="sp-doc-line"/>
              <span className="sp-doc-line"/>
              <span className="sp-doc-line short"/>
              <span className="sp-doc-line"/>
              <span className="sp-doc-line short"/>
              <span className="sp-doc-num">.{SP_SOURCES[step].ext}</span>
            </div>
          </div>
        )}

        {/* source nodes */}
        {NODES.map((n, i) => (
          <div
            key={`n-${i}`}
            className={`sp-node ${n.soon ? 'soon' : ''} ${i === activeNodeIdx ? 'live' : ''}`}
            style={{ left: `${n.x}%`, top: `${n.y}%` }}
          >
            <span className="sp-node-dot"/>
            <span className="sp-node-label">{n.id}</span>
          </div>
        ))}

        {/* SEL.IA core */}
        <div className="sp-core">
          <div className="sp-core-disc">
            <img src="assets/icone.png" alt="SEL.IA" className="sp-core-img"/>
          </div>
          <div className="sp-core-tag">APPROVED FOR INDEX</div>
        </div>
      </div>

      {/* progress strip */}
      <div className="sp-progress">
        <div className="sp-progress-row">
          <span className="sp-progress-label">PROGRESS &gt;&gt;&gt;</span>
          <span className="sp-progress-phase">{SP_PHASES[phaseIdx]}...</span>
          <span className="sp-progress-pct">
            <span className="sp-spinner"/> {Math.round(progress)}%
          </span>
        </div>
        <div className="sp-progress-track">
          <div className="sp-progress-fill" style={{ width: `${progress}%` }}/>
          {/* step ticks */}
          <div className="sp-progress-ticks">
            {Array.from({ length: N - 1 }).map((_, i) => (
              <span key={i} style={{ left: `${((i + 1) * 100) / N}%` }}/>
            ))}
          </div>
        </div>
      </div>

      {/* file list */}
      <div className="sp-list">
        {SP_SOURCES.map((s, i) => {
          const st = stateOf(i);
          return (
            <div className={`sp-row sp-row-${st}`} key={i}>
              <span className="sp-row-icon" aria-hidden="true">
                <svg width="14" height="16" viewBox="0 0 14 16" fill="none">
                  <path d="M1 1H9L13 5V15H1V1Z" stroke="currentColor" strokeWidth="1"/>
                  <path d="M9 1V5H13" stroke="currentColor" strokeWidth="1"/>
                </svg>
              </span>
              <span className="sp-row-tag">{s.id}</span>
              <span className="sp-row-file" title={s.file}>
                {s.file}
                {st === "processing" && <span className="sp-row-scan"/>}
              </span>
              <span className="sp-row-ext">.{s.ext}</span>
              <span className="sp-row-type">{s.type}</span>
              <span className={`sp-row-status sp-status-${st}`}>
                {st === "done" && <>Done</>}
                {st === "processing" && <>Processing</>}
                {st === "ready" && <>Pending</>}
              </span>
              <span className={`sp-row-review sp-review-${st}`}>
                <span className="sp-row-bullet"/>
                {st === "done" && <>Indexed</>}
                {st === "processing" && <>Reviewing</>}
                {st === "ready" && <>Queued</>}
              </span>
            </div>
          );
        })}
      </div>
    </div>
  );
};

Object.assign(window, { SourceProcessor });
