/* Poise onboarding - S17: scheduled desk focus session prompt.
   Shown after S16 coaching style, gated on the S5 workstyle answer: only for
   'sit' or 'mixed' (walking has no fixed schedule to set; Poise's activity
   detection already goes stricter while walking with nothing to configure). */

const { useState, useEffect, useLayoutEffect, useRef } = React;
const { Button: SchedButton } = window.PoiseDesignSystem_eee0d2;

/* ---------- iOS-style wheel column ---------- */
const WHEEL_ITEM_H = 34;
const WHEEL_VISIBLE = 5;

/* loop: hours/minutes wrap past their ends like the native picker (content is
   repeated in blocks; near an edge the scroll position teleports by a whole
   block, which is invisible because the content repeats). AM/PM doesn't loop. */
function Wheel({ items, value, onChange, width = 82, loop = true }) {
  const n = items.length;
  const reps = loop ? 7 : 1;
  const mid = Math.floor(reps / 2);
  const blockH = n * WHEEL_ITEM_H;
  const rows = loop ? Array.from({ length: n * reps }, (_, i) => items[i % n]) : items;
  const ref = useRef(null);
  const settleT = useRef(null);
  const lastIdx = useRef(0); /* modulo index, for detent ticks */
  const suppress = useRef(false);
  const H = WHEEL_ITEM_H * WHEEL_VISIBLE;
  const padH = WHEEL_ITEM_H * Math.floor(WHEEL_VISIBLE / 2);

  /* Position the wheel on its initial value (middle block when looping) before first paint */
  useLayoutEffect(() => {
    const el = ref.current;
    const idx = Math.max(0, items.indexOf(value));
    lastIdx.current = idx;
    if (el) {
      suppress.current = true;
      el.scrollTop = ((loop ? mid * n : 0) + idx) * WHEEL_ITEM_H;
      requestAnimationFrame(() => { suppress.current = false; });
    }
  }, []);

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

  const rowAt = (el) => Math.max(0, Math.min(rows.length - 1, Math.round(el.scrollTop / WHEEL_ITEM_H)));

  const onScroll = () => {
    const el = ref.current;
    if (!el || suppress.current) return;
    /* seamless wrap: shift by whole blocks near either end (modulo-preserving) */
    if (loop) {
      while (el.scrollTop < blockH) el.scrollTop += blockH;
      while (el.scrollTop > blockH * (reps - 1)) el.scrollTop -= blockH;
    }
    /* soft detent tick while the wheel turns */
    const idx = rowAt(el) % n;
    if (idx !== lastIdx.current) { lastIdx.current = idx; PoiseAudio.tick(); }
    /* commit once the wheel settles on a row */
    clearTimeout(settleT.current);
    settleT.current = setTimeout(() => {
      const el2 = ref.current;
      if (!el2) return;
      const i2 = rowAt(el2) % n;
      if (loop) {
        /* re-home into the middle block while idle */
        const home = (mid * n + i2) * WHEEL_ITEM_H;
        if (el2.scrollTop !== home) {
          suppress.current = true;
          el2.scrollTop = home;
          requestAnimationFrame(() => { suppress.current = false; });
        }
      }
      if (items[i2] !== value) onChange(items[i2]);
    }, 120);
  };

  const scrollToIdx = (i) => {
    const el = ref.current;
    if (el) el.scrollTo({ top: i * WHEEL_ITEM_H, behavior: 'smooth' });
  };

  return (
    <div ref={ref} className="wheel-col" onScroll={onScroll} style={{ width, height: H }}>
      <div style={{ height: padH, flexShrink: 0 }}></div>
      {rows.map((it, i) => (
        <button key={i} className="wheel-item" tabIndex={-1} style={{ height: WHEEL_ITEM_H }} onClick={() => scrollToIdx(i)}>{it}</button>
      ))}
      <div style={{ height: padH, flexShrink: 0 }}></div>
    </div>
  );
}

const WHEEL_HOURS = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'];
const WHEEL_MINS = ['00', '05', '10', '15', '20', '25', '30', '35', '40', '45', '50', '55'];
const WHEEL_MERIDIEM = ['AM', 'PM'];

function TimeWheels({ time, onChange }) {
  return (
    <div style={{ display: 'flex', justifyContent: 'center', padding: '6px 0 10px' }}>
      <div style={{ position: 'relative', display: 'flex' }}>
        {/* selection band behind the columns */}
        <div aria-hidden="true" style={{ position: 'absolute', top: WHEEL_ITEM_H * 2, left: -14, right: -14, height: WHEEL_ITEM_H, borderRadius: 9, background: 'var(--surface-elevated)' }}></div>
        <Wheel items={WHEEL_HOURS} value={time.h} onChange={(h) => onChange({ ...time, h })} />
        <Wheel items={WHEEL_MINS} value={time.m} onChange={(m) => onChange({ ...time, m })} />
        <Wheel items={WHEEL_MERIDIEM} value={time.ap} onChange={(ap) => onChange({ ...time, ap })} width={64} loop={false} />
      </div>
    </div>
  );
}

/* ---------- rows + disclosure ---------- */
function TimeRow({ label, time, open, onToggle }) {
  return (
    <button className="sched-row" aria-expanded={open} onClick={onToggle}>
      <span style={{ font: "400 17px 'SF Pro Text', sans-serif", color: 'var(--text-primary)' }}>{label}</span>
      <span className={`sched-chip${open ? ' open' : ''}`}>{time.h}:{time.m} {time.ap}</span>
    </button>
  );
}

