// ====================================================================
// SUPPORT PAGE, persona-aware
// Franchisee → Zendesk-style inbox + live availability + book-a-call
// HQ        → Advisor operations: KPIs, volume by location, themes, leaderboard
// ====================================================================
const { useState: useStateS, useMemo: useMemoS } = React;
const Ts = (t, b, k) => window.toast && window.toast(t, b, k);

// ---------------------------------------------------------------
// MOCK DATA, Franchisee inbox + threads
// ---------------------------------------------------------------
const ADVISORS = {
  'priya':   { name: 'Priya R.',     role: 'Local Marketing Strategist', initials: 'PR', color: 'var(--terra)'   },
  'marcus':  { name: 'Marcus T.',    role: 'Performance Advisor',        initials: 'MT', color: 'var(--sage)'    },
  'team':    { name: 'Support Team', role: 'Listings & Tech',            initials: 'ST', color: 'var(--sky)'     },
  'jen':     { name: 'Jen K.',       role: 'Creative Lead',              initials: 'JK', color: 'var(--marigold)'},
};

const SUPPORT_THREADS = [
  {
    id: 't-mothers',
    subject: "Re: Mother's Day promo creative",
    advisor: 'priya',
    last: 'Hot off the press, three new layouts attached. The gift-a-clean direction tested best in our last round.',
    timestamp: '2h ago', timeFull: 'Apr 27, 1:42 PM',
    unread: true, status: 'open',
    messages: [
      { from: 'priya',  ts: 'Apr 24, 9:12 AM', text: "Hey Alicia, flagging that Mother's Day is 16 days out. We have three creative directions ready. Want me to send mocks?" },
      { from: 'me',     ts: 'Apr 24, 11:30 AM', text: "Yes please. Gift cleans are the angle I'd lean into, we sell out Mother's Day gift-clean slots every year." },
      { from: 'priya',  ts: 'Apr 25, 10:01 AM', text: "Perfect. I'll bias toward the gift-a-clean look. Here's a brief draft, confirm tone (warm/family vs. premium/elevated)?" },
      { from: 'me',     ts: 'Apr 25, 4:18 PM',  text: "Warm/family. We're not a luxury spa." },
      { from: 'priya',  ts: 'Apr 27, 1:42 PM',  text: "Hot off the press, three new layouts attached. The gift-a-clean direction tested best in our last round. If you can review by Tuesday we can ship for the May 1 push." },
    ],
  },
  {
    id: 't-phone',
    subject: 'Phone routing setup confirmation',
    advisor: 'marcus',
    last: "All set, your LSA calls now route to (512) 555-0188 first, fallback to your cell after 4 rings. Test call worked.",
    timestamp: 'Yesterday', timeFull: 'Apr 26, 4:22 PM',
    unread: true, status: 'open',
    messages: [
      { from: 'me',     ts: 'Apr 26, 9:14 AM', text: "Sarah's phone got reassigned. Can we point LSA calls to the new front-of-house line?" },
      { from: 'marcus', ts: 'Apr 26, 9:48 AM', text: "On it. New number is (512) 555-0188, correct?" },
      { from: 'me',     ts: 'Apr 26, 10:02 AM', text: "Yes." },
      { from: 'marcus', ts: 'Apr 26, 4:22 PM',  text: "All set, your LSA calls now route to (512) 555-0188 first, fallback to your cell after 4 rings. Test call worked. Let me know if anything feels off this week." },
    ],
  },
  {
    id: 't-dg',
    subject: 'Demand Gen, is this right for us?',
    advisor: 'priya',
    last: "Sharing the cohort study from 18 FreshNest locations that activated in Q1. CPM held at $7.20, lead lift came in week 5–7.",
    timestamp: '3d ago', timeFull: 'Apr 24, 11:08 AM',
    unread: false, status: 'open',
    messages: [
      { from: 'me',     ts: 'Apr 23, 2:30 PM',  text: "Corporate keeps mentioning Demand Gen. Honestly not sure what it does or if it's right for a single location with our budget." },
      { from: 'priya',  ts: 'Apr 23, 5:11 PM',  text: "Totally fair question. Demand Gen is upper-funnel, it builds awareness so your search ads convert better later. It's usually NOT the first thing we'd recommend at your scale." },
      { from: 'priya',  ts: 'Apr 24, 11:08 AM', text: "That said, you're at the size where it could start paying off. Sharing the cohort study from 18 FreshNest locations that activated in Q1. CPM held at $7.20, lead lift came in week 5–7. Take a look and we can decide together on our next call." },
    ],
  },
  {
    id: 't-qbr',
    subject: 'Quarterly performance review prep',
    advisor: 'marcus',
    last: "Pre-read attached. Three things I want to walk through: PPC scaling, the LSA dispute pattern, and your review velocity.",
    timestamp: 'Last week', timeFull: 'Apr 21, 9:30 AM',
    unread: false, status: 'closed',
    messages: [
      { from: 'marcus', ts: 'Apr 21, 9:30 AM', text: "QBR is on the calendar for May 6, 2pm. Pre-read attached. Three things I want to walk through: PPC scaling, the LSA dispute pattern, and your review velocity." },
      { from: 'me',     ts: 'Apr 21, 3:14 PM', text: "Thanks, read through. Looking forward to it." },
    ],
  },
  {
    id: 't-listings',
    subject: 'Listing fixes, Apple Maps issue',
    advisor: 'team',
    last: "Apple Maps re-indexed your hours overnight. Should be live everywhere within 24 hours. Closing this ticket.",
    timestamp: '2 weeks ago', timeFull: 'Apr 14, 10:45 AM',
    unread: false, status: 'closed',
    messages: [
      { from: 'me',   ts: 'Apr 12, 6:48 PM',  text: "Apple Maps still showing 8pm close on Sundays. We close at 10. This is the third time." },
      { from: 'team', ts: 'Apr 13, 9:22 AM',  text: "Sorry about that, Apple's data partner has a stale feed. Submitting a manual override now." },
      { from: 'team', ts: 'Apr 14, 10:45 AM', text: "Apple Maps re-indexed your hours overnight. Should be live everywhere within 24 hours. Closing this ticket." },
    ],
  },
  {
    id: 't-creative',
    subject: 'Spring creative refresh approved',
    advisor: 'jen',
    last: "Final assets shipped to your Meta account. They'll start serving with the next budget cycle.",
    timestamp: '3 weeks ago', timeFull: 'Apr 8, 2:15 PM',
    unread: false, status: 'closed',
    messages: [
      { from: 'jen',  ts: 'Apr 6, 11:00 AM', text: "Spring carousel is approved by you and corporate. Pushing to production today." },
      { from: 'jen',  ts: 'Apr 8, 2:15 PM',  text: "Final assets shipped to your Meta account. They'll start serving with the next budget cycle." },
    ],
  },
];

