/* global React */
const { useState, useEffect } = React;

const STAGES = [
  { id: "upload",     label: "Reading the recording", em: "Reading", sub: "Stage 01 · audio ingest", dur: 1400 },
  { id: "transcribe", label: "Transcribing voices",   em: "Transcribing", sub: "Stage 02 · whisper-large", dur: 1800 },
  { id: "analyze",    label: "Reading between lines", em: "Reading", sub: "Stage 03 · segment intent", dur: 1600 },
  { id: "intent",     label: "Inferring who's who",   em: "Inferring", sub: "Stage 04 · role attribution", dur: 1400 },
  { id: "audio",      label: "Listening to the voice itself", em: "Listening", sub: "Stage 05 · spoof forensics", dur: 1400 },
  { id: "verdict",    label: "Reaching a verdict",    em: "Reaching", sub: "Stage 06 · fusion · gemini-2.5-flash", dur: 1200 },
];

const WAIT_LABELS = [
  "Calibrating confidence intervals...",
  "Synthesizing final evidence...",
  "Validating semantic consistency...",
  "Formatting dashboard response...",
];

function ProcessingStage({ file, isReady, onDone }) {
  const [idx, setIdx] = useState(0);
  const [waitIdx, setWaitIdx] = useState(0);

  useEffect(() => {
    // If we finished the animation stages
    if (idx >= STAGES.length - 1) { 
      if (isReady) {
        const t = setTimeout(onDone, 800); 
        return () => clearTimeout(t); 
      }
      
      // If not ready, rotate wait labels to show liveliness
      const t = setTimeout(() => {
        setWaitIdx(prev => (prev + 1) % WAIT_LABELS.length);
      }, 2500);
      return () => clearTimeout(t); 
    }

    // Determine duration: if data is ready, zip through remaining stages faster
    const currentDur = isReady ? 400 : STAGES[idx].dur;
    
    const t = setTimeout(() => setIdx(i => i + 1), currentDur);
    return () => clearTimeout(t);
  }, [idx, isReady, onDone]);

  const cur = STAGES[Math.min(idx, STAGES.length - 1)];
  const pct = Math.min(98, ((idx + 1) / STAGES.length) * 100);
  const displaySub = (idx === STAGES.length - 1 && !isReady) ? WAIT_LABELS[waitIdx] : cur.sub;

  return (
    <div className="proc-stage">
      <div className="proc-wrap">
        <div className="proc-canvas">
          {cur.id === "upload"     && <SceneUpload    key="u"/>}
          {cur.id === "transcribe" && <SceneTranscribe key="t"/>}
          {cur.id === "analyze"    && <SceneAnalyze   key="a"/>}
          {cur.id === "intent"     && <SceneIntent    key="i"/>}
          {cur.id === "audio"      && <SceneAudio     key="v"/>}
          {cur.id === "verdict"    && <SceneVerdict   key="r"/>}
        </div>

        <div className="proc-stage-label">
          <em>{cur.em}</em> {cur.label.replace(cur.em, "")}
        </div>
        <div className="proc-stage-sub" style={{ minHeight: '1.4em' }}>{displaySub}</div>

        <div className="proc-progress-wrap">
          <div className="proc-bar">
            <div className="proc-bar-fill" style={{
              width: `${isReady && idx === STAGES.length - 1 ? 100 : pct}%`,
              transition: isReady ? 'width 0.8s cubic-bezier(0.4, 0, 0.2, 1)' : 'width 2s ease-out'
            }}/>
          </div>
          <div className="proc-foot">
            <span className="step">Step <b>{Math.min(idx + 1, STAGES.length)}</b> of {STAGES.length}</span>
            <span>{file?.name || "scam1.mp3"} · {(file?.size / (1024 * 1024)).toFixed(1)} MB</span>
          </div>
        </div>
      </div>
    </div>
  );
}

function SceneUpload() {
  const heights = [25, 50, 75, 40, 90, 60, 85, 45, 70, 55, 80, 35, 65, 50, 90, 70, 45, 60, 30, 75, 50, 85, 40, 60];
  return (
    <div className="proc-scene scene-upload active">
      <div className="wave-build">
        {heights.map((h, i) => (
          <span key={i} style={{
            "--target": h / 100,
            animationDelay: `${i * 30}ms`,
            height: "80%",
          }}/>
        ))}
      </div>
    </div>
  );
}

