// Shared interactive components for the Service AI homepage.
// Globals used: React, ReactDOM, ICONS, IconRender, INDUSTRIES, TICKER_FEED, RESULTS, CAPABILITIES, PAIN_POINTS.
const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ─────────────────────────────── Phone Widget ───────────────────────────────
// Basic typewriter playback used in hero. Loops a short demo.
const HERO_SCRIPT = [
  { kind: "ring",  label: "Incoming · Mike's Auto",  meta: "11:43 PM · After hours" },
  { kind: "pick",  label: "AI picks up",             meta: "Receptionist · Maria" },
  { kind: "ai",    text: "Hi! Thanks for calling Mike's Auto. How can I help tonight?" },
  { kind: "user",  text: "My brakes are squealing — when can you take a look?" },
  { kind: "ai",    text: "We can fit you Thursday at 9 AM. Sound good?" },
  { kind: "user",  text: "Yes, perfect." },
  { kind: "ai",    text: "Booked. You'll get a text confirmation now." },
  { kind: "done",  label: "Appointment booked · Thursday 9:00 AM",  meta: "Confirmation SMS sent" },
];

function useTypewriter(text, speed = 22, active = true) {
  const [out, setOut] = useState("");
  useEffect(() => {
    if (!active) { setOut(text); return; }
    setOut("");
    let i = 0;
    const t = setInterval(() => {
      i++;
      setOut(text.slice(0, i));
      if (i >= text.length) clearInterval(t);
    }, speed);
    return () => clearInterval(t);
  }, [text, speed, active]);
  return out;
}

