/* AI Start Here - Lainey editorial components */

const { useState, useEffect, useRef, useMemo } = React;

// ========== Icon / SVG atoms ==========
const SubmarkImg = ({ size = 42, opacity = 1, duration = 60, src = "images/submark-burgundy.png" }) => (
  <img
    src={src}
    alt=""
    className="submark-img"
    style={{
      width: size,
      height: size,
      opacity,
      animationDuration: `${duration}s`
    }}
  />
);

const Wordmark = ({ color = "var(--burgundy)" }) => (
  <span className="wordmark" style={{ color }}>AI <span style={{ fontStyle: 'italic' }}>Start Here</span></span>
);

const JessClarkMark = ({ height = 18, color = "var(--burgundy)" }) => (
  <img
    src="images/jess-clark-wordmark.png"
    alt="Jess Clark"
    style={{
      height,
      width: 'auto',
      display: 'block',
      filter: color === 'var(--cream)' ? 'invert(98%) sepia(8%) saturate(280%) hue-rotate(330deg) brightness(102%)' : 'none'
    }}
  />
);

const LogoLockup = ({ color = "var(--burgundy)" }) => (
  <span className="logo-lockup">
    <SubmarkImg size={26} duration={60} src={color === 'var(--cream)' ? "images/submark-peri.png" : "images/submark-burgundy.png"} />
    <Wordmark color={color} />
  </span>
);

// ========== Masthead + progress ==========
const Masthead = ({ onExit }) => (
  <header className="masthead">
    <LogoLockup />
    <button className="save-exit" onClick={onExit}>Save &amp; Exit ↗</button>
  </header>
);

// Section labels - used in the page eyebrow inside the body, NOT in the top strip
const STEP_PILLS = [
  { key: 'welcome',     label: 'Welcome',     section: null },
  { key: 'pre-audit',   label: 'Before',      section: 1 },
  { key: 'chatgpt',     label: 'ChatGPT',     section: 2 },
  { key: 'claude',      label: 'Claude',      section: 3 },
  { key: 'compare',     label: 'Compare',     section: 4 },
  { key: 'bonus',       label: 'Bonus',       section: 5 },
  { key: 'post-audit',  label: 'After',       section: 6 }
];

// Lainey-style minimal progress bar: single hairline pill, periwinkle fill. No chips.
const ProgressBar = ({ progress }) => {
  const pct = typeof progress === 'number' ? Math.min(100, Math.max(0, progress)) : 0;
  return (
    <div className="progress-shell">
      <div
        className="progress-track"
        role="progressbar"
        aria-valuenow={Math.round(pct)}
        aria-valuemin="0"
        aria-valuemax="100"
        aria-label="Course progress"
      >
        <div className="progress-fill" style={{ width: `${pct}%` }} />
      </div>
    </div>
  );
};

// ========== Laptop illustration ==========
const Laptop = ({ videoSrc, fallbackTag = "Watch · 3 min", fallbackTitle = "Your explainer video drops in here" }) => {
  const [playing, setPlaying] = useState(false);
  const screenRef = React.useRef(null);
  const goFullscreen = () => {
    const target = screenRef.current?.querySelector('video') || screenRef.current;
    if (!target) return;
    if (document.fullscreenElement) {
      document.exitFullscreen();
    } else if (target.requestFullscreen) {
      target.requestFullscreen();
    } else if (target.webkitEnterFullscreen) {
      target.webkitEnterFullscreen();
    } else if (target.webkitRequestFullscreen) {
      target.webkitRequestFullscreen();
    }
  };
  return (
    <div className="laptop">
      <div className="laptop-screen" ref={screenRef}>
        {videoSrc ? (
          <video controls playsInline preload="metadata">
            <source src={videoSrc} type="video/mp4" />
          </video>
        ) : (
          <div className="video-placeholder" onClick={() => setPlaying(p => !p)}>
            <div className="play">
              <svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor">
                <path d="M8 5v14l11-7z" />
              </svg>
            </div>
            <div className="tag">{fallbackTag}</div>
            <div className="title">{fallbackTitle}</div>
          </div>
        )}
        <button type="button" className="fullscreen-btn" onClick={goFullscreen} aria-label="Toggle fullscreen">
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M4 9V4h5" />
            <path d="M20 9V4h-5" />
            <path d="M4 15v5h5" />
            <path d="M20 15v5h-5" />
          </svg>
        </button>
      </div>
      <svg className="laptop-shell" viewBox="0 0 800 540" fill="none" aria-hidden="true">
        <rect x="18" y="8" width="764" height="480" rx="18" ry="18"
              stroke="currentColor" strokeWidth="2" strokeLinejoin="round"/>
        <rect x="38" y="22" width="724" height="452"
              stroke="currentColor" strokeWidth="1.25" opacity="0.5"/>
        <rect x="0" y="500" width="800" height="30" rx="10" ry="10"
              stroke="currentColor" strokeWidth="2" strokeLinejoin="round"/>
        <line x1="340" y1="500" x2="460" y2="500" stroke="currentColor" strokeWidth="2" />
      </svg>
    </div>
  );
};