const BOOK_SLOTS = [
  { day: 'Wed Apr 30', time: '10:00 AM CT', advisor: 'marcus' },
  { day: 'Thu May 1',  time: '2:00 PM CT',  advisor: 'priya'  },
  { day: 'Fri May 2',  time: '9:00 AM CT',  advisor: 'marcus' },
];

// ---------------------------------------------------------------
// MOCK DATA, HQ advisor operations
// ---------------------------------------------------------------
const HQ_ADVISOR_OPS = {
  kpis: {
    avgResponseHrs:    2.4, responseTarget: 4,    responseGood: true,
    avgResolutionDays: 1.6, resolutionTarget: 2,  resolutionGood: true,
    bookingWindowDays: 2.8, bookingTarget: 2,     bookingGood: false,
    activeConversations: 184, activeDelta: +12,
  },
  volumeByLocation: [
    { unit: 'Las Vegas Strip',      city: 'Las Vegas, NV',   advisor: 'priya',  threads: 14, openThreads: 8, overSla: 2, avgResponse: 5.8, status: 'attention' },
    { unit: 'Houston Galleria',     city: 'Houston, TX',     advisor: 'marcus', threads: 12, openThreads: 4, overSla: 0, avgResponse: 1.9, status: 'healthy' },
    { unit: 'Atlanta Midtown',      city: 'Atlanta, GA',     advisor: 'priya',  threads: 11, openThreads: 3, overSla: 0, avgResponse: 2.1, status: 'healthy' },
    { unit: 'Chicago Loop',         city: 'Chicago, IL',     advisor: 'marcus', threads: 10, openThreads: 6, overSla: 1, avgResponse: 4.6, status: 'elevated' },
    { unit: 'Orlando I-Drive',      city: 'Orlando, FL',     advisor: 'jen',    threads: 10, openThreads: 2, overSla: 0, avgResponse: 1.4, status: 'healthy' },
    { unit: 'Austin Downtown',      city: 'Austin, TX',      advisor: 'priya',  threads: 9,  openThreads: 3, overSla: 0, avgResponse: 2.0, status: 'healthy' },
    { unit: 'Nashville Broadway',   city: 'Nashville, TN',   advisor: 'team',   threads: 8,  openThreads: 4, overSla: 1, avgResponse: 3.8, status: 'elevated' },
    { unit: 'Denver LoDo',          city: 'Denver, CO',      advisor: 'marcus', threads: 7,  openThreads: 2, overSla: 0, avgResponse: 2.5, status: 'healthy' },
    { unit: 'Fort Worth Stockyards',city: 'Fort Worth, TX',  advisor: 'priya',  threads: 7,  openThreads: 1, overSla: 0, avgResponse: 1.8, status: 'healthy' },
    { unit: 'Dallas Uptown',        city: 'Dallas, TX',      advisor: 'team',   threads: 6,  openThreads: 2, overSla: 0, avgResponse: 2.2, status: 'healthy' },
  ],
  themes: [
    { id: 'th-dg',       theme: 'Demand Gen enrollment interest',           locations: 14, trend: 'rising',  promote: true,  note: "Locations are asking unprompted, this is the right moment to push playbook activation." },
    { id: 'th-mothers',  theme: 'Promo creative timing for Mother\u2019s Day', locations: 22, trend: 'rising',  promote: false, note: 'Predictable seasonal spike. Creative kits already published.' },
    { id: 'th-budget',   theme: 'Budget reallocation requests',             locations: 11, trend: 'steady',  promote: false, note: '6 of 11 are asking to reduce paid social. Worth monitoring trend.' },
    { id: 'th-phones',   theme: 'Phone routing changes after staff turnover', locations: 9,  trend: 'rising',  promote: true,  note: 'Self-serve doc would deflect ~70%. Lenny drafted one.' },
    { id: 'th-apple',    theme: 'Listing accuracy issues on Apple Maps',     locations: 6,  trend: 'falling', promote: false, note: 'Decreasing since the publisher fix on Apr 13.' },
  ],
  leaderboard: [
    { advisor: 'marcus', threads: 47, avgResolutionDays: 1.2, satisfaction: 4.8 },
    { advisor: 'priya',  threads: 52, avgResolutionDays: 1.5, satisfaction: 4.9 },
    { advisor: 'jen',    threads: 31, avgResolutionDays: 1.7, satisfaction: 4.7 },
  ],
};