function PhoneWidget({ script = HERO_SCRIPT, accent = "#F57A2B" }) {
  const [step, setStep] = useState(0);
  const [tick, setTick] = useState(0);
  useEffect(() => {
    const cur = script[step];
    const dwell = cur.kind === "ring" ? 1400
                : cur.kind === "pick" ? 1100
                : cur.kind === "done" ? 2400
                : Math.max(1600, (cur.text?.length || 0) * 30 + 600);
    const t = setTimeout(() => {
      setStep((s) => (s + 1) % script.length);
      if (step === script.length - 1) setTick((x) => x + 1);
    }, dwell);
    return () => clearTimeout(t);
  }, [step, script]);

  const visible = script.slice(0, step + 1);
  const last = script[step];

  return (
    <div className="phone-widget" key={tick}>
      <div className="phone-head">
        <div className="phone-status">
          <span className="dot live" /> <span className="mono">SERVICEAI · LIVE</span>
        </div>
        <div className="phone-time mono">{new Date().toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" })}</div>
      </div>

      <div className="phone-stream">
        {visible.map((s, i) => <PhoneLine key={i} step={s} active={i === step} accent={accent} />)}
      </div>

      <div className="phone-foot">
        <div className="phone-waveform" aria-hidden="true">
          {Array.from({ length: 28 }).map((_, i) => (
            <span key={i} style={{ animationDelay: `${(i * 70) % 1800}ms`, background: accent }} />
          ))}
        </div>
        <div className="mono small phone-foot-label">
          {last.kind === "done" ? "Call complete" : last.kind === "ring" ? "Ringing…" : "Connected"}
        </div>
      </div>
    </div>
  );
}

function PhoneLine({ step, active, accent }) {
  const text = step.text || "";
  const typed = useTypewriter(text, 22, active);
  if (step.kind === "ring") return (
    <div className="pline pline-ring">
      <span className="pline-icon" style={{ color: accent }}><IconRender name="phoneMissed" size={18} /></span>
      <div><div className="pline-label">{step.label}</div><div className="pline-meta">{step.meta}</div></div>
    </div>
  );
  if (step.kind === "pick") return (
    <div className="pline pline-pick">
      <span className="pline-icon" style={{ color: "#4ADE80" }}><IconRender name="dot" size={18} /></span>
      <div><div className="pline-label">{step.label}</div><div className="pline-meta">{step.meta}</div></div>
    </div>
  );
  if (step.kind === "done") return (
    <div className="pline pline-done">
      <span className="pline-icon" style={{ color: "#4ADE80" }}><IconRender name="check" size={18} /></span>
      <div><div className="pline-label">{step.label}</div><div className="pline-meta">{step.meta}</div></div>
    </div>
  );
  const isAi = step.kind === "ai";
  return (
    <div className={"pline pline-msg " + (isAi ? "ai" : "user")}>
      <div className="pline-author mono">{isAi ? "AI · Maria" : "Caller"}</div>
      <div className="pline-bubble" style={isAi ? { borderColor: accent + "55" } : null}>{typed}<span className={"caret " + (active && typed.length < text.length ? "blink" : "hide")} /></div>
    </div>
  );
}

// ─────────────────────────────── Industry Demo Modal ───────────────────────────────

function IndustryDemoModal({ industry, onClose, accent = "#F57A2B" }) {
  const [step, setStep] = useState(0);
  const [playing, setPlaying] = useState(true);
  useEffect(() => {
    if (!playing) return;
    if (step >= industry.transcript.length) return;
    const line = industry.transcript[step];
    const dwell = Math.max(1500, line[1].length * 32);
    const t = setTimeout(() => setStep((s) => s + 1), dwell);
    return () => clearTimeout(t);
  }, [step, playing, industry]);

  useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    window.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => { window.removeEventListener("keydown", onKey); document.body.style.overflow = ""; };
  }, [onClose]);

  const lines = industry.transcript.slice(0, step + 1);
  const done = step >= industry.transcript.length;

  return (
    <div className="demo-overlay" onClick={onClose}>
      <div className="demo-modal" onClick={(e) => e.stopPropagation()}>
        <button className="demo-close" onClick={onClose} aria-label="Close"><IconRender name="close" size={18} /></button>
        <div className="demo-head">
          <div className="demo-tag" style={{ color: accent }}><IconRender name={industry.iconKey} size={20} /></div>
          <div>
            <div className="demo-label mono">LIVE DEMO · {industry.name.toUpperCase()}</div>
            <div className="demo-title">{industry.role}</div>
          </div>
          <div className="demo-status">
            <span className="dot live" /><span className="mono small">RECORDING</span>
          </div>
        </div>

        <div className="demo-body">
          <div className="demo-transcript">
            {lines.map(([who, t], i) => (
              <DemoLine key={i} who={who} text={t} active={i === step && !done} accent={accent} />
            ))}
            {done && (
              <div className="demo-outcome">
                <IconRender name="check" size={16} />
                <span>{industry.outcome}</span>
              </div>
            )}
          </div>
          <aside className="demo-side">
            <div className="demo-side-card">
              <div className="mono small">STAT</div>
              <div className="demo-side-stat">{industry.stat}</div>
            </div>
            <div className="demo-side-card">
              <div className="mono small">PRICING</div>
              <div className="demo-side-price"><strong>{industry.price}</strong><span> · {industry.setup} setup</span></div>
            </div>
            <a className="demo-side-link" href={industry.url} target="_blank" rel="noopener noreferrer">
              See full industry site <IconRender name="external" size={14} />
            </a>
            <button className="demo-replay" onClick={() => { setStep(0); setPlaying(true); }}>
              <IconRender name="play" size={12} /> Replay demo
            </button>
          </aside>
        </div>
      </div>
    </div>
  );
}

function DemoLine({ who, text, active, accent }) {
  const typed = useTypewriter(text, 18, active);
  const isAi = who === "ai";
  return (
    <div className={"dline " + (isAi ? "ai" : "user")}>
      <div className="dline-author mono">{isAi ? "AI" : "Caller"}</div>
      <div className="dline-bubble" style={isAi ? { borderColor: accent + "55" } : null}>
        {active ? typed : text}
        <span className={"caret " + (active && typed.length < text.length ? "blink" : "hide")} />
      </div>
    </div>
  );
}

// ─────────────────────────────── Ticker ───────────────────────────────

function Ticker({ items = TICKER_FEED }) {
  const doubled = [...items, ...items];
  return (
    <div className="ticker">
      <div className="ticker-track">
        {doubled.map((it, i) => (
          <div className="ticker-item" key={i}>
            <span className="dot live" />
            <strong>{it.who}</strong>
            <span className="ticker-dash">—</span>
            <span>{it.what}</span>
          </div>
        ))}
      </div>
    </div>
  );
}

// ─────────────────────────────── ROI Calculator ───────────────────────────────

