// Chat / Stack / Schedule screens

// ─────────────────────────────────────────────────────────────────────────────
// CHAT SCREEN — analyzing → recommendation conversation
// ─────────────────────────────────────────────────────────────────────────────
function ChatScreen({ accent, goal, profile, onViewStack, onOpenVoice, customSchedule, setCustomSchedule, onViewSchedule }) {
  const protocol = GOAL_PROTOCOLS[goal];
  const [messages, setMessages] = React.useState([]);
  const [phase, setPhase] = React.useState('thinking'); // thinking | done
  const [draft, setDraft] = React.useState('');
  const [recording, setRecording] = React.useState(false);
  const [waiting, setWaiting] = React.useState(false);
  const [photoOpen, setPhotoOpen] = React.useState(false);
  const scrollRef = React.useRef(null);

  // Detect when the user wants the AI to build/update their calendar
  const wantsCalendar = (text) => /\b(calendar|schedule|track|plan|protocol|cycle|weekly|reminder)\b/i.test(text)
    && /\b(add|create|build|make|generate|set up|setup|start|track|put|push|save)\b/i.test(text);

  // Ask Gemini to produce a structured JSON schedule. Returns parsed object or null.
  const generateSchedule = async (userPromptText) => {
    if (!window.geminiText) return null;
    const peptideRefs = protocol.stack.map((id) => {
      const p = PEPTIDES[id];
      return `- ${p.name} (id: "${id}"): ${p.dose}, ${p.frequency}, ${p.route}, color ${p.color}, category ${p.category}`;
    }).join('\n');

    const prompt = `You are Pepagent's scheduling engine. The user wants to build a dosing calendar.

User goal: ${protocol.label}
Stack: ${protocol.stack.join(' + ')}
Duration: ${protocol.duration}
User: ${profile.weight}kg, ${profile.age}y, ${profile.experience}

Peptide reference (use these exact ids and colors):
${peptideRefs}

User's latest request: "${userPromptText}"

Output ONLY a JSON object — no markdown, no code fences, no commentary. Schema:
{
  "label": "<goal label>",
  "duration": "<e.g. 8 weeks>",
  "weeks": <integer number of weeks>,
  "rationale": "<one sentence explaining the timing logic>",
  "stack": [
    {
      "id": "<peptide id from reference list>",
      "name": "<display name>",
      "dose": "<e.g. 250mcg>",
      "time": "<HH:MM in 24h, e.g. 08:00 or 21:30>",
      "days": [<0=Mon..6=Sun array of dose days>],
      "color": "<hex color from reference>",
      "category": "<category from reference>"
    }
  ]
}

Pick dose times based on each peptide's pharmacology (GH-releasers before bed, BPC-157 with meals, cognitive peptides in the morning). Pick days based on the peptide's frequency (daily=all 7, 2× weekly=Mon+Thu, 5× weekly=Mon-Fri, etc.). Be precise.`;

    try {
      const raw = await window.geminiText(prompt);
      // Strip any code fences or stray prose
      const cleaned = String(raw).replace(/```json\s*|```/g, '').trim();
      const start = cleaned.indexOf('{');
      const end = cleaned.lastIndexOf('}');
      if (start < 0 || end < 0) return null;
      const json = JSON.parse(cleaned.slice(start, end + 1));
      if (!json.stack || !Array.isArray(json.stack) || json.stack.length === 0) return null;
      return json;
    } catch (e) {
      console.warn('[Pepagent] schedule generation failed:', e);
      return null;
    }
  };

  // Scripted analyzing sequence — runs once per goal, then a flag in
  // localStorage suppresses replays so navigation back to chat doesn't
  // re-trigger the intro.
  React.useEffect(() => {
    const introKey = `pepagent.introShown.${goal}`;
    if (localStorage.getItem(introKey)) {
      // Skip intro — show the recommendation card immediately so the chat
      // surface isn't empty for returning users.
      setMessages([
        { who: 'user', text: `I want to focus on ${protocol.label.toLowerCase()}.` },
        { who: 'agent', text: protocol.summary },
        { who: 'agent', kind: 'recommendation' },
      ]);
      setPhase('done');
      return;
    }
    const seq = [
      { delay: 600, msg: { who: 'user', text: `I want to focus on ${protocol.label.toLowerCase()}.` } },
      { delay: 1100, msg: { who: 'agent', kind: 'status', text: 'Analyzing goal vector…' } },
      { delay: 800, msg: { who: 'agent', kind: 'status', text: `Cross-referencing ${profile.weight}kg / age ${profile.age} / ${profile.experience}…` } },
      { delay: 900, msg: { who: 'agent', kind: 'status', text: 'Screening 23 peptide candidates against contraindications…' } },
      { delay: 800, msg: { who: 'agent', kind: 'status', text: `Selected: ${protocol.stack.join(' + ')}` } },
      { delay: 800, msg: { who: 'agent', text: protocol.summary } },
      { delay: 600, msg: { who: 'agent', kind: 'recommendation' } },
    ];
    let acc = 0;
    const timers = [];
    seq.forEach((s) => {
      acc += s.delay;
      timers.push(setTimeout(() => {
        setMessages((m) => [...m, s.msg]);
        if (s.msg.kind === 'recommendation') {
          setPhase('done');
          try { localStorage.setItem(introKey, '1'); } catch (e) {}
        }
      }, acc));
    });
    return () => timers.forEach(clearTimeout);
  }, [goal]);

  React.useEffect(() => {
    const el = scrollRef.current;
    if (el) el.scrollTop = el.scrollHeight;
  }, [messages]);

  const send = async () => {
    if (!draft.trim() || waiting) return;
    const userText = draft;
    const newMessages = [...messages, { who: 'user', text: userText }];
    setMessages(newMessages);
    setDraft('');
    setWaiting(true);

    // Calendar intent — generate a structured schedule and surface a card in chat.
    if (wantsCalendar(userText) && setCustomSchedule) {
      try {
        const sched = await generateSchedule(userText);
        if (sched) {
          setCustomSchedule(sched);
          setMessages((m) => [
            ...m,
            { who: 'agent', text: `Done — I built a ${sched.weeks || sched.duration || ''} schedule for ${sched.stack.map((s) => s.name).join(' + ')}. ${sched.rationale || ''}`.trim() },
            { who: 'agent', kind: 'schedule-card', schedule: sched },
          ]);
          setWaiting(false);
          return;
        }
        // Fall through to normal reply if generation failed
      } catch (e) {
        console.warn('[Pepagent] calendar gen error:', e);
      }
    }

    try {
      const sysContext = `You are Pepagent, a knowledgeable but cautious AI peptide protocol advisor. Speak conversationally — short paragraphs (2-4 sentences max), no markdown, no bullet points. Mention "consult a clinician" only when the user asks about dosing, side effects, or starting a protocol — not on every reply.

CRITICAL: Read the full conversation below and remember what the user has already said. Do NOT re-ask questions they have already answered. Build on prior turns — be decisive and move the protocol forward.

If the user asks to add the protocol to their calendar / schedule / track it, tell them you'll build it now and offer to confirm — the system will detect that intent automatically and generate it.

Current user goal: ${protocol.label}. Recommended stack: ${protocol.stack.join(' + ')}. Duration: ${protocol.duration}. Summary: ${protocol.summary}
User profile: ${profile.weight}kg, ${profile.age} years old, ${profile.experience} experience.

Available peptides: BPC-157, TB-500, CJC-1295, Ipamorelin, GHK-Cu, Tesamorelin, Semax, Selank, Epitalon. Reference real dosing, half-lives, and mechanisms when relevant.`;

      const transcript = newMessages
        .filter((m) => m.text && !m.kind)
        .map((m) => (m.who === 'user' ? `USER: ${m.text}` : `PEPAGENT: ${m.text}`))
        .join('\n');

      const fullPrompt = `${sysContext}\n\n=== CONVERSATION SO FAR ===\n${transcript}\n=== END ===\n\nReply now as PEPAGENT. Output only what you would say next — no labels, no quotes.`;

      let reply;
      if (window.claude?.complete) {
        const claudeMsgs = newMessages
          .filter((m) => m.text && !m.kind)
          .map((m) => ({ role: m.who === 'user' ? 'user' : 'assistant', content: m.text }));
        claudeMsgs.unshift({ role: 'user', content: sysContext + '\n\n(Begin replying.)' });
        reply = await window.claude.complete({ messages: claudeMsgs });
      } else if (window.geminiText) {
        reply = await window.geminiText(fullPrompt);
      } else {
        reply = followUpReply(userText, protocol);
      }
      setMessages((m) => [...m, { who: 'agent', text: String(reply || '').trim() || followUpReply(userText, protocol) }]);
    } catch (e) {
      console.warn('[Pepagent] chat reply failed:', e);
      setMessages((m) => [...m, { who: 'agent', text: followUpReply(userText, protocol) }]);
    }
    setWaiting(false);
  };

  const orbState = phase === 'thinking' ? 'thinking' : (recording ? 'listening' : 'idle');
  const orbIntensity = phase === 'thinking' ? 0.7 : (recording ? 0.85 : 0.35);

  return (
    <div className="screen chat" data-screen-label="03 Chat">
      <div className="chat-rail">
        <div className="rail-orb">
          <Orb size={180} intensity={orbIntensity} color={accent} state={orbState} />
        </div>
        <div className="rail-state">
          <div className="rail-eyebrow">AGENT STATE</div>
          <div className="rail-status">
            <span className="rail-dot" style={{ background: accent }} />
            {phase === 'thinking' ? 'ANALYZING' : recording ? 'LISTENING' : 'READY'}
          </div>
        </div>
        <div className="rail-meta">
          <div className="rail-row"><span>GOAL</span><b>{protocol.label}</b></div>
          <div className="rail-row"><span>SUBJECT</span><b>{profile.weight}kg · {profile.age}y</b></div>
          <div className="rail-row"><span>EXPERIENCE</span><b>{profile.experience}</b></div>
          <div className="rail-row"><span>SESSION</span><b className="mono">PA-{Math.floor(Math.random() * 99000 + 1000)}</b></div>
        </div>
        {phase === 'done' && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
            <button className="cta" style={{ '--accent': accent }} onClick={onOpenVoice}>
              <Icon.mic /> TALK TO PEPAGENT
            </button>
            <button className="ghost" onClick={onViewStack}>VIEW STACK</button>
          </div>
        )}
      </div>

      <div className="chat-main">
        <div className="chat-header">
          <div className="chat-title">CONSULTATION TRANSCRIPT</div>
          <div className="chat-time">SESSION 14:{String(messages.length).padStart(2, '0')}</div>
        </div>
        <div className="chat-scroll" ref={scrollRef}>
          {messages.map((m, i) => <Message key={i} m={m} accent={accent} protocol={protocol} onViewSchedule={onViewSchedule} />)}
          {phase === 'thinking' && <div className="msg msg-agent"><span className="typing"><i /><i /><i /></span></div>}
        </div>
        <div className="chat-input">
          <button
            className={"mic " + (recording ? 'on' : '')}
            style={{ '--accent': accent }}
            onClick={onOpenVoice}
            title="Open voice mode"
          >
            <Icon.mic />
          </button>
          <button
            className="mic"
            style={{ '--accent': accent }}
            onClick={() => setPhotoOpen(true)}
            title="Analyze a photo"
          >
            <Icon.camera />
          </button>
          <input
            placeholder={recording ? 'Listening…' : 'Ask a follow-up…'}
            value={draft}
            onChange={(e) => setDraft(e.target.value)}
            onKeyDown={(e) => e.key === 'Enter' && send()}
          />
          <button className="send" onClick={send} style={{ '--accent': accent }}>
            <Icon.send />
          </button>
        </div>
      </div>
      {photoOpen && (
        <PhotoCapture
          accent={accent}
          goal={goal}
          profile={profile}
          onClose={() => setPhotoOpen(false)}
          onResult={({ imageUrl, analysis }) => {
            setMessages((m) => [
              ...m,
              { who: 'user', kind: 'photo', imageUrl },
              { who: 'agent', text: analysis },
            ]);
          }}
        />
      )}
      <Crosshairs />
    </div>
  );
}