// ====================================================================
// SUPPORT PAGE, persona router
// ====================================================================
function SupportPage({ data, persona }) {
  if (persona === 'hq') return <SupportPageHq data={data}/>;
  return <SupportPageFranchisee data={data}/>;
}
window.SupportPage = SupportPage;

// ====================================================================
// FRANCHISEE
// ====================================================================
function SupportPageFranchisee({ data }) {
  // Simulated availability, flip between true/false to demo.
  const [available] = useStateS(true);
  const [openThread, setOpenThread] = useStateS(null);
  const [reply, setReply] = useStateS('');
  const [threads, setThreads] = useStateS(SUPPORT_THREADS);

  const unreadCount = threads.filter(t => t.unread).length;

  const openT = (t) => {
    setOpenThread(t);
    if (t.unread) {
      setThreads(prev => prev.map(x => x.id === t.id ? { ...x, unread: false } : x));
    }
  };

  const sendReply = () => {
    if (!reply.trim() || !openThread) return;
    Ts('Reply sent', `Your message to ${ADVISORS[openThread.advisor].name} is on its way.`, 'ok');
    setReply('');
  };

  return (
    <div className="page active">
      <div className="page-header">
        <div>
          <div className="page-title">Support.</div>
          <div className="page-sub">Your Local Marketing Team is here. Email, call, or message, whichever works.</div>
        </div>
        <div className="page-actions">
          <button className="btn btn-ghost btn-sm" onClick={() => Ts('Help center', 'Opening the FreshNest knowledge base in a new tab.', 'info')}>Help center</button>
          <button className="btn btn-primary btn-sm" onClick={() => Ts('New ticket', 'Draft a new request, your strategist will see it within the hour.', 'info')}>New request</button>
        </div>
      </div>

      {/* Live availability strip */}
      <AvailabilityStrip available={available}/>

      <div className="grid" style={{ gridTemplateColumns: '1.5fr 1fr', gap: 20, alignItems: 'start' }}>
        {/* LEFT, inbox */}
        <div>
          <div className="section-label">
            Inbox <span className="count">{threads.length} threads · {unreadCount} unread</span>
          </div>
          <div className="card" style={{ overflow: 'hidden' }}>
            {threads.map((t, i) => (
              <ThreadRow
                key={t.id}
                t={t}
                advisor={ADVISORS[t.advisor]}
                last={i === threads.length - 1}
                onOpen={() => openT(t)}
              />
            ))}
          </div>
        </div>

        {/* RIGHT, book a call + lenny */}
        <div>
          <BookCallCard slots={BOOK_SLOTS}/>
          <div className="lenny-card" style={{ padding: '14px 16px', marginTop: 16 }}>
            <div style={{ display: 'flex', gap: 10, alignItems: 'flex-start', position: 'relative', zIndex: 1 }}>
              <div style={{ width: 30, height: 30, background: 'var(--paper)', border: '2px solid var(--cream-3)', borderRadius: '50%', overflow: 'hidden', flexShrink: 0 }}>
                <LennyLlama size={30} mood="happy" bg="circle"/>
              </div>
              <div style={{ flex: 1, fontSize: 12.5, color: 'var(--ink-2)', lineHeight: 1.55 }}>
                <div style={{ fontSize: 10, fontWeight: 700, color: 'var(--violet)', textTransform: 'uppercase', letterSpacing: '0.06em', marginBottom: 4 }}>Lenny's note</div>
                <strong style={{ color: 'var(--ink)' }}>Priya replies fastest in the morning.</strong> Her median response Mon–Fri before noon is ~38 minutes. After 3pm it's 2–3 hours.
              </div>
            </div>
          </div>
        </div>
      </div>

      {/* Thread drawer */}
      {openThread && (
        <ThreadDrawer
          thread={openThread}
          advisor={ADVISORS[openThread.advisor]}
          reply={reply}
          setReply={setReply}
          onSend={sendReply}
          onClose={() => setOpenThread(null)}
        />
      )}
    </div>
  );
}