function ROICalculator({ accent = "#F57A2B" }) {
  const [missed, setMissed] = useState(20);
  const [value,  setValue]  = useState(500);
  const [rate,   setRate]   = useState(30);
  const monthly = Math.round((missed * value * (rate / 100)) / 10) * 10;
  const target = useRef(0);
  const [display, setDisplay] = useState(0);
  useEffect(() => {
    target.current = monthly;
    let raf;
    const start = performance.now();
    const from = display;
    const dur = 700;
    const tick = (t) => {
      const k = Math.min(1, (t - start) / dur);
      const eased = 1 - Math.pow(1 - k, 3);
      setDisplay(Math.round(from + (target.current - from) * eased));
      if (k < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [monthly]);

  return (
    <div className="roi">
      <div className="roi-rows">
        <RoiSlider label="Calls missed / month" value={missed} setValue={setMissed} min={0}   max={100}  step={1}   fmt={(v) => v} accent={accent} />
        <RoiSlider label="Average job value"    value={value}  setValue={setValue}  min={100} max={5000} step={50}  fmt={(v) => "$" + v.toLocaleString()} accent={accent} />
        <RoiSlider label="Close rate"           value={rate}   setValue={setRate}   min={10}  max={80}   step={1}   fmt={(v) => v + "%"} accent={accent} />
      </div>
      <div className="roi-out">
        <div className="roi-out-label mono">REVENUE LEFT ON THE TABLE</div>
        <div className="roi-out-amount" style={{ color: accent }}>${display.toLocaleString()}<span className="roi-out-per">/mo</span></div>
        <div className="roi-out-sub">That's <strong>${(display*12).toLocaleString()}</strong> a year you're handing your competitors.</div>
        <button className="btn btn-flame" style={{ background: accent }}>Get that money back <IconRender name="arrow" size={14} /></button>
      </div>
    </div>
  );
}

function RoiSlider({ label, value, setValue, min, max, step, fmt, accent }) {
  const pct = ((value - min) / (max - min)) * 100;
  return (
    <div className="roi-row">
      <div className="roi-row-head">
        <div className="mono small">{label}</div>
        <div className="roi-row-val">{fmt(value)}</div>
      </div>
      <input type="range" min={min} max={max} step={step} value={value} onChange={(e) => setValue(+e.target.value)}
             style={{ background: `linear-gradient(to right, ${accent} 0%, ${accent} ${pct}%, #2E2E2E ${pct}%, #2E2E2E 100%)` }} />
    </div>
  );
}

// ─────────────────────────────── Industry Card ───────────────────────────────

function IndustryCard({ ind, onDemo, accent = "#F57A2B", compact = false, featured = false }) {
  return (
    <div className={"ind-card" + (compact ? " compact" : "") + (featured ? " ind-feat" : "")}>
      <div className="ind-card-top">
        <span className="ind-card-icon" style={{ color: accent }}><IconRender name={ind.iconKey} size={featured ? 28 : 22} /></span>
        <div className="ind-card-titles">
          <div className="ind-card-name" style={featured ? { fontSize: 22 } : {}}>{ind.name}</div>
          <div className="ind-card-role mono">{ind.role}</div>
        </div>
      </div>
      {!compact && <div className="ind-card-stat">{ind.stat}</div>}
      {featured && <div className="ind-feat-price mono small" style={{ color: "var(--smoke)", marginTop: 4 }}>{ind.price} · {ind.setup} setup</div>}
      <div className="ind-card-actions">
        <button className="ind-btn primary" onClick={() => onDemo(ind)}>
          <IconRender name="play" size={11} /> Watch demo
        </button>
        <a className="ind-btn ghost" href={ind.url} target="_blank" rel="noopener noreferrer">
          Site <IconRender name="external" size={12} />
        </a>
      </div>
    </div>
  );
}

// ─────────────────────────────── Count-up ───────────────────────────────

function CountUp({ value, suffix = "", duration = 1400 }) {
  const [n, setN] = useState(0);
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(([e]) => { if (e.isIntersecting) setSeen(true); }, { threshold: 0.3 });
    io.observe(ref.current);
    return () => io.disconnect();
  }, []);
  useEffect(() => {
    if (!seen) return;
    const raw = parseFloat(String(value).replace(/[^0-9.-]/g, "")) || 0;
    let raf, start;
    const tick = (t) => {
      if (!start) start = t;
      const k = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - k, 3);
      setN(raw * eased);
      if (k < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [seen, value, duration]);
  const sign = String(value).startsWith("+") ? "+" : "";
  return <span ref={ref}>{sign}{Math.round(n)}{suffix}</span>;
}

Object.assign(window, { PhoneWidget, IndustryDemoModal, Ticker, ROICalculator, IndustryCard, CountUp });