// ========== Phone illustration (for vertical Reel-style video) ==========
const Phone = ({ videoSrc, captionsSrc, fallbackTag = "Watch · 2 min", fallbackTitle = "Press play" }) => {
  const [playing, setPlaying] = useState(false);
  return (
    <div className="phone">
      <div className="phone-screen">
        {videoSrc ? (
          <video controls playsInline preload="metadata" crossOrigin="anonymous">
            <source src={videoSrc} type="video/mp4" />
            {captionsSrc && (
              <track default kind="captions" srcLang="en" label="English" src={captionsSrc} />
            )}
          </video>
        ) : (
          <div className="video-placeholder" onClick={() => setPlaying(p => !p)}>
            <div className="play">
              <svg width="22" height="22" viewBox="0 0 24 24" fill="currentColor">
                <path d="M8 5v14l11-7z" />
              </svg>
            </div>
            <div className="tag">{fallbackTag}</div>
            <div className="title">{fallbackTitle}</div>
          </div>
        )}
      </div>
      <svg className="phone-shell" viewBox="0 0 400 820" fill="none" aria-hidden="true">
        {/* Outer body */}
        <rect x="4" y="4" width="392" height="812" rx="48" ry="48"
              stroke="currentColor" strokeWidth="2.5" />
        {/* Inner screen edge */}
        <rect x="14" y="14" width="372" height="792" rx="40" ry="40"
              stroke="currentColor" strokeWidth="1.25" opacity="0.45" />
        {/* Dynamic island */}
        <rect x="155" y="28" width="90" height="22" rx="11" ry="11"
              fill="currentColor" />
        {/* Home indicator */}
        <rect x="140" y="788" width="120" height="4" rx="2" ry="2"
              fill="currentColor" opacity="0.55" />
        {/* Side buttons */}
        <line x1="3" y1="180" x2="3" y2="240" stroke="currentColor" strokeWidth="3" strokeLinecap="round" />
        <line x1="3" y1="280" x2="3" y2="340" stroke="currentColor" strokeWidth="3" strokeLinecap="round" />
        <line x1="397" y1="220" x2="397" y2="290" stroke="currentColor" strokeWidth="3" strokeLinecap="round" />
      </svg>
    </div>
  );
};