function Message({ m, accent, protocol, onViewSchedule }) {
  if (m.kind === 'photo') {
    return (
      <div className="msg msg-user">
        <div className="bubble bubble-photo">
          <img src={m.imageUrl} alt="user upload" />
        </div>
      </div>
    );
  }
  if (m.kind === 'status') {
    return (
      <div className="msg msg-status">
        <span className="status-dot" style={{ background: accent }} />
        <span className="status-text">{m.text}</span>
      </div>
    );
  }
  if (m.kind === 'schedule-card') {
    const s = m.schedule;
    const dayLabels = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];
    return (
      <div className="msg msg-agent">
        <div className="sched-card" style={{ '--accent': accent }}>
          <div className="sched-card-head">
            <div className="sched-card-eyebrow">CALENDAR · ADDED</div>
            <div className="sched-card-title">{s.label || protocol.label}</div>
            <div className="sched-card-sub">{s.duration || (s.weeks ? `${s.weeks} weeks` : '')} · {s.stack.length} peptide{s.stack.length === 1 ? '' : 's'}</div>
          </div>
          <div className="sched-card-list">
            {s.stack.map((p, i) => (
              <div key={i} className="sched-card-row" style={{ '--c': p.color || accent }}>
                <span className="sched-card-dot" />
                <div className="sched-card-info">
                  <div className="sched-card-name">{p.name}</div>
                  <div className="sched-card-meta">{p.dose} · {p.time}</div>
                </div>
                <div className="sched-card-days">
                  {dayLabels.map((d, di) => (
                    <span
                      key={di}
                      className={"sched-card-day " + ((p.days || []).includes(di) ? 'on' : '')}
                    >{d}</span>
                  ))}
                </div>
              </div>
            ))}
          </div>
          {onViewSchedule && (
            <button className="sched-card-cta" onClick={onViewSchedule} style={{ '--accent': accent }}>
              OPEN CALENDAR <Icon.arrow />
            </button>
          )}
        </div>
      </div>
    );
  }
  if (m.kind === 'recommendation') {
    return (
      <div className="msg msg-agent">
        <div className="recommend">
          <div className="recommend-head">
            <div className="recommend-eyebrow">RECOMMENDED PROTOCOL</div>
            <div className="recommend-title">{protocol.label}</div>
            <div className="recommend-sub">Duration · {protocol.duration}</div>
          </div>
          <div className="recommend-stack">
            {protocol.stack.map((id) => {
              const p = PEPTIDES[id];
              return (
                <div key={id} className="rec-pep" style={{ '--c': p.color }}>
                  <span className="rec-pep-dot" />
                  <div className="rec-pep-body">
                    <div className="rec-pep-name">{p.name}</div>
                    <div className="rec-pep-sub">{p.dose} · {p.frequency}</div>
                  </div>
                  <div className="rec-pep-cat">{p.category}</div>
                </div>
              );
            })}
          </div>
        </div>
      </div>
    );
  }
  return (
    <div className={"msg " + (m.who === 'agent' ? 'msg-agent' : 'msg-user')}>
      <div className="bubble" style={m.who === 'agent' ? { '--accent': accent } : null}>{m.text}</div>
    </div>
  );
}

