// demo.jsx — interactive "Try it yourself" demo: auto-populated setup → customer view + business view
// Requires React, ios-frame.jsx, chat-ui.jsx loaded first.

const Demo = (() => {
  const { useState, useEffect, useRef } = React;

  // ── Example (gym) content — fictional ─────────────────────
  const GYM = {
    name: "Iron Peak Fitness",
    website: "https://ironpeakfitness.com",
    context:
      "Iron Peak Fitness is a full-service gym in Austin, TX. We're open Mon-Fri 5am-10pm, Sat-Sun 8am-6pm. We offer group classes (HIIT, yoga, spin, strength), personal training ($85/session), and drop-in visits ($20/day). Membership starts at $49/month. We have free parking, showers, and a smoothie bar. Our team of certified trainers is available for consultations by appointment.",
    zip: "78701",
    number: "(XXX) 555-0123",
  };

  const FILES = [
    { name: "iron-peak-faq.pdf", size: "184 KB" },
    { name: "class-schedule.docx", size: "92 KB" },
  ];

  // ── Customer-view Q&A ─────────────────────────────────────
  const QUESTIONS = [
    {
      q: "What are your hours?",
      a: "We're open Mon-Fri 5am-10pm and Sat-Sun 8am-6pm. Come by anytime!",
      typingMs: 1300,
    },
    {
      q: "How much is a day pass?",
      a: "Drop-in visits are just $20/day. No reservation needed - walk right in!",
      typingMs: 1200,
    },
    {
      q: "Do you offer personal training?",
      a: "Absolutely! Personal training is $85/session with one of our certified trainers. Want me to grab you a consultation slot?",
      typingMs: 1900,
    },
    {
      q: "What classes do you have?",
      a: "We offer HIIT, yoga, spin, and strength classes throughout the week. I can send you the full schedule if you'd like!",
      typingMs: 1600,
    },
  ];

  // ── Business-view mock data ───────────────────────────────
  const CONVOS = [
    {
      initials: "MD", name: "Marcus D.", snippet: "do you do corporate memberships?", time: "1m",
      phone: "(512) 555-0184", unread: true,
      thread: [
        { from: "them", text: "hi! do you do corporate memberships? id like to set something up for my office" },
        { from: "me", text: "We do! Want to schedule a time for someone on our membership team to give you a call?" },
        { from: "them", text: "anything before 5pm works" },
        { from: "me", text: "Perfect - someone will give you a ring shortly. Talk soon!" },
      ],
    },
    {
      initials: "SM", name: "Sarah M.", snippet: "is there parking at the gym?", time: "2m",
      phone: "(512) 555-4821",
      thread: [
        { from: "them", text: "is there parking at the gym?" },
        { from: "me", text: "Yes! We have a free parking lot right next to the building - plenty of spots even during peak hours. \uD83D\uDE97" },
        { from: "them", text: "great, im thinking of joining. how much is membership" },
        { from: "me", text: "Membership starts at $49/month, no contracts required. Want me to tell you about what's included?" },
        { from: "them", text: "all good, ill just stop by this week to check it out" },
        { from: "me", text: "Sounds great - see you soon!" },
      ],
    },
    {
      initials: "JK", name: "James K.", snippet: "do you have locker rooms", time: "14m",
      phone: "(512) 555-3387",
      thread: [
        { from: "them", text: "do you have locker rooms" },
        { from: "me", text: "We do - full locker rooms with showers, plus towels at the front desk. Just bring a lock or rent one for $1." },
        { from: "them", text: "perfect thanks" },
      ],
    },
    {
      initials: "PL", name: "Priya L.", snippet: "can i pause my membership?", time: "1h",
      phone: "(512) 555-9054",
      thread: [
        { from: "them", text: "can i pause my membership?" },
        { from: "me", text: "Yes, you can pause for up to 3 months once per year at no charge. Want me to set that up for you?" },
        { from: "them", text: "yes please, starting next month" },
        { from: "me", text: "Done - your membership will pause starting July 1 and resume automatically. You'll get a text confirmation shortly." },
        { from: "them", text: "awesome, thank you!!" },
      ],
    },
    {
      initials: "TB", name: "Tom B.", snippet: "whats the cancellation policy", time: "3h",
      phone: "(512) 555-7712",
      thread: [
        { from: "them", text: "whats the cancellation policy" },
        { from: "me", text: "No contracts here - you can cancel anytime from your account or by texting us. No fees, no questions." },
      ],
    },
    {
      initials: "AR", name: "Alyssa R.", snippet: "do u offer student discounts", time: "1d",
      phone: "(512) 555-2240",
      thread: [
        { from: "them", text: "do u offer student discounts" },
        { from: "me", text: "We do - students get 20% off any membership with a valid ID. That brings the base plan to $39/month." },
        { from: "them", text: "sweet, what do i need to bring?" },
        { from: "me", text: "Just a valid student ID and you're all set!" },
      ],
    },
  ];

  const CheckIcon = () => (
    <svg className="check" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
      <path d="M20 6L9 17l-5-5"></path>
    </svg>
  );

  const FileGlyph = () => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path>
      <path d="M14 2v6h6"></path>
    </svg>
  );

  const PhoneGlyph = ({ size = 18 }) => (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path>
    </svg>
  );

  // ── Phase 1: auto-populating setup form ───────────────────
  function SetupForm({ onLaunch }) {
    const [name, setName] = useState("");
    const [website, setWebsite] = useState("");
    const [context, setContext] = useState("");
    const [zip, setZip] = useState("");
    const [fileCount, setFileCount] = useState(0);
    const [ready, setReady] = useState(false);
    const [promptStage, setPromptStage] = useState(-1);
    // `pleases` retired — the escalating "please please please" badges
    // on the Try button read as needy / try-hard. Variable kept declared
    // as a no-op so the schedule below doesn't crash if anything still
    // references it.
    const pleases = 0;
    const started = useRef(false);
    const timers = useRef([]);
    const cardRef = useRef(null);

    useEffect(() => () => timers.current.forEach(clearTimeout), []);

    useEffect(() => {
      const el = cardRef.current;
      if (!el) return;
      const check = () => {
        if (started.current) return;
        const r = el.getBoundingClientRect();
        const vh = window.innerHeight || document.documentElement.clientHeight;
        const visible = Math.min(r.bottom, vh) - Math.max(r.top, 0);
        if (visible > 0 && visible / Math.min(r.height, vh) >= 0.35) {
          started.current = true;
          window.removeEventListener("scroll", check);
          window.removeEventListener("resize", check);
          runSequence();
        }
      };
      window.addEventListener("scroll", check, { passive: true });
      window.addEventListener("resize", check);
      check();
      return () => {
        window.removeEventListener("scroll", check);
        window.removeEventListener("resize", check);
      };
    }, []);

    function at(ms, fn) { timers.current.push(setTimeout(fn, ms)); }
    function typeText(text, startMs, perChar, setter) {
      for (let i = 1; i <= text.length; i++) {
        at(startMs + i * perChar, () => setter(text.slice(0, i)));
      }
      return startMs + text.length * perChar;
    }

    function runSequence() {
      const reduced = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
      if (reduced) {
        setName(GYM.name); setWebsite(GYM.website); setContext(GYM.context);
        setZip(GYM.zip); setFileCount(FILES.length); setReady(true);
        setPromptStage(2);
        return;
      }
      typeText(GYM.name, 0, 44, setName);                  // ~0.84s
      typeText(GYM.website, 960, 30, setWebsite);          // ~0.9s
      FILES.forEach((_, i) => at(1900 + i * 300, () => setFileCount(i + 1)));
      at(2640, () => setContext(GYM.context));             // pasted at once
      typeText(GYM.zip, 2840, 120, setZip);                // ~0.6s
      at(3900, () => setReady(true));

      const isMobile = window.matchMedia && window.matchMedia("(max-width: 768px)").matches;
      if (isMobile) {
        // Mobile: only the "Yes, here" prompt, for 3s, and never returns.
        at(9900,  () => setPromptStage(1));                // "Yes, here"
        at(12900, () => setPromptStage(3));                // hide forever
      } else {
        // 6s after button is clickable, then 2s between each prompt:
        at(9900,  () => setPromptStage(0));                // "Click here"
        at(11900, () => setPromptStage(1));                // "Yes, here"
        at(13900, () => setPromptStage(2));                // "you know you want to"
        at(15900, () => setPromptStage(3));                // hide prompts forever
        // "please please please" badges retired. Schedule kept empty to
        // preserve timing of the surrounding hide-prompts step (stage 3).
      }
    }

    const fieldCls = (v) => "form-field" + (v ? " filled" : "");

    const [titlePulse, setTitlePulse] = useState(0);
    const pulseClick = () => setTitlePulse((n) => n + 1);

    return (
      <div className="demo-card phase" ref={cardRef} data-screen-label="Demo — setup form" onClick={pulseClick}>
        <div className="demo-card-head">
          <div>
            <h3 key={titlePulse}
                className={"demo-card-title" + (titlePulse ? " demo-card-title-pulse" : "")}
                style={{ fontSize: "var(--t-18)", fontWeight: 600, color: "var(--fg-strong)" }}>
              An example of how easy the setup is...
            </h3>
          </div>
        </div>
        <hr className="demo-title-divider" />

        <div className="form-grid">
          <div className={fieldCls(name)}>
            <label className="lbl">Business name <CheckIcon /></label>
            <input className="field" value={name} readOnly placeholder="e.g. CrossFit Midtown" />
          </div>
          <div className={fieldCls(website)}>
            <label className="lbl">Business website <CheckIcon /></label>
            <input className="field" type="url" value={website} readOnly placeholder="yourwebsite.com" />
          </div>

          <div className={"full " + fieldCls(fileCount === FILES.length ? "y" : "")}>
            <label className="lbl">Upload materials <CheckIcon /></label>
            <div className="files-row">
              {FILES.slice(0, fileCount).map((f) => (
                <span className="file-chip" key={f.name}>
                  <FileGlyph />
                  <span className="file-chip-name">{f.name}</span>
                  <span className="file-chip-size">{f.size}</span>
                </span>
              ))}
              {fileCount === 0 && <span className="hint">FAQs, menus, policies, or any docs</span>}
            </div>
          </div>

          <div className={"full " + fieldCls(context)}>
            <label className="lbl">Additional context <CheckIcon /></label>
            <textarea className="field" rows="3" value={context} readOnly
              placeholder="Any extra info you'd like your agent to know - pricing, hours, policies, team bios, etc."></textarea>
          </div>

          <div className={"full " + fieldCls(zip)}>
            <label className="lbl">Your zip code <CheckIcon /></label>
            <input className="field zip-field" inputMode="numeric" maxLength="5" value={zip} readOnly placeholder="10001" />
          </div>
        </div>

        <div className="launch-wrap">
          <button
          className={"btn btn-primary btn-lg" + (ready ? " btn-pulse" : "")}
          style={{ width: "100%", justifyContent: "center", height: 52 }}
          disabled={!ready}
          onClick={() => onLaunch({ name: GYM.name, number: GYM.number })}>
          {ready ? (
            <React.Fragment>
              Try the agent now!
              {pleases > 0 && (
                <span className="btn-please">{Array(pleases).fill("please").join(" ")}</span>
              )}
            </React.Fragment>
          ) : "Setting up\u2026"}
        </button>
        {ready && (
          <React.Fragment>
            {promptStage === 0 && (
              <span className="click-prompt pop-in">
                <span className="click-label">Click here</span>
                <svg className="click-arrow" width="38" height="34" viewBox="0 0 38 34" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M4 4 C 18 6, 28 14, 30 28"></path>
                  <path d="M22 24 L 30 28 L 34 19"></path>
                </svg>
              </span>
            )}
            {promptStage === 1 && (
              <span className="click-prompt click-prompt-2 pop-in">
                <span className="click-label">Yes, here</span>
                <svg className="click-arrow" width="38" height="34" viewBox="0 0 38 34" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
                  <path d="M4 4 C 18 6, 28 14, 30 28"></path>
                  <path d="M22 24 L 30 28 L 34 19"></path>
                </svg>
              </span>
            )}
            {promptStage === 2 && (
              <span className="click-prompt click-prompt-3 pop-in">
                <span className="click-label">you know you want to</span>
              </span>
            )}
            <span className="click-cursor">
              <svg width="26" height="26" viewBox="0 0 24 24">
                <path d="M5 2l14 11h-7l4 8-3.4 1.6L8.6 14 4 19z" fill="#1B1913" stroke="#fff" strokeWidth="1.4"></path>
              </svg>
            </span>
          </React.Fragment>
        )}
        </div>
      </div>
    );
  }

  // ── Phase 2: customer view ────────────────────────────────
  function CustomerView({ business }) {
    const [messages, setMessages] = useState([]);
    const [typing, setTyping] = useState(false);
    const [busy, setBusy] = useState(false);
    const [asked, setAsked] = useState([]);
    const [compose, setCompose] = useState("");
    const [nudge, setNudge] = useState(false);
    const threadRef = useRef(null);
    const timers = useRef([]);

    useEffect(() => () => timers.current.forEach(clearTimeout), []);
    useEffect(() => {
      const el = threadRef.current;
      if (el) el.scrollTop = el.scrollHeight;
    }, [messages, typing]);

    const ask = (item, idx) => {
      if (busy || asked.includes(idx)) return;
      setBusy(true);
      setAsked((a) => [...a, idx]);

      // type the message into the compose bar quickly (<1s), then send
      const text = item.q;
      const perChar = Math.min(28, Math.floor(620 / text.length));
      for (let i = 1; i <= text.length; i++) {
        timers.current.push(setTimeout(() => setCompose(text.slice(0, i)), i * perChar));
      }
      const sendAt = text.length * perChar + 180;
      timers.current.push(setTimeout(() => {
        setCompose("");
        setMessages((m) => [...m, { from: "me", text }]);
      }, sendAt));
      timers.current.push(setTimeout(() => setTyping(true), sendAt + 450));
      timers.current.push(setTimeout(() => {
        setTyping(false);
        setMessages((m) => [...m, { from: "them", text: item.a }]);
        setBusy(false);
      }, sendAt + 450 + item.typingMs));
    };

    // Clicking the (display-only) compose input before starting nudges the
    // start-hint bubble so the visitor knows to tap a question instead.
    const bumpNudge = () => {
      if (messages.length || typing) return;
      setNudge(false);
      requestAnimationFrame(() => setNudge(true));
      timers.current.push(setTimeout(() => setNudge(false), 720));
    };
    const composeBar = (
      <div onClick={bumpNudge}>
        <ComposeBar text={compose} low />
      </div>
    );

    return (
      <div className="demo-split" style={{ display: "flex", gap: "var(--s-8)", alignItems: "center", justifyContent: "center" }} data-screen-label="Demo — customer view">
        <div style={{ width: 342, height: 480, flexShrink: 0 }}>
          <div style={{ width: 402, height: 565, transform: "scale(0.85)", transformOrigin: "top left" }}>
            <IOSDevice width={402} height={565} time={nowTime()} homeIndicator={false}
              radius={30} island={{ width: 100, height: 28, top: 9 }} statusCompact>
              <ChatScreen contact={business.name} avatar={"\uD83D\uDCAA"} tone="plain" callIcon compact threadRef={threadRef} footer={composeBar}>
                {messages.length === 0 && !typing ? (
                  <div className={"start-hint" + (nudge ? " nudge" : "")}>Tap a question to start the conversation</div>
                ) : (
                  <div className="chat-stamp">{nowStamp()}</div>
                )}
                {messages.map((m, i) => (
                  <ChatBubble key={i} from={m.from}>{m.text}</ChatBubble>
                ))}
                {typing && <TypingBubble from="them" />}
              </ChatScreen>
            </IOSDevice>
          </div>
        </div>
        <div style={{ flex: "0 1 320px", display: "flex", flexDirection: "column", gap: "var(--s-3)" }}>
          <div className="t-eyebrow">Ask as a customer</div>
          <div className="quick-questions">
            {QUESTIONS.map((item, idx) => (
              <button key={item.q}
                className={"qq-btn" + (asked.includes(idx) ? " asked" : "")}
                disabled={busy || asked.includes(idx)}
                onClick={() => ask(item, idx)}>
                {item.q}
              </button>
            ))}
          </div>
          <span className="hint">These are example questions - a real customer can ask anything, in any wording. Every reply comes from the business details provided in real time. Want to try the agent on your own business? <a className="byo-link" href="/try">Click here</a>.</span>
        </div>
      </div>
    );
  }

  // ── Phase 2: business view ────────────────────────────────
  function BusinessView() {
    const [selected, setSelected] = useState(0);
    const convo = CONVOS[selected];

    return (
      <div className="dash" data-screen-label="Demo — business view">
        <div className="dash-list">
          <div className="dash-list-head">
            <span className="t-eyebrow">Conversations</span>
          </div>
          {CONVOS.map((c, i) => (
            <button key={c.name} className={"convo-row" + (i === selected ? " active" : "") + (c.unread ? " unread" : "")} onClick={() => setSelected(i)}>
              <span className="unread-dot"></span>
              <span className="avatar">{c.initials}</span>
              <span className="convo-meta">
                <span className="convo-top">
                  <span className="convo-name">{c.name}</span>
                  <span className="convo-time">{c.time}</span>
                </span>
                <span className="convo-snippet">{c.snippet}</span>
              </span>
            </button>
          ))}
        </div>
        <div className="dash-thread">
          <div className="thread-meta">
            <span className="avatar">{convo.initials}</span>
            <span>
              <span className="thread-name" style={{ display: "block" }}>{convo.name}</span>
              <span className="thread-phone">{convo.phone}</span>
            </span>
            <span className="thread-call"><PhoneGlyph /></span>
          </div>
          <div className="thread-body">
            {convo.thread.map((m, i) => (
              <ChatBubble key={selected + "-" + i} from={m.from}>{m.text}</ChatBubble>
            ))}
          </div>
        </div>
      </div>
    );
  }

  // ── Phase 2 shell ─────────────────────────────────────────
  function LiveDemo({ business }) {
    const [tab, setTab] = useState("customer");

    useEffect(() => {
      const sub = document.querySelector("#demo .section-sub");
      if (sub) { sub.textContent = ""; sub.style.display = "none"; }
    }, [tab]);

    return (
      <div className="phase phase-enter">
        <div className="tab-row tab-row-big" role="tablist">
          <button className={"tab-btn" + (tab === "customer" ? " active" : "")} role="tab" aria-selected={tab === "customer"} onClick={() => setTab("customer")}>Customer view</button>
          <button className={"tab-btn" + (tab === "business" ? " active" : "")} role="tab" aria-selected={tab === "business"} onClick={() => setTab("business")}>Business view</button>
        </div>
        {tab === "customer" ? <CustomerView business={business} /> : <BusinessView />}
      </div>
    );
  }

  // ── Root ──────────────────────────────────────────────────
  function DemoApp() {
    const [phase, setPhase] = useState("setup");
    const [exiting, setExiting] = useState(false);
    const [business, setBusiness] = useState({ name: GYM.name, number: GYM.number });

    const launch = (biz) => {
      const demoEl = document.getElementById("demo");
      if (demoEl) demoEl.dataset.live = "1";
      setBusiness(biz);
      setExiting(true);
      setTimeout(() => {
        setPhase("live");
        setExiting(false);
        // Snap the section's top flush to the bottom of the sticky header.
        const el = document.getElementById("demo");
        const nav = document.querySelector(".nav");
        if (el) {
          const navH = nav ? nav.getBoundingClientRect().height : 56;
          const top = window.scrollY + el.getBoundingClientRect().top - navH;
          window.scrollTo({ top: Math.max(0, top), behavior: "smooth" });
        }
      }, 300);
    };

    return phase === "setup" ? (
      <div className={exiting ? "phase phase-exit" : "phase"}>
        <SetupForm onLaunch={launch} />
      </div>
    ) : (
      <LiveDemo business={business} />
    );
  }

  return DemoApp;
})();

const demoRoot = document.getElementById("demo-root");
if (demoRoot) ReactDOM.createRoot(demoRoot).render(<Demo />);
