function normalizeCarouselPosition(position, cycleWidth) {
  if (cycleWidth <= 0) return position;
  return cycleWidth + ((position - cycleWidth) % cycleWidth + cycleWidth) % cycleWidth;
}

function CourseInterest({discovery, query, preferences, onSelectIntake, isMobile, onClearFilters}) {
  const [open, setOpen] = React.useState(false);
  const [busy, setBusy] = React.useState(false);
  const [error, setError] = React.useState('');
  const [success, setSuccess] = React.useState('');
  const [expanded, setExpanded] = React.useState(null);
  const [cycleRepeats, setCycleRepeats] = React.useState(1);
  const railRef = React.useRef(null);
  const railInteraction = React.useRef({hover: false, focus: false, until: 0});
  const matches = discovery?.matches || [];
  const recommendations = discovery?.recommendations || [];
  const filtered = discovery?.reason === 'filters' || (!query && !matches.length);
  const whatsapp = 'https://wa.me/6566905566?text=' + encodeURIComponent('Hi AKC, I would like to enquire about ' + (query || 'a course') + ' and available class dates.');
  const trigger = React.useRef(null);
  React.useLayoutEffect(() => {
    const rail = railRef.current;
    if (!rail || !recommendations.length) return;
    function sizeCycles() {
      const card = rail.querySelector('.akc-interest-card');
      const cardWidth = card?.getBoundingClientRect().width || 330;
      // Each repeated cycle must be wider than the viewport, including for one course.
      setCycleRepeats(Math.max(1, Math.ceil((rail.clientWidth + 18) / ((cardWidth + 18) * recommendations.length))));
    }
    sizeCycles();
    const observer = new ResizeObserver(sizeCycles);
    observer.observe(rail);
    return () => observer.disconnect();
  }, [discovery]);
  React.useLayoutEffect(() => {
    const rail = railRef.current;
    if (!rail) return;
    const cycles = rail.querySelectorAll('.akc-interest-cycle');
    if (cycles.length < 2) return;
    rail.scrollLeft = cycles[1].offsetLeft - cycles[0].offsetLeft;
    setExpanded(null);
  }, [discovery, cycleRepeats]);
  React.useEffect(() => {
    const rail = railRef.current;
    if (!rail || open || expanded) return;
    const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)');
    let frame, previous = 0, position = rail.scrollLeft;
    function move(now) {
      const elapsed = previous ? Math.min(now - previous, 50) : 0;
      previous = now;
      const interaction = railInteraction.current;
      const cycles = rail.querySelectorAll('.akc-interest-cycle');
      const cycleWidth = cycles.length > 1 ? cycles[1].offsetLeft - cycles[0].offsetLeft : 0;
      if (reducedMotion.matches || document.hidden || interaction.hover || interaction.focus || now < interaction.until || cycleWidth <= 0) {
        position = rail.scrollLeft;
      } else {
        // Equivalent repeated cards occupy both sides of the seam: no stop or visible reset.
        position = normalizeCarouselPosition(position + elapsed * 0.018, cycleWidth);
        rail.scrollLeft = position;
      }
      frame = requestAnimationFrame(move);
    }
    frame = requestAnimationFrame(move);
    return () => cancelAnimationFrame(frame);
  }, [discovery, open, expanded, cycleRepeats]);
  function moveRail(direction) {
    railInteraction.current.until = performance.now() + 8000;
    const rail = railRef.current;
    if (rail) {
      const cycles = rail.querySelectorAll('.akc-interest-cycle');
      const cycleWidth = cycles.length > 1 ? cycles[1].offsetLeft - cycles[0].offsetLeft : 0;
      if (!expanded && !railInteraction.current.focus) rail.scrollLeft = normalizeCarouselPosition(rail.scrollLeft, cycleWidth);
      rail.scrollBy({left: direction * (rail.clientWidth * 0.8), behavior: window.matchMedia('(prefers-reduced-motion: reduce)').matches ? 'auto' : 'smooth'});
    }
  }
  React.useEffect(() => {
    if (!open) return;
    const previous = document.activeElement;
    const oldOverflow = document.body.style.overflow;
    document.body.style.overflow = 'hidden';
    const dialog = document.getElementById('akc-interest-dialog');
    dialog?.querySelector('input:not([type=hidden])')?.focus();
    function keydown(e) {
      if (e.key === 'Escape' && !busy) setOpen(false);
      if (e.key !== 'Tab') return;
      const nodes = [...dialog.querySelectorAll('button:not(:disabled), input:not([type=hidden]), select, a[href]')].filter(n => n.offsetParent !== null);
      if (e.shiftKey && document.activeElement === nodes[0]) { e.preventDefault(); nodes[nodes.length-1]?.focus(); }
      if (!e.shiftKey && document.activeElement === nodes[nodes.length-1]) { e.preventDefault(); nodes[0]?.focus(); }
    }
    document.addEventListener('keydown', keydown);
    return () => { document.body.style.overflow = oldOverflow; document.removeEventListener('keydown', keydown); previous?.focus(); };
  }, [open, busy]);
  async function submit(event) {
    event.preventDefault();
    if (busy) return;
    const form = new FormData(event.currentTarget);
    setBusy(true); setError('');
    try {
      const result = await window.akcApiPost('course-interest', {
        name: form.get('name'), email: form.get('email'), phone: form.get('phone'),
        course_token: form.get('course_token') || '', query: form.get('query') || query,
        consent: form.get('consent') === 'on', website: form.get('website') || '',
        ...preferences,
        rep: sessionStorage.getItem('akc_salesperson_token') || '',
        source: sessionStorage.getItem('akc_registration_source') || 'website'
      });
      setSuccess(result.message || "Thanks! We'll contact you about this course.");
    } catch (e) { setError(e.message || 'Unable to send your enquiry. Please try again.'); }
    finally { setBusy(false); }
  }
  return <section className="akc-interest">
    <div className="akc-interest-hero">
      <div className="akc-interest-mark" aria-hidden="true">✦</div>
      <p className="akc-interest-eyebrow">YOUR NEXT STEP STARTS HERE</p>
      <h2>{filtered ? 'Let’s find a class that works for you.' : matches.length ? 'No available schedule for this course yet.' : 'Looking for a particular course?'}</h2>
      <p>{filtered ? 'No classes match your selected filters. Try other dates, languages or locations, or let us help you find a suitable class.' : 'Leave your details and we’ll get back to you about upcoming classes. You can also chat with our team.'}</p>
      <div className="akc-interest-actions">
        {filtered && <button type="button" className="akc-btn secondary" onClick={onClearFilters}>Clear class filters</button>}
        <button ref={trigger} type="button" className="akc-btn primary" onClick={() => {setError('');setSuccess('');setOpen(true);}}>Keep me updated</button>
        <a className="akc-btn secondary" href={whatsapp} target="_blank" rel="noopener noreferrer">Chat with us on WhatsApp ↗</a>
      </div>
    </div>
    {recommendations.length > 0 && <div className="akc-interest-related">
      <p className="akc-interest-eyebrow">EXPLORE MORE</p><h3>{discovery?.recommendation_title || 'Browse similar courses'}</h3>
      <p>{discovery?.recommendation_description || 'Courses with available classes. Check each course’s requirements before registering.'}</p>
      <div className="akc-interest-rail-controls" aria-label="Similar course controls">
        <button type="button" className="akc-btn secondary" onClick={()=>moveRail(-1)} aria-label="Previous courses">←</button>
        <button type="button" className="akc-btn secondary" onClick={()=>moveRail(1)} aria-label="Next courses">→</button>
      </div>
      <div ref={railRef} className="akc-interest-rail" role="region" aria-label="Similar courses"
        onPointerEnter={()=>{railInteraction.current.hover=true;}}
        onPointerLeave={()=>{railInteraction.current.hover=false;}}
        onFocusCapture={()=>{railInteraction.current.focus=true;}}
        onBlurCapture={e=>{if(!e.currentTarget.contains(e.relatedTarget))railInteraction.current.focus=false;}}
        onPointerDown={()=>{railInteraction.current.until=performance.now()+8000;}}
        onWheel={()=>{railInteraction.current.until=performance.now()+8000;}}
      >{[0, 1, 2].map(cycle => <div className="akc-interest-cycle" key={cycle}>
        {Array.from({length: cycleRepeats}, (_, repeat) => recommendations.map(course => {
          const cardKey = cycle + ':' + repeat + ':' + courseKey(course);
          return <div className="akc-interest-card" key={cardKey}>
            <CourseGroup course={course} expanded={expanded===cardKey} onToggle={() => setExpanded(expanded===cardKey?null:cardKey)} onSelectIntake={onSelectIntake} isMobile={true}/>
          </div>;
        }))}
      </div>)}</div>
    </div>}
    {open && <div className="akc-interest-overlay" onClick={e => {if(e.target===e.currentTarget && !busy)setOpen(false);}}>
      <div id="akc-interest-dialog" className="akc-interest-dialog" role="dialog" aria-modal="true" aria-labelledby="akc-interest-title">
        <button className="akc-interest-close" type="button" aria-label="Close" disabled={busy} onClick={()=>setOpen(false)}>×</button>
        <p className="akc-interest-eyebrow">LET’S STAY IN TOUCH</p><h2 id="akc-interest-title">Tell us what you’re looking for</h2>
        {success ? <div role="status"><p className="akc-interest-success">{success}</p><button type="button" className="akc-btn primary" onClick={()=>setOpen(false)}>Done</button></div> : <form onSubmit={submit}>
          <p>Our team will contact you about suitable course dates. This does not create a registration or reserve a seat.</p>
          {matches.length ? <label>Course<select name="course_token" defaultValue={matches[0].token}>{matches.map(c=><option key={c.token} value={c.token}>{c.name}</option>)}</select></label> : <label>Course you’re interested in<input name="query" defaultValue={query} required maxLength={120}/></label>}
          <label>Your name<input name="name" autoComplete="name" required minLength={2} maxLength={150}/></label>
          <label>Email address<input name="email" type="email" autoComplete="email" required maxLength={255}/></label>
          <label>Mobile number, including country code<input name="phone" type="tel" autoComplete="tel" placeholder="+65 9123 4567" required maxLength={25}/></label>
          <input name="website" type="hidden" defaultValue=""/>
          <label className="akc-interest-consent"><input name="consent" type="checkbox" required/><span>I agree to AKC contacting me about this course, in accordance with the <a href="https://www.sg-akc.com/privacy-policy/" target="_blank" rel="noopener noreferrer">PDPA notice</a>.</span></label>
          {error && <p className="akc-interest-error" role="alert">{error}</p>}
          <button type="submit" className="akc-btn primary" disabled={busy}>{busy?'Sending…':'Send my interest'}</button>
        </form>}
      </div>
    </div>}
  </section>;
}