// ----------- Availability strip -----------
function AvailabilityStrip({ available }) {
  const dotColor = available ? 'var(--ok)' : 'var(--marigold)';
  return (
    <div className="card card-pad" style={{ marginBottom: 20, display: 'flex', alignItems: 'center', gap: 16 }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, flex: 1 }}>
        <span style={{ position: 'relative', width: 10, height: 10 }}>
          <span style={{ position: 'absolute', inset: 0, borderRadius: '50%', background: dotColor }}/>
          {available && <span style={{ position: 'absolute', inset: -4, borderRadius: '50%', background: dotColor, opacity: 0.25, animation: 'avPulse 2s ease-in-out infinite' }}/>}
        </span>
        <div>
          <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ink)' }}>
            {available ? 'An advisor is available now.' : 'No advisors available right now.'}
          </div>
          <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2 }}>
            {available
              ? 'Marcus T. and Priya R. are both online · typical response <5 min'
              : 'Next availability: 2:30 PM CT today · or send a message and we\u2019ll respond ASAP'}
          </div>
        </div>
      </div>
      <button className="btn btn-ghost btn-sm" onClick={() => Ts('Chat opening', 'Connecting you to the next available advisor.', 'info')}>Start chat</button>
      <button className="btn btn-primary btn-sm" disabled={!available} onClick={() => Ts('Calling…', 'Connecting you to your strategist now.', 'info')}>📞 Call now</button>
      <style>{`@keyframes avPulse { 0%, 100% { transform: scale(1); opacity: 0.25; } 50% { transform: scale(1.6); opacity: 0; } }`}</style>
    </div>
  );
}

// ----------- Thread row in the inbox -----------
function ThreadRow({ t, advisor, last, onOpen }) {
  return (
    <div onClick={onOpen}
         onMouseEnter={e => e.currentTarget.style.background = 'var(--cream)'}
         onMouseLeave={e => e.currentTarget.style.background = t.unread ? 'rgba(245,124,86,.04)' : 'transparent'}
         style={{
           display: 'grid', gridTemplateColumns: '40px 1fr auto', gap: 14, padding: '14px 18px',
           borderBottom: last ? 'none' : '1px solid var(--cream-2)',
           background: t.unread ? 'rgba(245,124,86,.04)' : 'transparent',
           cursor: 'pointer', alignItems: 'center', transition: 'background .12s ease',
         }}>
      <AdvisorAvatar advisor={advisor} size={40}/>
      <div style={{ minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginBottom: 3 }}>
          <span style={{ fontSize: 13, fontWeight: t.unread ? 700 : 600, color: 'var(--ink)' }}>{t.subject}</span>
          {t.unread && <span style={{ display: 'inline-block', width: 6, height: 6, borderRadius: '50%', background: 'var(--terra)' }}/>}
          {t.status === 'closed' && <span className="badge badge-neutral" style={{ fontSize: 9.5 }}>Resolved</span>}
        </div>
        <div style={{ fontSize: 11.5, color: 'var(--ink-4)', marginBottom: 4 }}>
          {advisor.name} · {advisor.role}
        </div>
        <div style={{ fontSize: 12, color: 'var(--ink-3)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
          {t.last}
        </div>
      </div>
      <div style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--ff-mono)', whiteSpace: 'nowrap' }}>
        {t.timestamp}
      </div>
    </div>
  );
}

// ----------- Advisor avatar -----------
function AdvisorAvatar({ advisor, size }) {
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: advisor.color, color: 'var(--cream)',
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      fontFamily: 'var(--ff-display)', fontSize: size >= 40 ? 14 : 11, fontWeight: 600, flexShrink: 0,
    }}>
      {advisor.initials}
    </div>
  );
}