function followUpReply(q, protocol) {
  const ql = q.toLowerCase();
  if (ql.includes('side') || ql.includes('safe')) {
    return `Common considerations for ${protocol.stack[0]}: rotate injection sites, watch for redness or itching, hydrate well. Stop and consult a clinician if you experience persistent headache, joint swelling, or unusual fatigue.`;
  }
  if (ql.includes('cost') || ql.includes('price')) {
    return `Reconstituted, this stack runs roughly $180–$240 per month from a vetted compounding pharmacy. I can flag suppliers in your region.`;
  }
  if (ql.includes('cycle') || ql.includes('how long')) {
    return `Plan on ${protocol.duration} for the primary cycle, followed by a 2–4 week off-period to preserve receptor sensitivity.`;
  }
  if (ql.includes('stack') || ql.includes('combine')) {
    return `These two are designed to run together. If you want to layer in something else, I'd consider GHK-Cu for connective tissue support — it doesn't conflict.`;
  }
  return `Good question. Based on your profile and the ${protocol.stack.join(' + ')} stack, I'd say: stay consistent for the first 2 weeks before you judge response, and track sleep, recovery, and morning HRV.`;
}

// ─────────────────────────────────────────────────────────────────────────────
// STACK SCREEN — detailed peptide cards
// ─────────────────────────────────────────────────────────────────────────────
function StackScreen({ accent, goal, profile, onSchedule, onBack }) {
  const protocol = GOAL_PROTOCOLS[goal];
  const [active, setActive] = React.useState(protocol.stack[0]);
  const peptide = PEPTIDES[active];

  return (
    <div className="screen stack-screen" data-screen-label="04 Stack">
      <div className="stack-head">
        <div>
          <div className="hd-eyebrow">PROTOCOL · {protocol.label.toUpperCase()}</div>
          <div className="hd-title">Your stack</div>
          <div className="hd-sub">{protocol.stack.length} peptides · {protocol.duration} cycle · calibrated for {profile.weight}kg</div>
        </div>
        <div className="stack-actions">
          <button className="ghost" onClick={onBack}>BACK</button>
          <button className="cta" style={{ '--accent': accent }} onClick={onSchedule}>
            DOSING SCHEDULE <Icon.arrow />
          </button>
        </div>
      </div>

      <div className="stack-body">
        <div className="stack-list">
          {protocol.stack.map((id) => {
            const p = PEPTIDES[id];
            const on = active === id;
            return (
              <button key={id} className={"stack-item " + (on ? 'on' : '')} style={{ '--c': p.color, '--accent': accent }} onClick={() => setActive(id)}>
                <span className="stack-mini-orb">
                  <span className="stack-mini-core" style={{ background: p.color }} />
                  <span className="stack-mini-ring" />
                </span>
                <div className="stack-item-text">
                  <div className="stack-item-name">{p.name}</div>
                  <div className="stack-item-sub">{p.category}</div>
                </div>
                <div className="stack-item-dose">{p.dose}</div>
              </button>
            );
          })}
        </div>

        <div className="stack-detail">
          <div className="detail-head">
            <div>
              <div className="detail-eyebrow">{peptide.category.toUpperCase()}</div>
              <div className="detail-name">{peptide.name}</div>
              <div className="detail-full">{peptide.full}</div>
            </div>
            <div className="detail-orb">
              <Orb size={180} intensity={0.4} color={peptide.color} state="idle" />
            </div>
          </div>

          <div className="detail-grid">
            <DetailStat label="DOSE" value={peptide.dose} icon={<Icon.drop />} />
            <DetailStat label="FREQUENCY" value={peptide.frequency} icon={<Icon.pulse />} />
            <DetailStat label="ROUTE" value={peptide.route} icon={<Icon.syringe />} />
            <DetailStat label="HALF-LIFE" value={peptide.halfLife} icon={<Icon.pulse />} />
          </div>

          <div className="detail-section">
            <div className="detail-eyebrow">MECHANISM</div>
            <p>{peptide.mechanism}</p>
          </div>

          <div className="detail-section">
            <div className="detail-eyebrow">CYCLE</div>
            <p>{peptide.cycle}</p>
          </div>

          <div className="detail-section">
            <div className="detail-eyebrow">SYNERGIZES WITH</div>
            <div className="chip-row">
              {peptide.stacks.map((s) => (
                <span key={s} className="chip" style={{ '--c': PEPTIDES[s]?.color || accent }}>
                  <span className="chip-dot" /> {s}
                </span>
              ))}
            </div>
          </div>

          <div className="warning">
            <Icon.warn />
            <span>Educational protocol only. Confirm with a licensed clinician before initiating any peptide regimen. Pepagent screens for common contraindications but does not replace medical supervision.</span>
          </div>
        </div>
      </div>
      <Crosshairs />
    </div>
  );
}