function Disclosure({ open, children }) {
  return (
    <div style={{ height: open ? WHEEL_ITEM_H * WHEEL_VISIBLE + 16 : 0, overflow: 'hidden', transition: 'height 300ms var(--ease-out)' }}>
      {children}
    </div>
  );
}

/* ---------- days ---------- */
const SCHED_DAYS = [
  { k: 'mon', l: 'M', name: 'Monday' },
  { k: 'tue', l: 'T', name: 'Tuesday' },
  { k: 'wed', l: 'W', name: 'Wednesday' },
  { k: 'thu', l: 'T', name: 'Thursday' },
  { k: 'fri', l: 'F', name: 'Friday' },
  { k: 'sat', l: 'S', name: 'Saturday' },
  { k: 'sun', l: 'S', name: 'Sunday' },
];
const WEEKDAYS = ['mon', 'tue', 'wed', 'thu', 'fri'];

/* ---------- shared screen ---------- */
function SessionScheduleScreen({ kind, screenId, label, headline, body }) {
  const flow = useFlow();
  const saved = (flow.schedules || {})[kind];
  const [days, setDays] = useState(() => (saved && saved.days) || WEEKDAYS);
  const [start, setStart] = useState(() => (saved && saved.start) || { h: '9', m: '00', ap: 'AM' });
  const [end, setEnd] = useState(() => (saved && saved.end) || { h: '5', m: '00', ap: 'PM' });
  const [open, setOpen] = useState('start');

  const toggleDay = (k) => {
    PoiseAudio.tick();
    setDays((d) => (d.includes(k) ? d.filter((x) => x !== k) : SCHED_DAYS.map((s) => s.k).filter((x) => d.includes(x) || x === k)));
  };

  /* session length footnote: derived from live picker state (overnight wraps) */
  const toMin = (t) => ((parseInt(t.h, 10) % 12) + (t.ap === 'PM' ? 12 : 0)) * 60 + parseInt(t.m, 10);
  let dur = toMin(end) - toMin(start);
  if (dur <= 0) dur += 24 * 60;
  const durLabel = `${Math.floor(dur / 60)} hr${dur % 60 ? ` ${dur % 60} min` : ''}`;
  const daysLabel = days.length === 7 ? 'every day' : `${days.length} day${days.length === 1 ? '' : 's'} a week`;

  const fmt = (t) => `${t.h}:${t.m} ${t.ap}`;
  const save = () => {
    flow.setSchedule(kind, { days, start, end });
    track(`${kind}_sessions_set`, { days: days.join(','), start: fmt(start), end: fmt(end) });
    flow.next();
  };
  const skip = () => {
    flow.setSchedule(kind, null);
    track(`${kind}_sessions_skipped`, {});
    flow.next();
  };

  return (
    <Screen
      id={screenId} label={label}
      topBar={<TopBar onBack={() => flow.back()} />}
      cta={
        <React.Fragment>
          <SchedButton variant="primary" size="lg" fullWidth disabled={days.length === 0} onClick={save}>Set schedule</SchedButton>
          <button className="ghost-link" style={{ color: 'var(--mint)', fontWeight: 600 }} onClick={skip}>Skip for now</button>
        </React.Fragment>
      }
    >
      <div style={{ display: 'flex', flexDirection: 'column', paddingTop: 26 }}>
        <H style={{ fontSize: 27, marginBottom: 8 }}>{headline}</H>
        <P style={{ fontSize: 15, marginBottom: 24 }}>{body}</P>
        <div className="rise" style={{ animationDelay: '100ms' }}>
          <div style={{ background: 'var(--surface-card)', border: '1px solid var(--border-hairline)', borderRadius: 'var(--radius-card)', padding: '16px 16px 2px' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', paddingBottom: 16 }}>
              {SCHED_DAYS.map((d) => (
                <button key={d.k} className={`day-chip${days.includes(d.k) ? ' sel' : ''}`} aria-label={d.name} aria-pressed={days.includes(d.k)} onClick={() => toggleDay(d.k)}>{d.l}</button>
              ))}
            </div>
            <div style={{ borderTop: '1px solid var(--border-hairline)' }}>
              <TimeRow label="Starts" time={start} open={open === 'start'} onToggle={() => setOpen(open === 'start' ? null : 'start')} />
              <Disclosure open={open === 'start'}><TimeWheels time={start} onChange={setStart} /></Disclosure>
            </div>
            <div style={{ borderTop: '1px solid var(--border-hairline)' }}>
              <TimeRow label="Ends" time={end} open={open === 'end'} onToggle={() => setOpen(open === 'end' ? null : 'end')} />
              <Disclosure open={open === 'end'}><TimeWheels time={end} onChange={setEnd} /></Disclosure>
            </div>
          </div>
          <P style={{ fontSize: 13, marginTop: 12, textAlign: 'center' }}>
            {days.length === 0 ? 'Pick at least one day.' : `${durLabel} sessions, ${daysLabel}`}
          </P>
        </div>
      </div>
    </Screen>
  );
}

function DeskScheduleScreen() {
  return (
    <SessionScheduleScreen
      kind="desk" screenId="desk-schedule" label="S17 · Desk sessions"
      headline="When are you at your desk?"
      body="Poise reminds you to start a focus session during these hours. You can change this anytime, or skip for now."
    />
  );
}

Object.assign(window, { DeskScheduleScreen });
