/* Root app — Icon, StatusBar, 3-flow router, HomeView state machine */
const { useState, useEffect, useRef } = React;

function Icon({ name, size = 24, color = 'currentColor', style, className }) {
  const html = window.HS_ICONS && window.HS_ICONS[name] || '';
  return (
    <span className={"ic" + (className ? " " + className : "")} aria-hidden="true"
    style={{ width: size, height: size, color, ...style }}
    dangerouslySetInnerHTML={{ __html: html }} />);

}
window.Icon = Icon;

function StatusBar({ light = false }) {
  return (
    <div className={"statusbar" + (light ? " light" : "")}>
      <span>9:41</span>
      <div className="sb-icons">
        <svg viewBox="0 0 19 12" width="18" height="11">
          <rect x="0" y="7.5" width="3.2" height="4.5" rx=".7" fill="currentColor" />
          <rect x="4.8" y="5" width="3.2" height="7" rx=".7" fill="currentColor" />
          <rect x="9.6" y="2.5" width="3.2" height="9.5" rx=".7" fill="currentColor" />
          <rect x="14.4" y="0" width="3.2" height="12" rx=".7" fill="currentColor" />
        </svg>
        <svg viewBox="0 0 17 13" width="16" height="12">
          <path d="M8.5 3.2c2.3 0 4.4.9 5.9 2.4l1.1-1.1C13.7 2.7 11.2 1.5 8.5 1.5S3.3 2.7 1.5 4.5l1.1 1.1C4.1 4.1 6.2 3.2 8.5 3.2z" fill="currentColor" />
          <path d="M8.5 6.8c1.4 0 2.6.5 3.5 1.4l1.1-1.1c-1.3-1.2-2.9-2-4.6-2s-3.3.8-4.6 2L5 8.2c.9-.9 2.1-1.4 3.5-1.4z" fill="currentColor" />
          <circle cx="8.5" cy="10.5" r="1.5" fill="currentColor" />
        </svg>
        <svg viewBox="0 0 27 13" width="25" height="12">
          <rect x=".5" y=".5" width="23" height="12" rx="3.5" stroke="currentColor" strokeOpacity=".35" fill="none" />
          <rect x="2" y="2" width="20" height="9" rx="2" fill="currentColor" />
          <path d="M25 4.5v4c.8-.3 1.5-1.3 1.5-2s-.7-1.7-1.5-2z" fill="currentColor" fillOpacity=".5" />
        </svg>
      </div>
    </div>);

}
window.StatusBar = StatusBar;