// ----------- Thread drawer -----------
function ThreadDrawer({ thread, advisor, reply, setReply, onSend, onClose }) {
  return (
    <window.ModalPortal><>
      <div onClick={onClose} style={{ position: 'fixed', inset: 0, background: 'rgba(45,32,18,.32)', zIndex: 200, animation: 'fadeIn .15s ease' }}/>
      <div style={{ position: 'fixed', top: 0, right: 0, bottom: 0, width: 580, background: 'var(--paper)', borderLeft: '1px solid var(--line)', boxShadow: '-12px 0 32px rgba(45,32,18,.12)', zIndex: 201, display: 'flex', flexDirection: 'column', animation: 'slideInRight .2s ease' }}>
        {/* Header */}
        <div style={{ padding: '18px 22px 14px', borderBottom: '1px solid var(--line)' }}>
          <div style={{ display: 'flex', alignItems: 'flex-start', gap: 12 }}>
            <AdvisorAvatar advisor={advisor} size={42}/>
            <div style={{ flex: 1 }}>
              <div style={{ fontFamily: 'var(--ff-display)', fontSize: 18, fontWeight: 600, color: 'var(--ink)', letterSpacing: '-0.012em' }}>{thread.subject}</div>
              <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 2 }}>
                {advisor.name} · {advisor.role}
              </div>
            </div>
            <button onClick={onClose} style={{ background: 'transparent', border: 'none', fontSize: 22, color: 'var(--ink-3)', cursor: 'pointer', lineHeight: 1, padding: 0 }}>×</button>
          </div>
        </div>

        {/* Messages */}
        <div style={{ flex: 1, overflowY: 'auto', padding: '20px 22px', background: 'var(--cream)' }}>
          {thread.messages.map((m, i) => {
            const fromMe = m.from === 'me';
            const fromAdvisor = !fromMe ? ADVISORS[m.from] : null;
            return (
              <div key={i} style={{ display: 'flex', flexDirection: fromMe ? 'row-reverse' : 'row', alignItems: 'flex-start', gap: 10, marginBottom: 14 }}>
                {!fromMe && fromAdvisor && <AdvisorAvatar advisor={fromAdvisor} size={30}/>}
                {fromMe && <div style={{ width: 30, height: 30, borderRadius: '50%', background: 'var(--ink-2)', color: 'var(--cream)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 11, fontWeight: 600 }}>MC</div>}
                <div style={{ maxWidth: '78%' }}>
                  <div style={{
                    background: fromMe ? 'var(--ink)' : 'var(--paper)',
                    color: fromMe ? 'var(--cream)' : 'var(--ink)',
                    border: fromMe ? 'none' : '1px solid var(--cream-3)',
                    padding: '10px 14px', borderRadius: 12, fontSize: 13, lineHeight: 1.55,
                  }}>
                    {m.text}
                  </div>
                  <div style={{ fontSize: 10.5, color: 'var(--ink-4)', marginTop: 4, fontFamily: 'var(--ff-mono)', textAlign: fromMe ? 'right' : 'left' }}>
                    {fromMe ? 'You' : fromAdvisor.name} · {m.ts}
                  </div>
                </div>
              </div>
            );
          })}
        </div>

        {/* Composer */}
        <div style={{ padding: '14px 22px', borderTop: '1px solid var(--line)', background: 'var(--paper)' }}>
          <textarea
            value={reply}
            onChange={e => setReply(e.target.value)}
            placeholder={`Reply to ${advisor.name}…`}
            style={{
              width: '100%', minHeight: 70, padding: '10px 12px',
              background: 'var(--cream)', border: '1px solid var(--cream-3)', borderRadius: 8,
              fontSize: 13, color: 'var(--ink)', resize: 'vertical',
              fontFamily: 'inherit', outline: 'none',
            }}
          />
          <div style={{ display: 'flex', gap: 8, marginTop: 10, alignItems: 'center' }}>
            <button className="btn btn-quiet btn-sm" onClick={() => Ts('Attachment', 'File picker would open here.', 'info')}>📎 Attach</button>
            <span style={{ flex: 1 }}/>
            <button className="btn btn-quiet btn-sm" onClick={onClose}>Close</button>
            <button className="btn btn-primary btn-sm" disabled={!reply.trim()} onClick={onSend}>Send reply</button>
          </div>
        </div>
      </div>
    </></window.ModalPortal>
  );
}

// ----------- Book a call card -----------
function BookCallCard({ slots }) {
  const [picked, setPicked] = useStateS(null);
  return (
    <div className="card card-pad">
      <div className="card-header" style={{ marginBottom: 10 }}>
        <div>
          <div className="card-title">Book a performance call</div>
          <div className="card-sub">30-min review with your strategist</div>
        </div>
        <span className="badge badge-info">Free</span>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 8, marginBottom: 12 }}>
        {slots.map((s, i) => {
          const advisor = ADVISORS[s.advisor];
          const on = picked === i;
          return (
            <button key={i} onClick={() => setPicked(i)}
                    style={{
                      display: 'flex', alignItems: 'center', gap: 10, padding: '10px 12px',
                      background: on ? 'var(--ink)' : 'var(--cream)',
                      color: on ? 'var(--cream)' : 'var(--ink)',
                      border: `1px solid ${on ? 'var(--ink)' : 'var(--cream-3)'}`,
                      borderRadius: 8, cursor: 'pointer', textAlign: 'left',
                      transition: 'all .12s ease',
                    }}>
              <div style={{ flex: 1 }}>
                <div style={{ fontSize: 13, fontWeight: 600 }}>{s.day} · {s.time}</div>
                <div style={{ fontSize: 11, color: on ? 'rgba(250,246,239,.65)' : 'var(--ink-4)', marginTop: 2 }}>
                  with {advisor.name}
                </div>
              </div>
              <span style={{ fontSize: 11, fontFamily: 'var(--ff-mono)', opacity: on ? 1 : 0.5 }}>
                {on ? '✓' : 'Pick'}
              </span>
            </button>
          );
        })}
      </div>
      <button className="btn btn-primary btn-sm" disabled={picked === null}
              onClick={() => {
                const s = slots[picked];
                Ts('Call booked', `${s.day} at ${s.time} with ${ADVISORS[s.advisor].name}. Calendar invite on its way.`, 'ok');
                setPicked(null);
              }}
              style={{ width: '100%' }}>
        {picked === null ? 'Pick a slot above' : 'Confirm booking →'}
      </button>
      <button className="btn btn-quiet btn-xs" onClick={() => Ts('Calendar', 'Opening full calendar of available slots.', 'info')}
              style={{ width: '100%', marginTop: 6 }}>
        See more slots
      </button>
    </div>
  );
}