// ========== Voice memo player ==========
const VoiceMemo = ({ title = "Jess's 2-min voice memo", duration = "2:14", audioSrc, transcriptSrc }) => {
  const [playing, setPlaying] = useState(false);
  const [now, setNow] = useState(0);
  const [total, setTotal] = useState(null);
  const [showTx, setShowTx] = useState(false);
  const [tx, setTx] = useState(null);
  const [txLoading, setTxLoading] = useState(false);
  const audioRef = React.useRef(null);
  const bars = 32;
  // Derive transcript URL from audio URL if not given (audio/2.1.mp3 -> transcripts/2.1.txt)
  const txSrc = transcriptSrc || (audioSrc ? audioSrc.replace(/^audio\//, 'transcripts/').replace(/\.mp3$/, '.txt') : null);

  // Real audio playback
  React.useEffect(() => {
    const a = audioRef.current;
    if (!a) return;
    const onTime = () => setNow(a.currentTime);
    const onEnd = () => { setPlaying(false); setNow(0); };
    const onMeta = () => setTotal(a.duration);
    a.addEventListener('timeupdate', onTime);
    a.addEventListener('ended', onEnd);
    a.addEventListener('loadedmetadata', onMeta);
    return () => {
      a.removeEventListener('timeupdate', onTime);
      a.removeEventListener('ended', onEnd);
      a.removeEventListener('loadedmetadata', onMeta);
    };
  }, [audioSrc]);

  const togglePlay = () => {
    const a = audioRef.current;
    if (audioSrc && a) {
      if (a.paused) { a.play(); setPlaying(true); }
      else { a.pause(); setPlaying(false); }
    } else {
      setPlaying(p => !p);
    }
  };

  const fmt = (s) => {
    if (!Number.isFinite(s)) return duration;
    const m = Math.floor(s / 60), sec = Math.floor(s % 60);
    return `${m}:${sec.toString().padStart(2, '0')}`;
  };
  const display = audioSrc
    ? (playing ? fmt(now) : (total ? fmt(total) : duration))
    : (playing ? "0:42" : duration);

  const toggleTranscript = async () => {
    if (showTx) { setShowTx(false); return; }
    setShowTx(true);
    if (!tx && txSrc) {
      setTxLoading(true);
      try {
        const r = await fetch(txSrc);
        if (r.ok) setTx(await r.text());
        else setTx("(Transcript not available yet.)");
      } catch (e) {
        setTx("(Transcript not available yet.)");
      }
      setTxLoading(false);
    }
  };

  return (
    <div className="voice-memo">
      {audioSrc && <audio ref={audioRef} src={audioSrc} preload="metadata" />}
      <div className="card-eyebrow">
        <span className="eyebrow">Voice memo</span>
      </div>
      <h3>{title}</h3>
      <div className="voice-player">
        <button className="voice-icon" onClick={togglePlay} aria-label={playing ? "Pause" : "Play"}>
          {playing ? (
            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><rect x="6" y="5" width="4" height="14"/><rect x="14" y="5" width="4" height="14"/></svg>
          ) : (
            <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>
          )}
        </button>
        <div className={`voice-wave ${playing ? 'playing' : ''}`}>
          {Array.from({ length: bars }).map((_, i) => (
            <span key={i} style={{
              height: `${20 + Math.abs(Math.sin(i * 0.7)) * 80}%`,
              animationDelay: `${(i % 8) * 0.1}s`
            }} />
          ))}
        </div>
        <div className="voice-time">{display}</div>
      </div>
      {txSrc && (
        <button type="button" className={`transcript-toggle ${showTx ? 'open' : ''}`} onClick={toggleTranscript} aria-expanded={showTx}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <path d="M4 6h16M4 12h12M4 18h8" />
          </svg>
          {showTx ? "Hide transcript" : "Read transcript"}
        </button>
      )}
      {showTx && (
        <div className="transcript-panel" role="region" aria-label="Voice memo transcript">
          {txLoading ? <p className="transcript-loading">Loading transcript…</p> : <p>{tx}</p>}
        </div>
      )}
    </div>
  );
};

// ========== Reflection text box ==========
const Reflection = ({ prompt, storageKey }) => {
  const [value, setValue] = useState(() => {
    try { return localStorage.getItem(storageKey) || ""; } catch { return ""; }
  });
  const [saved, setSaved] = useState(false);
  useEffect(() => {
    const t = setTimeout(() => {
      try { localStorage.setItem(storageKey, value); } catch {}
      if (value) { setSaved(true); setTimeout(() => setSaved(false), 1200); }
    }, 600);
    return () => clearTimeout(t);
  }, [value, storageKey]);
  const count = value.trim().length;
  return (
    <div className="reflection-card">
      <div className="card-eyebrow">
        <span className="eyebrow">Your turn</span>
      </div>
      <h3>Capture what lands.</h3>
      <p className="prompt">{prompt}</p>
      <textarea
        className="reflection-textarea"
        value={value}
        onChange={e => setValue(e.target.value)}
        placeholder="Start typing - no wrong answers, just your real thoughts…"
      />
      <div className="reflection-meta">
        <span>{count} chars</span>
        <span className={saved ? 'saved' : ''}>{saved ? "✓ Saved" : "Autosaves as you type"}</span>
      </div>
    </div>
  );
};

// ========== Primary button ==========
const Btn = ({ children, onClick, disabled, ghost, full, style }) => (
  <button
    className={`btn ${ghost ? 'btn-ghost' : ''} ${full ? 'btn-full' : ''}`}
    onClick={onClick}
    disabled={disabled}
    style={style}
  >
    {children}
  </button>
);

// ========== Complete checkbox ==========
const CompleteCheck = ({ checked, onChange }) => (
  <label className="complete-check">
    <input type="checkbox" checked={checked} onChange={e => onChange(e.target.checked)} />
    <span className="box" aria-hidden="true">
      <svg viewBox="0 0 24 24" fill="none" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
        <polyline points="4 12 10 18 20 6"></polyline>
      </svg>
    </span>
    <span>Mark this step complete</span>
  </label>
);

// ========== Step footer ==========
const StepFooter = ({ onPrev, onNext, nextLabel = "Continue", canNext, complete, setComplete, prevLabel = "← Back", hideComplete }) => (
  <footer className="step-footer">
    <Btn ghost onClick={onPrev}>{prevLabel}</Btn>
    {hideComplete ? <span /> : <CompleteCheck checked={complete} onChange={setComplete} />}
    <Btn onClick={onNext} disabled={!canNext}>
      {nextLabel} <span className="arrow">→</span>
    </Btn>
  </footer>
);

// ========== Copy-to-clipboard button ==========
const CopyButton = ({ text, label = "Copy prompt" }) => {
  const [copied, setCopied] = useState(false);
  const onCopy = async () => {
    try {
      if (navigator.clipboard && window.isSecureContext) {
        await navigator.clipboard.writeText(text);
      } else {
        const ta = document.createElement('textarea');
        ta.value = text;
        ta.style.position = 'fixed';
        ta.style.opacity = '0';
        document.body.appendChild(ta);
        ta.select();
        document.execCommand('copy');
        document.body.removeChild(ta);
      }
      setCopied(true);
      setTimeout(() => setCopied(false), 1800);
    } catch (e) {
      setCopied(false);
    }
  };
  return (
    <button type="button" className={`copy-btn ${copied ? 'copied' : ''}`} onClick={onCopy} aria-label={copied ? "Copied" : label}>
      {copied ? (
        <>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round"><polyline points="4 12 10 18 20 6" /></svg>
          Copied
        </>
      ) : (
        <>
          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <rect x="9" y="9" width="11" height="11" rx="2" />
            <path d="M5 15V5a2 2 0 0 1 2-2h10" />
          </svg>
          {label}
        </>
      )}
    </button>
  );
};

// ========== Legal footer (every page) ==========
const LegalFooter = () => (
  <footer className="legal-footer">
    <div className="legal-footer-inner">
      <div className="legal-footer-mark">
        <JessClarkMark height={20} color="var(--burgundy)" />
      </div>
      <div className="legal-footer-copy">
        <p className="legal-line legal-copyright">&copy; 2026 Jess Clark. All rights reserved.</p>
        <p className="legal-line">This tool is licensed for single-user, personal business use only as part of your AI Start Here purchase.</p>
        <p className="legal-line">Unauthorised sharing, distribution, reproduction, or resale is strictly prohibited.</p>
        <p className="legal-line legal-jurisdiction">Governed by the laws of Victoria, AUS.</p>
      </div>
    </div>
  </footer>
);

Object.assign(window, {
  SubmarkImg, Wordmark, LogoLockup, JessClarkMark,
  Masthead, ProgressBar, LegalFooter,
  Laptop, Phone, VoiceMemo, Reflection,
  Btn, CompleteCheck, StepFooter, CopyButton
});