/* ----- Ebb's canned-but-contextual responder ----- */
function ebbReply(text) {
  const t = (text || '').toLowerCase();
  if (/sleep|tired|insomnia|awake|rest|can't sleep|exhaust/.test(t))
  return { text: "It sounds like rest has been hard to come by. Let's ease the day down gently — here's something to help you wind down tonight.", recs: ['sleep', 'compassion'] };
  if (/focus|work|deadline|distract|procrast|study|concentrat/.test(t))
  return { text: "A busy mind is tough to steer. Before you dive back in, let's anchor your attention — this can help you find a steadier gear.", recs: ['focus', 'grounded'] };
  if (/sad|down|lonely|hard|cry|low|grief|hurt/.test(t))
  return { text: "Thank you for trusting me with that. Be gentle with yourself today — here's a small, kind pause to come back to.", recs: ['compassion', 'reframe'] };
  if (/stress|anxious|anxiety|overwhelm|panic|nervous|worried|tense|pressure/.test(t))
  return { text: "Welcome. I'm grateful you're here. That pressure is real — let's loosen its grip together, starting with the breath.", recs: ['reframe', 'grounded'] };
  return { text: "Welcome. I'm grateful you're here. Whatever's on your mind, let's take it one breath at a time — here's a gentle place to begin.", recs: ['grounded', 'reframe'] };
}
window.ebbReply = ebbReply;

let MID = 1;
const nextId = () => MID++;

/* ============================================================
   App — flow picker + view router
   Flow 1: onboarding → notif dialog → personalizing → home (personalized)
   Flow 2: lock → home (Ebb care conversation → Care scheduling → side menu)
   Flow 3: lock → player (Deep Sleep) → personalizing → home
   ============================================================ */
function App() {
  const D = window.HS_DATA;
  const [flow, setFlow] = useState(1);
  const [view, setView] = useState('onboarding'); // onboarding | notif | lock | player | personalizing | home
  const [period, setPeriod] = useState('morning');
  const [homeEntry, setHomeEntry] = useState(null); // null | care | personalized
  const [homeKey, setHomeKey] = useState(0);

  const Onboarding = window.Onboarding;
  const FlowSelector = window.FlowSelector;
  const LockScreen = window.LockScreen;
  const NotificationDialog = window.NotificationDialog;
  const PersonalizingInterstitial = window.PersonalizingInterstitial;

  function startFlow(f) {
    setFlow(f);
    setHomeEntry(null);
    setHomeKey((k) => k + 1);
    if (f === 1) { setPeriod('morning'); setView('onboarding'); }
    else if (f === 2) { setPeriod('morning'); setView('lock'); }
    else if (f === 3) { setPeriod('night'); setView('lock'); }
  }

  const goHome = (entry) => { setHomeEntry(entry || null); setView('home'); };

  // Flow 1
  const onbFinish = () => setView('notif');
  const onbSkip = () => { setHomeEntry(null); setView('home'); };
  const notifResolved = () => { setHomeEntry(null); setView('personalizing'); };
  // Flow 2 & 3
  const lockTap = () => { if (flow === 2) goHome('care'); else setView('player'); };
  const sleepPlayerClose = () => { setPeriod('night'); setHomeEntry('personalized'); setView('personalizing'); };
  const personalizingDone = () => setView('home');

  const isDark = period === 'night';
  const showChrome = view === 'onboarding' || view === 'notif' || view === 'home' || view === 'personalizing';
  const showHome = view === 'home' || view === 'personalizing';

  return (
    <div className="stage">
      <FlowSelector flow={flow} onSelect={startFlow} />

      <div className={"phone " + period + (isDark ? ' dark' : '')} id="phone">
        <div className="island"></div>

        <div className="clouds">
          <div className="cloud" style={{ width: 180, height: 90, left: -30, top: 230 }}></div>
          <div className="cloud" style={{ width: 150, height: 70, right: -20, top: 300 }}></div>
          <div className="cloud" style={{ width: 220, height: 100, left: 40, top: 380 }}></div>
        </div>

        {showChrome && <StatusBar />}

        {(view === 'onboarding' || view === 'notif') &&
          <Onboarding onFinish={onbFinish} onSkip={onbSkip} />}
        {view === 'notif' &&
          <NotificationDialog onAllow={notifResolved} onDeny={notifResolved} />}

        {view === 'lock' &&
          <LockScreen variant={flow === 3 ? 'sleep' : 'care'} onTap={lockTap} />}

        {view === 'player' &&
          <Player content={D.C.deepsleep} onClose={sleepPlayerClose} />}

        {showHome &&
          <HomeView key={homeKey} period={period} setPeriod={setPeriod} entry={homeEntry} flow={flow} />}
        {view === 'personalizing' &&
          <PersonalizingInterstitial flow={flow} onDone={personalizingDone} />}

        {showChrome && <div className="home-bar"></div>}
      </div>
    </div>);
}

/* ----- Home surface — Today content + Ebb overlay sheet + Care + Drawer ----- */
function HomeView({ period, setPeriod, entry, flow }) {
  const D = window.HS_DATA;
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [drawerCare, setDrawerCare] = useState(false);
  const [drawerTip, setDrawerTip] = useState(false);
  const [player, setPlayer] = useState(null);
  const [messages, setMessages] = useState([]);
  const [pending, setPending] = useState(false);
  const [draft, setDraft] = useState('');
  const [ebbOpen, setEbbOpen] = useState(false);
  const [kbUp, setKbUp] = useState(false);
  const [searchOpen, setSearchOpen] = useState(false);
  const [tab, setTab] = useState('today');
  const [chipSet, setChipSet] = useState('none'); // none | care (default chips are inline in the greeting card)
  const [careStage, setCareStage] = useState(null);  // null | connecting | scheduling
  const [stateVal, setStateVal] = useState('California');
  const [feedUpdated, setFeedUpdated] = useState(false); // Flow 1: feed adjusted after the Ebb chat
  const [adjusting, setAdjusting] = useState(false);     // "Adjusting your plan…" interstitial
  const PersonalizingInterstitial = window.PersonalizingInterstitial;
  const personalized = entry === 'personalized';
  const careMode = entry === 'care';

  // Flow 2 — tapping the notification opens a FRESH Ebb chat: greeting +
  // quick actions, with a half-typed message and the keyboard up. The grief
  // conversation only unfolds once Blake sends.
  useEffect(() => {
    if (entry === 'care') {
      setChipSet('none');
      setEbbOpen(true);
      setKbUp(true);
    }
  }, []); // once

  const openEbb = () => { setEbbOpen(true); setKbUp(true); };

  // Swipe up from the bottom 10% of the screen to summon Ebb
  const swipeRef = useRef({});
  useEffect(() => {
    const phone = document.getElementById('phone');
    if (!phone) return;
    const g = swipeRef.current;
    const pt = (e) => e.touches && e.touches[0] ? e.touches[0] : e;
    const down = (e) => {
      g.active = false;
      if (ebbOpen || drawerOpen || player || searchOpen) return;
      const r = phone.getBoundingClientRect();
      const p = pt(e);
      if (p.clientX < r.left || p.clientX > r.right) return;
      if (p.clientY < r.bottom - r.height * 0.10) return;
      g.active = true; g.startY = p.clientY; g.fired = false;
    };
    const move = (e) => {
      if (!g.active || g.fired) return;
      if (g.startY - pt(e).clientY > 40) { g.fired = true; g.active = false; openEbb(); }
    };
    const end = () => { g.active = false; };
    phone.addEventListener('pointerdown', down);
    phone.addEventListener('pointermove', move);
    phone.addEventListener('pointerup', end);
    phone.addEventListener('pointercancel', end);
    return () => {
      phone.removeEventListener('pointerdown', down);
      phone.removeEventListener('pointermove', move);
      phone.removeEventListener('pointerup', end);
      phone.removeEventListener('pointercancel', end);
    };
  }, [ebbOpen, drawerOpen, player, searchOpen]);

  const closeEbb = () => {
    setEbbOpen(false); setKbUp(false);
    if (careStage === 'scheduling') { setDrawerOpen(true); setDrawerCare(true); setDrawerTip(true); }
    // Flow 1 — closing the Ebb conversation adjusts the Today feed based on it
    else if (flow === 1 && !feedUpdated && messages.some((m) => m.from === 'me')) {
      setAdjusting(true);
    }
  };
  const openPlayer = (content) => { setPlayer(content); setDrawerOpen(false); setEbbOpen(false); setKbUp(false); setSearchOpen(false); };
  const searchToEbb = (text) => { setSearchOpen(false); sendQuick(text); };

  function pushEbb(userText) {
    setPending(true);
    const reply = window.ebbReply(userText);
    window.setTimeout(() => {
      setPending(false);
      setMessages((m) => [...m, { id: nextId(), from: 'ebb', text: reply.text, recs: reply.recs, revealed: 1 }]);
    }, 1500);
  }
  function send() {
    const text = draft.trim();
    if (!text) { setKbUp(false); return; }
    if (careMode && !messages.some((m) => m.careOffer)) {
      const ebbTurns = messages.filter((m) => m.from === 'ebb').length;
      setDraft(''); setKbUp(false);
      setMessages((m) => [...m, { id: nextId(), from: 'me', text }]);
      setPending(true);
      window.setTimeout(() => {
        setPending(false);
        if (ebbTurns === 0) {
          setMessages((m) => [...m, { id: nextId(), from: 'ebb', text: "That sounds really overwhelming — like there's too much coming at you at once and not enough time to get through it all.\n\nWhen you look at everything in front of you, what feels most pressing or hardest to face right now?" }]);
        } else {
          setMessages((m) => [...m, { id: nextId(), from: 'ebb', careOffer: true, text: "A loss like this is so, so tough, Blake. Navigating the shock and grief, all while taking care of family responsibilities, is a lot to carry. And having work demands on top of that can make everything feel even more impossible.\n\nWould talking to someone whether a phone or video chat help? I can help you connect to the care you need." }]);
        }
      }, ebbTurns === 0 ? 1500 : 1800);
      return;
    }
    const firstDefault = !careMode && messages.filter((m) => m.from === 'me').length === 0;
    setDraft(''); setKbUp(false);
    setMessages((m) => [...m, { id: nextId(), from: 'me', text }]);
    if (firstDefault) {
      setPending(true);
      window.setTimeout(() => {
        setPending(false);
        setMessages((m) => [...m, { id: nextId(), from: 'ebb', text: "That sounds like a heavy loop to be in, Blake. When work feels nonstop, routines can be the first thing to slip. And then sleep gets harder, which makes everything feel even bigger.\n\nWhat feels most present right now: the stress from work, or the frustration of not being able to wind down at night?" }]);
      }, 1600);
      return;
    }
    pushEbb(text);
  }
  function sendQuick(text) {
    setEbbOpen(true); setKbUp(false);
    setMessages((m) => [...m, { id: nextId(), from: 'me', text }]);
    pushEbb(text);
  }
  function newChat() { setMessages([]); setPending(false); setDraft(''); setKbUp(true); setChipSet('none'); setCareStage(null); }

  // Flow 2 — Blake taps "Schedule Care": the tile becomes a sent message, Ebb
  // connects, then the thread collapses into a summary + Care Scheduling panel.
  function scheduleCare() {
    setChipSet('none');
    setMessages((m) => [...m, { id: nextId(), from: 'me', kind: 'action', text: 'Schedule Care', icon: 'calendar' }]);
    window.setTimeout(() => {
      setMessages((m) => [...m, { id: nextId(), from: 'ebb', text: 'Connecting you with Care scheduling' }]);
      setPending(true); setCareStage('connecting');
      window.setTimeout(() => { setPending(false); setCareStage('scheduling'); }, 3600);
    }, 480);
  }
  function sos() {
    setChipSet('none');
    setMessages((m) => [...m, { id: nextId(), from: 'me', kind: 'action', text: 'SOS', icon: 'qa-sos' }]);
    setPending(true);
    window.setTimeout(() => {
      setPending(false);
      setMessages((m) => [...m, { id: nextId(), from: 'ebb', text: "You don't have to hold this alone. I'm connecting you with urgent support right now — help is one tap away." }]);
    }, 1500);
  }

  const greetingText = careMode ? "Hi, Blake. Glad you're here. What's on your mind right now?" : (flow === 1 ? "Blake, you mentioned work stress earlier — what feels most challenging right now?" : undefined);  const greetBadge = careMode ? "Based on Apple Health · Resting HR 72 bpm" : undefined;  const introChips = careMode ? [
    { label: 'Breathing exercise', icon: 'breath', color: 'var(--hs-warm-grey-700)', onClick: () => openPlayer(D.C.grounded) },
    { label: 'Meditate', icon: 'qa-meditate', color: 'var(--hs-orange-200, #FF7300)', onClick: () => openPlayer(D.FEATURE) },
  ] : [
    { label: 'Meditate', icon: 'qa-meditate', color: 'var(--hs-orange-200, #FF7300)', onClick: () => openPlayer(D.FEATURE) },
    { label: 'Check-in', icon: 'qa-checkin', color: 'var(--hs-green-200, #02873E)', onClick: () => sendQuick("I'd like to check in") },
  ];

  // Scripted replies Blake auto-types when he taps the field (Flow 2)
  let careScript = null;
  if (careMode && !messages.some((m) => m.careOffer)) {
    const userMsgs = messages.filter((m) => m.from === 'me').length;
    careScript = userMsgs === 0
      ? "i'm feeling really stressed, i can't handle all the things i need to deal with by the end of the day."
      : userMsgs === 1
        ? "well my cousin passed away suddenly and i have a lot of family stuff to deal with. and it's all on top of my already stressful workload. i'm completely overwhelmed"
        : null;
  } else if (!careMode && messages.filter((m) => m.from === 'me').length === 0) {
    careScript = "Work has been a lot lately. I keep telling myself I'm going to get back into a routine, but every time the week gets busy, I fall off. Now I'm tired, behind, and I can't sleep.";
  }

  return (
    <React.Fragment>
      <Drawer open={drawerOpen} onClose={() => setDrawerOpen(false)} onOpenPlayer={openPlayer}
        care={drawerCare} tooltip={drawerTip} onDismissTip={() => setDrawerTip(false)} streakCount={drawerCare ? 2 : 0} />

      <div className={"screen-push" + (drawerOpen ? " pushed" : "")}>
        <div className="chrome">
          <button className="chrome-btn" aria-label="Your journey" onClick={() => { setKbUp(false); setDrawerOpen((o) => !o); }}>
            <Icon name="explore" size={24} className="ic-inset" />
          </button>
        </div>

        <div className="top-fade"></div>

        <MainScreen onOpenPlayer={openPlayer} period={period} setPeriod={setPeriod} personalized={personalized} updated={feedUpdated} />

        {!ebbOpen && <EbbFab onTap={openEbb} />}

        <TabBar active={tab} setActive={setTab} onSearch={() => setSearchOpen(true)} detaching={ebbOpen} />

        <EbbSheet open={ebbOpen} kbUp={kbUp}
          messages={messages} pending={pending}
          draft={draft} setDraft={setDraft}
          chipSet={chipSet} careStage={careStage}
          stateVal={stateVal} setStateVal={setStateVal}
          greetingText={greetingText} greetBadge={greetBadge} introChips={introChips}
          careScript={careScript}
          onClose={closeEbb} onNewChat={newChat}
          onRaiseKb={() => setKbUp(true)} onDropKb={() => setKbUp(false)}
          onSend={send}
          onChar={(ch) => setDraft((d) => d + ch)}
          onBackspace={() => setDraft((d) => d.slice(0, -1))}
          onOpenPlayer={openPlayer}
          onReveal={(id) => setMessages((m) => m.map((x) => x.id === id ? { ...x, revealed: (x.revealed || 1) + 1 } : x))}
          onMeditate={() => openPlayer(D.FEATURE)} onCheckIn={() => sendQuick("I'd like to check in")}
          onScheduleCare={scheduleCare} onSOS={sos} />

        <div className={"push-scrim" + (drawerOpen ? " open" : "")} onClick={() => setDrawerOpen(false)}></div>
      </div>

      <Player content={player} onClose={() => setPlayer(null)} />

      {adjusting && PersonalizingInterstitial &&
        <PersonalizingInterstitial light duration={2000}
          label="Adjusting your plan based on your responses…"
          onDone={() => { setAdjusting(false); setFeedUpdated(true); }} />}

      <SearchOverlay open={searchOpen} onClose={() => setSearchOpen(false)}
        onSearch={searchToEbb} onOpenPlayer={openPlayer} />
    </React.Fragment>);
}

/* ----- Bottom navigation ----- */
function TabBar({ active, setActive, onSearch, detaching }) {
  return (
    <div className={"nav" + (detaching ? " detaching" : "")}>
      <div className="nav-main" data-comment-anchor="34e54b44bd-div-228-7">
        <button className={"nav-tab" + (active === 'today' ? " is-active" : "")}
          onClick={() => setActive('today')} aria-label="Today">
          <Icon name="today" size={24} />
          <span>Today</span>
        </button>
        <div className="nav-ebb-slot"><span>Ebb</span></div>
        <button className={"nav-tab" + (active === 'care' ? " is-active" : "")}
          onClick={() => setActive('care')} aria-label="Care">
          <Icon name="care" size={24} />
          <span>Care</span>
        </button>
      </div>
      <button className="nav-explore" onClick={onSearch} aria-label="Explore">
        <Icon name="search-line" size={24} />
        <span>Explore</span>
      </button>
    </div>);
}
window.TabBar = TabBar;

function EbbFab({ onTap }) {
  return (<button className="ebb-fab" aria-label="Talk to Ebb" onClick={onTap}></button>);
}
window.EbbFab = EbbFab;

/* scale phone to fit viewport */
function fitPhone() {
  const p = document.getElementById('phone');
  if (!p) return;
  const stacked = window.matchMedia('(max-width: 920px)').matches;
  const m = 24;
  const phoneW = 393;
  const phoneH = 852;
  const sideReserve = stacked ? 0 : 200;
  const s = Math.min(
    (window.innerWidth - m * 2 - sideReserve) / phoneW,
    (window.innerHeight - m * 2) / phoneH,
    1
  );
  const scale = Math.max(0.4, s);
  p.style.transform = `scale(${scale})`;
  // transform doesn't shrink layout; pull Flows up so the visual gap is ~80px when stacked
  if (stacked) {
    p.style.marginBottom = `${80 - phoneH * (1 - scale)}px`;
  } else {
    p.style.marginBottom = '';
  }
}
window.addEventListener('resize', fitPhone);

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
window.setTimeout(fitPhone, 60);