// ====================================================================
// HQ / CORPORATE
// ====================================================================
function SupportPageHq({ data }) {
  const ops = HQ_ADVISOR_OPS;
  const n = data.network?.totalLocations || 700;

  return (
    <div className="page active">
      <div className="page-header">
        <div>
          <div className="page-title">Advisor Operations.</div>
          <div className="page-sub">Communications volume, response times, and themes across <strong style={{ color: 'var(--ink-2)' }}>{n} locations</strong>.</div>
        </div>
        <div className="page-actions">
          <button className="btn btn-ghost btn-sm" onClick={() => Ts('Export', 'Advisor activity CSV, sending to your inbox.', 'ok')}>Export CSV</button>
          <button className="btn btn-primary btn-sm" onClick={() => Ts('Outreach scheduled', 'Brand-wide check-in scheduled, advisors will reach out to flagged locations this week.', 'ok')}>Schedule outreach</button>
        </div>
      </div>

      {/* KPI strip */}
      <div className="grid grid-4" style={{ marginBottom: 16 }}>
        <SlaKpi label="Avg response time" value={`${ops.kpis.avgResponseHrs}h`}    target={`${ops.kpis.responseTarget}h target`}    good={ops.kpis.responseGood}/>
        <SlaKpi label="Avg resolution time" value={`${ops.kpis.avgResolutionDays}d`} target={`${ops.kpis.resolutionTarget}d target`} good={ops.kpis.resolutionGood}/>
        <SlaKpi label="Booking window" value={`${ops.kpis.bookingWindowDays}d`} target={`${ops.kpis.bookingTarget}d target`} good={ops.kpis.bookingGood}/>
        <KpiCard label="Active conversations" value={ops.kpis.activeConversations} delta={ops.kpis.activeDelta} color="var(--violet)" dotColor="var(--violet)"/>
      </div>

      {/* Volume by location + Themes */}
      <SourceNote>Source: Zendesk</SourceNote>

      <div className="grid" style={{ gridTemplateColumns: '1.4fr 1fr', gap: 16, marginBottom: 16 }}>
        <VolumeByLocationCard rows={ops.volumeByLocation}/>
        <CommonThemesCard themes={ops.themes}/>
      </div>

      <SourceNote>Source: Zendesk · themes clustered by LOCALACT</SourceNote>

      {/* Advisor leaderboard */}
      <AdvisorLeaderboard rows={ops.leaderboard}/>
      <SourceNote>Source: Zendesk</SourceNote>
    </div>
  );
}

