(() => {
  const scenes = [
    {
      id: "roles",
      label: "동료에게 질문",
      title: <>동료의 AI에게<br />바로 물어보세요.</>,
      description: "담당자를 골라 평소처럼 질문하세요. 동료가 공유한 업무 맥락을 AI가 참고해 답합니다.",
      details: ["기획자도, 디자이너도 익숙한 대화창에서", "AI가 보낸 답변은 구분해서 표시"],
      icon: "chat",
    },
    {
      id: "features",
      label: "답변 범위 설정",
      title: <>어디까지 답할지는,<br />내가 정합니다.</>,
      description: "누구에게 어떤 주제까지 답할지 정하세요. 확인이 필요한 질문은 직접 답할 수 있습니다.",
      details: ["동료와 주제별 자동 답변·확인·거절", "Claude Code는 허용한 작업 폴더만 참고"],
      icon: "control",
    },
    {
      id: "follow-up",
      label: "이어서 대화",
      title: <>지난 대화에서<br />이어서 물어보세요.</>,
      description: "처음부터 다시 설명할 필요 없이, 궁금한 점을 이어서 물어보세요. 앞서 주고받은 대화를 참고해 답합니다.",
      details: ["이전 질문과 답변을 맥락으로 활용", "주고받은 내용은 대화 기록에서 다시 확인"],
      icon: "reply",
    },
    {
      id: "away",
      label: "부재 중에도 연결",
      title: <>동료가 자리를 비워도,<br />업무는 이어가세요.</>,
      description: "휴가 중인 동료에게 확인할 일이 생겼나요? 공유된 작업 맥락을 AI에게 묻고, 필요한 내용을 확인해 다음 일을 이어가세요.",
      details: ["동료가 허용한 업무 맥락 안에서 자동 답변", "동료의 앱이 켜져 있고 AI를 사용할 수 있을 때"],
      icon: "calendar",
    },
  ];
  const desktopQuery = "(min-width: 981px) and (min-height: 700px)";

  function StoryIcon({ name }) {
    return (
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
        {name === "chat" ? <path d="M20 11.5a8 8 0 0 1-8 8H5l-3 2v-10a9 9 0 0 1 18 0Z" /> : name === "control" ? <><path d="M5 3v7m0 4v7M12 3v12m0 4v2M19 3v2m0 4v12" /><path d="M2 10h6m1 5h6m1-10h6" /></> : name === "calendar" ? <><rect x="3" y="5" width="18" height="16" rx="2" /><path d="M7 3v4m10-4v4M3 11h18m-14 5 3 3 6-6" /></> : <><path d="m8 4-5 5 5 5" /><path d="M3 9h10a7 7 0 0 1 7 7v4" /></>}
      </svg>
    );
  }

  function MobileDemo({ step, reducedMotion }) {
    const demoRef = React.useRef(null);
    const [inView, setInView] = React.useState(false);

    React.useEffect(() => {
      const observer = new IntersectionObserver(([entry]) => {
        setInView(entry.isIntersecting && entry.intersectionRatio >= .35);
      }, { threshold: .35, rootMargin: "-68px 0px 0px 0px" });
      observer.observe(demoRef.current);
      return () => observer.disconnect();
    }, []);

    return <div className="ps-mobile-demo" ref={demoRef}><window.ProductDemo step={step} animate={inView && !reducedMotion} /></div>;
  }

  function ProductStory() {
    const sectionRef = React.useRef(null);
    const stepRefs = React.useRef([]);
    const [activeStep, setActiveStep] = React.useState(0);
    const [desktop, setDesktop] = React.useState(() => window.matchMedia(desktopQuery).matches);
    const [reducedMotion, setReducedMotion] = React.useState(() => window.matchMedia("(prefers-reduced-motion: reduce)").matches);
    const [motionEnabled, setMotionEnabled] = React.useState(true);
    const [inView, setInView] = React.useState(false);

    React.useEffect(() => {
      const layout = window.matchMedia(desktopQuery);
      const motion = window.matchMedia("(prefers-reduced-motion: reduce)");
      const updateLayout = () => setDesktop(layout.matches);
      const updateMotion = () => setReducedMotion(motion.matches);
      layout.addEventListener("change", updateLayout);
      motion.addEventListener("change", updateMotion);
      return () => {
        layout.removeEventListener("change", updateLayout);
        motion.removeEventListener("change", updateMotion);
      };
    }, []);

    React.useEffect(() => {
      if (!desktop) return;
      let frame = 0;
      let previousStep = -1;
      let previousVisible = null;
      const measure = () => {
        frame = 0;
        const viewportCenter = 68 + (window.innerHeight - 68) / 2;
        const bounds = sectionRef.current.getBoundingClientRect();
        const visible = bounds.top < viewportCenter && bounds.bottom > viewportCenter;
        if (visible !== previousVisible) {
          previousVisible = visible;
          setInView(visible);
        }
        let closest = 0;
        let distance = Infinity;
        stepRefs.current.forEach((step, index) => {
          const rect = step.getBoundingClientRect();
          const nextDistance = Math.abs(rect.top + rect.height / 2 - viewportCenter);
          if (nextDistance < distance) {
            distance = nextDistance;
            closest = index;
          }
        });
        if (closest !== previousStep) {
          previousStep = closest;
          setActiveStep(closest);
        }
      };
      const schedule = () => {
        if (!frame) frame = window.requestAnimationFrame(measure);
      };
      const resizeObserver = new ResizeObserver(schedule);
      resizeObserver.observe(sectionRef.current);
      window.addEventListener("scroll", schedule, { passive: true });
      window.addEventListener("resize", schedule);
      measure();
      return () => {
        window.cancelAnimationFrame(frame);
        resizeObserver.disconnect();
        window.removeEventListener("scroll", schedule);
        window.removeEventListener("resize", schedule);
      };
    }, [desktop]);

    const goToScene = (index) => {
      const rect = stepRefs.current[index].getBoundingClientRect();
      const viewportCenter = 68 + (window.innerHeight - 68) / 2;
      // Match the same center used by scroll tracking; never intercept wheel input.
      window.scrollTo({ top: window.scrollY + rect.top + rect.height / 2 - viewportCenter, behavior: "instant" });
      setActiveStep(index);
    };

    return (
      <section id="how" className="product-story" ref={sectionRef} aria-labelledby="ps-title">
        <div className="container">
          <div className="ps-intro">
            <h2 id="ps-title">VantaGreen 사용하기</h2>
            <p>스크롤하며 대화를 따라가 보세요 <span aria-hidden="true">↓</span></p>
          </div>
          <div className="ps-layout">
            <div className="ps-narrative">
              {scenes.map((scene, index) => (
                <article className="ps-step" id={scene.id} key={scene.id} ref={(node) => { stepRefs.current[index] = node; }} data-active={!desktop || index === activeStep} aria-labelledby={`ps-heading-${index}`}>
                  <div className="ps-copy">
                    <div className="ps-label"><StoryIcon name={scene.icon} /><span>{scene.label}</span></div>
                    <h3 id={`ps-heading-${index}`}>{scene.title}</h3>
                    <p className="ps-description">{scene.description}</p>
                    <ul>{scene.details.map((detail) => <li key={detail}><svg viewBox="0 0 16 16" fill="none" aria-hidden="true"><path d="m3 8 3 3 7-7" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /></svg>{detail}</li>)}</ul>
                  </div>
                  {!desktop && <MobileDemo step={index} reducedMotion={reducedMotion} />}
                </article>
              ))}
            </div>
            {desktop && <div className="ps-visual-column">
              <div className="ps-sticky">
                <window.ProductDemo step={activeStep} animate={inView && motionEnabled && !reducedMotion} />
                <div className="ps-demo-controls">
                  <div className="ps-scene-buttons" role="group" aria-label="데모 장면 선택">
                    {scenes.map((scene, index) => <button key={scene.id} type="button" onClick={() => goToScene(index)} aria-label={`${index + 1}. ${scene.label}`} aria-pressed={index === activeStep}><span aria-hidden="true" /></button>)}
                    <span className="ps-scene-count" aria-hidden="true">{activeStep + 1} / {scenes.length}</span>
                  </div>
                  {!reducedMotion && <button className="ps-motion-toggle" type="button" onClick={() => setMotionEnabled((enabled) => !enabled)} aria-pressed={motionEnabled}>{motionEnabled ? <svg viewBox="0 0 16 16" aria-hidden="true"><path d="M5 3v10M11 3v10" stroke="currentColor" strokeWidth="1.7" /></svg> : <svg viewBox="0 0 16 16" aria-hidden="true"><path d="m5 3 8 5-8 5Z" fill="currentColor" /></svg>}{motionEnabled ? "움직임 끄기" : "움직임 켜기"}</button>}
                </div>
              </div>
            </div>}
          </div>
        </div>
      </section>
    );
  }

  window.ProductStory = ProductStory;
})();