function DetailStat({ label, value, icon }) {
  return (
    <div className="detail-stat">
      <div className="ds-icon">{icon}</div>
      <div>
        <div className="ds-label">{label}</div>
        <div className="ds-value">{value}</div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────────
// SCHEDULE SCREEN — weekly dosing calendar
// ─────────────────────────────────────────────────────────────────────────────
function ScheduleScreen({ accent, goal, onBack, onRestart, customSchedule }) {
  const protocol = GOAL_PROTOCOLS[goal];
  const days = ['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'];

  // Prefer the AI-generated custom schedule if the user asked for one in chat.
  // Otherwise fall back to the deterministic schedule built from the protocol.
  const schedule = customSchedule && customSchedule.stack
    ? customSchedule.stack.map((s) => ({
        id: s.id,
        p: {
          name: s.name,
          dose: s.dose,
          color: s.color || accent,
          category: s.category || 'Custom',
          frequency: '',
          route: '',
          stacks: [],
          mechanism: '',
          cycle: '',
        },
        hits: Array.isArray(s.days) ? s.days : [0, 1, 2, 3, 4],
        time: s.time || '08:00',
      }))
    : protocol.stack.map((id, i) => {
        const p = PEPTIDES[id];
        let hits;
        if (/2× weekly/.test(p.frequency)) hits = [0, 3];
        else if (/Daily/.test(p.frequency) || /1×/.test(p.frequency)) hits = [0, 1, 2, 3, 4, 5, 6];
        else hits = [0, 1, 2, 3, 4];
        let time;
        if (/evening/i.test(p.frequency) || p.category === 'Sleep & GH' || p.category === 'Metabolism') time = '21:30';
        else if (p.category === 'Cognitive') time = '08:00';
        else time = i === 0 ? '08:00' : '21:30';
        return { id, p, hits, time };
      });

  // Real "today" — JS getDay() is 0=Sun..6=Sat, our grid is 0=Mon..6=Sun.
  const now = new Date();
  const jsDay = now.getDay();
  const today = (jsDay + 6) % 7; // 0=Mon..6=Sun

  // Real dates for the current week's Mon..Sun
  const weekDates = (() => {
    const monday = new Date(now);
    monday.setDate(now.getDate() - today);
    return Array.from({ length: 7 }, (_, i) => {
      const d = new Date(monday);
      d.setDate(monday.getDate() + i);
      return d.getDate();
    });
  })();

  // Persist completed doses per week so check-marks survive reloads.
  const weekKey = (() => {
    const monday = new Date(now);
    monday.setDate(now.getDate() - today);
    return `pepagent.completed.${monday.toISOString().slice(0, 10)}`;
  })();
  const [completed, setCompleted] = React.useState(() => {
    try {
      const raw = localStorage.getItem(weekKey);
      return raw ? JSON.parse(raw) : {};
    } catch (e) { return {}; }
  });
  const toggle = (k) => setCompleted((c) => {
    const next = { ...c, [k]: !c[k] };
    try { localStorage.setItem(weekKey, JSON.stringify(next)); } catch (e) {}
    return next;
  });

  return (
    <div className="screen schedule" data-screen-label="05 Schedule">
      <div className="sch-head">
        <div>
          <div className="hd-eyebrow">{customSchedule ? 'AI-GENERATED CALENDAR' : 'DOSING CALENDAR'}</div>
          <div className="hd-title">
            Week 1 of {customSchedule?.weeks || protocol.duration.split(' ')[0]}
          </div>
          <div className="hd-sub">
            {(customSchedule?.label || protocol.label)} · {schedule.map((r) => r.p.name).join(' + ')}
          </div>
        </div>
        <div className="sch-actions">
          <button className="ghost" onClick={onBack}>BACK</button>
          <button className="cta" style={{ '--accent': accent }} onClick={onRestart}>
            NEW CONSULTATION <Icon.arrow />
          </button>
        </div>
      </div>

      <div className="sch-grid">
        <div className="sch-col-head" />
        {days.map((d, i) => (
          <div key={d} className={"sch-day-head " + (i === today ? 'on' : '')} style={{ '--accent': accent }}>
            <span className="sch-day-name">{d}</span>
            <span className="sch-day-num">{weekDates[i]}</span>
          </div>
        ))}

        {schedule.map((row) => (
          <React.Fragment key={row.id}>
            <div className="sch-pep" style={{ '--c': row.p.color }}>
              <span className="sch-pep-dot" />
              <div>
                <div className="sch-pep-name">{row.p.name}</div>
                <div className="sch-pep-sub">{row.p.dose} · {row.time}</div>
              </div>
            </div>
            {days.map((d, i) => {
              const has = row.hits.includes(i);
              const key = row.id + '-' + i;
              const isToday = i === today;
              const done = !!completed[key];
              if (!has) return <div key={key} className="sch-cell empty" />;
              return (
                <button
                  key={key}
                  className={"sch-cell has " + (done ? 'done' : '') + (isToday ? ' today' : '')}
                  style={{ '--c': row.p.color, '--accent': accent }}
                  onClick={() => toggle(key)}
                >
                  <span className="sch-cell-time">{row.time}</span>
                  <span className="sch-cell-dose">{row.p.dose.split(' ')[0]}</span>
                  {done ? <span className="sch-check"><Icon.check size={12} /></span> : <span className="sch-pending" />}
                </button>
              );
            })}
          </React.Fragment>
        ))}
      </div>

      <div className="sch-legend">
        <div className="legend-item"><span className="legend-box pending" /> Scheduled</div>
        <div className="legend-item"><span className="legend-box done" style={{ background: accent }} /> Logged</div>
        <div className="legend-item"><span className="legend-box today" /> Today</div>
        <div className="sch-summary">
          {Object.values(completed).filter(Boolean).length} / {schedule.reduce((a, r) => a + r.hits.length, 0)} doses logged this week
        </div>
      </div>
      <Crosshairs />
    </div>
  );
}

window.ChatScreen = ChatScreen;
window.StackScreen = StackScreen;
window.ScheduleScreen = ScheduleScreen;