function SceneTranscribe() {
  const words = [
    {t: "Good"}, {t: "afternoon"}, {t: "this"}, {t: "is"}, {t: "Sammy"},
    {t: "calling"}, {t: "from"}, {t: "the"}, {t: "fraud"}, {t: "watch"},
    {t: "division", flag: true}, {t: "regarding"}, {t: "the"}, {t: "security"},
    {t: "of"}, {t: "your"}, {t: "Visa", flag: true}, {t: "and"},
    {t: "Mastercard", flag: true}, {t: "accounts"}
  ];
  return (
    <div className="proc-scene scene-transcribe active">
      <div className="mini-wave">
        {[1,2,3,4,5,6,7,8,9,10,11,12].map((_, i) => (
          <span key={i} style={{animationDelay: `${i * 90}ms`, height: "100%"}}/>
        ))}
      </div>
      <div className="word-stream">
        {words.map((w, i) => (
          <span key={i} className={`word ${w.flag ? "flag" : ""}`}
                style={{animationDelay: `${i * 110 + 200}ms`}}>
            {w.t}
          </span>
        ))}
      </div>
    </div>
  );
}

function SceneAnalyze() {
  const segs = [
    {color: "var(--danger)"}, {color: "var(--warn)"}, {color: "var(--danger)"},
    {color: "var(--warn)"}, {color: "var(--danger)"}, {color: "var(--safe)"},
    {color: "var(--danger)"}, {color: "var(--warn)"}, {color: "var(--danger)"},
    {color: "var(--warn)"},
  ];
  const tags = [
    {t: "establish authority", d: true},
    {t: "create urgency", d: true},
    {t: "request credentials", d: true},
    {t: "impersonation", d: true},
    {t: "fear induction", d: true},
  ];
  return (
    <div className="proc-scene scene-analyze active">
      <div className="seg-row">
        {segs.map((s, i) => (
          <div key={i} className="seg" style={{
            "--seg-color": s.color,
            animationDelay: `${i * 80}ms`,
          }}/>
        ))}
      </div>
      <div className="tag-cloud">
        {tags.map((tag, i) => (
          <span key={i} className={`tag ${tag.d ? "danger" : ""}`}
                style={{animationDelay: `${900 + i * 140}ms`}}>
            {tag.t}
          </span>
        ))}
      </div>
    </div>
  );
}

function SceneIntent() {
  return (
    <div className="proc-scene scene-intent active">
      <div className="node scammer">
        S0
        <div className="node-label">Speaker 0</div>
      </div>
      <div className="link"></div>
      <div className="node victim">
        S1
        <div className="node-label">Speaker 1</div>
      </div>
    </div>
  );
}

function SceneAudio() {
  const bars = Array.from({length: 28}).map((_, i) => ({
    min: 15 + (i * 7) % 40,
    max: 60 + (i * 11) % 40,
    delay: i * 60,
  }));
  return (
    <div className="proc-scene scene-audio active">
      {bars.map((b, i) => (
        <span key={i} style={{
          "--min": `${b.min}%`,
          "--max": `${b.max}%`,
          animationDelay: `${b.delay}ms`,
          height: `${b.max}%`,
        }}/>
      ))}
    </div>
  );
}

function SceneVerdict() {
  const r = 70, c = 2 * Math.PI * r;
  const filled = c * 0.95;
  return (
    <div className="proc-scene scene-verdict active">
      <div className="ring">
        <svg width="160" height="160" viewBox="0 0 160 160">
          <circle cx="80" cy="80" r={r} stroke="var(--line-2)" strokeWidth="3" fill="none"/>
          <circle cx="80" cy="80" r={r} stroke="var(--danger)" strokeWidth="3" fill="none"
                  strokeDasharray={c} strokeDashoffset={c}
                  strokeLinecap="round"
                  style={{
                    animation: "verdictFill 1.4s ease-out forwards",
                    "--filled": c - filled,
                  }}/>
        </svg>
        <div className="num">95</div>
      </div>
    </div>
  );
}

window.ProcessingStage = ProcessingStage;