// ----------- SLA KPI tile (custom, embeds target + hit/miss) -----------
function SlaKpi({ label, value, target, good }) {
  const tone = good ? 'var(--sage)' : 'var(--terra)';
  const bg   = good ? 'var(--sage-soft)' : 'var(--terra-soft)';
  return (
    <div className="card card-pad" style={{ position: 'relative' }}>
      <div style={{ fontSize: 11, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600, marginBottom: 8 }}>{label}</div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 8 }}>
        <span style={{ fontFamily: 'var(--ff-display)', fontSize: 28, fontWeight: 500, color: 'var(--ink)', letterSpacing: '-0.02em' }}>{value}</span>
        <span style={{ fontSize: 11, color: 'var(--ink-4)', fontFamily: 'var(--ff-mono)' }}>{target}</span>
      </div>
      <div style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '3px 8px', borderRadius: 999, background: bg, color: tone, fontSize: 10.5, fontWeight: 700 }}>
        <span style={{ width: 5, height: 5, borderRadius: '50%', background: tone }}/>
        {good ? 'Hitting target' : 'Above target'}
      </div>
    </div>
  );
}

// ----------- Volume by location -----------
function VolumeByLocationCard({ rows }) {
  return (
    <div className="card card-pad">
      <div className="card-header" style={{ marginBottom: 10 }}>
        <div>
          <div className="card-title">Conversation volume by location</div>
          <div className="card-sub">Top {rows.length} locations · this month</div>
        </div>
      </div>
      <div style={{
        display: 'grid', gridTemplateColumns: '1.6fr 1fr 0.6fr 0.7fr 0.9fr',
        gap: 8, padding: '6px 10px 8px', borderBottom: '1px solid var(--cream-3)',
        fontSize: 10, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 600,
      }}>
        <span>Location</span>
        <span>Advisor</span>
        <span style={{ textAlign: 'right' }}>Threads</span>
        <span style={{ textAlign: 'right' }}>Resp.</span>
        <span>Status</span>
      </div>
      {rows.map((r, i) => {
        const advisor = ADVISORS[r.advisor];
        const tone = r.status === 'attention' ? 'var(--terra)' : r.status === 'elevated' ? 'var(--marigold)' : 'var(--sage)';
        const bg   = r.status === 'attention' ? 'var(--terra-soft)' : r.status === 'elevated' ? 'var(--marigold-soft)' : 'var(--sage-soft)';
        const statusLabel = r.status === 'attention' ? 'Attention' : r.status === 'elevated' ? 'Elevated' : 'Healthy';
        return (
          <div key={r.unit}
               onClick={() => Ts(r.unit, `${r.threads} threads · ${r.openThreads} open · ${r.overSla} over SLA`, 'info')}
               onMouseEnter={e => e.currentTarget.style.background = 'var(--cream)'}
               onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
               style={{
                 display: 'grid', gridTemplateColumns: '1.6fr 1fr 0.6fr 0.7fr 0.9fr',
                 gap: 8, padding: '10px', alignItems: 'center', fontSize: 12.5, cursor: 'pointer',
                 borderBottom: i === rows.length - 1 ? 'none' : '1px solid var(--cream-2)',
               }}>
            <div>
              <div style={{ color: 'var(--ink)', fontWeight: 600 }}>{r.unit}</div>
              {r.openThreads > 0 && (
                <div style={{ fontSize: 11, color: r.overSla > 0 ? 'var(--terra)' : 'var(--ink-4)', marginTop: 1 }}>
                  {r.openThreads} open{r.overSla > 0 ? `, ${r.overSla} over SLA` : ''}
                </div>
              )}
            </div>
            <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
              <AdvisorAvatar advisor={advisor} size={22}/>
              <span style={{ fontSize: 12, color: 'var(--ink-2)' }}>{advisor.name}</span>
            </div>
            <div style={{ textAlign: 'right', fontFamily: 'var(--ff-mono)', color: 'var(--ink-2)', fontWeight: 600 }}>{r.threads}</div>
            <div style={{ textAlign: 'right', fontFamily: 'var(--ff-mono)', color: r.avgResponse > 4 ? 'var(--terra)' : 'var(--ink-2)' }}>{r.avgResponse}h</div>
            <div>
              <span style={{ display: 'inline-flex', alignItems: 'center', gap: 5, padding: '2px 8px', borderRadius: 999, background: bg, color: tone, fontSize: 10.5, fontWeight: 700 }}>
                <span style={{ width: 5, height: 5, borderRadius: '50%', background: tone }}/>
                {statusLabel}
              </span>
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ----------- Common themes -----------
function CommonThemesCard({ themes }) {
  return (
    <div className="card card-pad">
      <div className="card-header" style={{ marginBottom: 10 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ width: 22, height: 22, borderRadius: '50%', background: 'var(--violet-soft, rgba(77,105,137,.12))', color: 'var(--violet)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12, fontWeight: 700 }}>L</span>
          <div>
            <div className="card-title">Common themes</div>
            <div className="card-sub">Lenny surfaced these from advisor threads</div>
          </div>
        </div>
      </div>
      {themes.map((t, i) => {
        const trendIcon = t.trend === 'rising' ? '↑' : t.trend === 'falling' ? '↓' : '→';
        const trendColor = t.trend === 'rising' ? 'var(--terra)' : t.trend === 'falling' ? 'var(--sage)' : 'var(--ink-4)';
        return (
          <div key={t.id} style={{ padding: '12px 0', borderBottom: i === themes.length - 1 ? 'none' : '1px solid var(--cream-2)' }}>
            <div style={{ display: 'flex', alignItems: 'baseline', gap: 8, marginBottom: 4 }}>
              <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)', flex: 1 }}>{t.theme}</span>
              <span style={{ fontSize: 11, fontFamily: 'var(--ff-mono)', color: trendColor, fontWeight: 700 }}>{trendIcon}</span>
              <span style={{ fontSize: 11, fontFamily: 'var(--ff-mono)', color: 'var(--ink-3)' }}>{t.locations} locations</span>
            </div>
            <div style={{ fontSize: 11.5, color: 'var(--ink-3)', marginBottom: 8, lineHeight: 1.5 }}>{t.note}</div>
            <div style={{ display: 'flex', gap: 8 }}>
              <button className="btn btn-quiet btn-xs" onClick={() => Ts('Threads opened', `Showing all ${t.locations} threads on "${t.theme}".`, 'info')}>View threads</button>
              {t.promote && (
                <button className="btn btn-marigold btn-xs"
                        onClick={() => Ts('Promoted to playbook', `"${t.theme}" queued for playbook activation review.`, 'ok')}>
                  Promote to playbook →
                </button>
              )}
            </div>
          </div>
        );
      })}
    </div>
  );
}

// ----------- Advisor leaderboard -----------
function AdvisorLeaderboard({ rows }) {
  const sorted = [...rows].sort((a, b) => a.avgResolutionDays - b.avgResolutionDays);
  return (
    <div className="card card-pad">
      <div className="card-header" style={{ marginBottom: 10 }}>
        <div>
          <div className="card-title">Advisor leaderboard</div>
          <div className="card-sub">Top advisors this month · resolution time + satisfaction</div>
        </div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12 }}>
        {sorted.map((r, i) => {
          const advisor = ADVISORS[r.advisor];
          return (
            <div key={r.advisor} style={{ padding: 14, background: 'var(--cream)', border: '1px solid var(--cream-3)', borderRadius: 10, position: 'relative' }}>
              <div style={{ position: 'absolute', top: 10, right: 12, fontSize: 10, color: 'var(--ink-4)', fontFamily: 'var(--ff-mono)', fontWeight: 700 }}>#{i + 1}</div>
              <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 12 }}>
                <AdvisorAvatar advisor={advisor} size={36}/>
                <div>
                  <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>{advisor.name}</div>
                  <div style={{ fontSize: 11, color: 'var(--ink-4)' }}>{advisor.role}</div>
                </div>
              </div>
              <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 6 }}>
                <Stat label="Threads"   v={r.threads}/>
                <Stat label="Avg resol." v={`${r.avgResolutionDays}d`}/>
                <Stat label="CSAT"      v={`${r.satisfaction}★`}/>
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

function Stat({ label, v }) {
  return (
    <div>
      <div style={{ fontSize: 9.5, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.06em', fontWeight: 700, marginBottom: 2 }}>{label}</div>
      <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ink)', fontFamily: 'var(--ff-display)' }}>{v}</div>
    </div>
  );
}
