// ====================================================================
// HQ ROLLUP, Corporate / Franchisor portfolio view
// Rebuilt: Portfolio · Listings · Offers tabs, regional parsing,
//   services enrollment, review-theme intelligence, labels, budget push
// ====================================================================

const { useState: useStateH, useMemo: useMemoH, useEffect: useEffectH } = React;

function HqPage({ data, persona, onNav }) {
  const [tab, setTab] = useStateH('portfolio');
  const [range, setRange] = useStateH('month');
  const [locDetail, setLocDetail] = useStateH(null);
  const [newOffer, setNewOffer] = useStateH(false);
  const [labelMgr, setLabelMgr] = useStateH(false);

  const fullData = useMemoH(() => {
    const r700 = window.buildPortfolio ? window.buildPortfolio(data.hqRollup, 700) : data.hqRollup;
    return { ...data, hqRollup: r700 };
  }, [data]);
  const rollup = fullData.hqRollup;
  const brand = "FreshNest";
  const regionCount = new Set(rollup.map((r) => r.region)).size;
  const subtitle = `${rollup.length.toLocaleString()} locations · ${regionCount} regions · your brand`;

  return (
    <div className="page active">
      <div className="page-header">
        <div>
          <div className="page-title">Local Portfolio.</div>
          <div className="page-sub">{subtitle}</div>
        </div>
        <div className="page-actions">
          <DropMenu value={range} onPick={(v) => {setRange(v);T('Range updated', v === 'month' ? 'This month' : v === 'qtr' ? 'This quarter' : 'Year to date', 'info');}} options={[
          { v: 'month', l: 'This month' }, { v: 'qtr', l: 'This quarter' }, { v: 'year', l: 'Year to date' }]
          } />
          <button className="btn btn-ghost btn-sm" onClick={() => T('Rollup exporting', 'XLS + PDF rollup queued, download link will email in ~2 min.', 'ok')}>Export roll-up</button>
        </div>
      </div>

      <div className="tabs">
        {[['portfolio', 'Portfolio'], ['offers', 'Offers & Labels']].map(([k, l]) =>
        <button key={k} className={`tab ${tab === k ? 'active' : ''}`} onClick={() => setTab(k)}>{l}</button>
        )}
      </div>

      {tab === 'portfolio' && <PortfolioTab data={fullData} onOpen={setLocDetail} />}
      {tab === 'offers' && <OffersTab data={fullData} onNewOffer={() => setNewOffer(true)} onManageLabels={() => setLabelMgr(true)} />}

      <LocationModal loc={locDetail} onClose={() => setLocDetail(null)} />
      <NewOfferModal open={newOffer} onClose={() => setNewOffer(false)} data={fullData} />
      <LabelManagerModal open={labelMgr} onClose={() => setLabelMgr(false)} />
    </div>);

}
window.HqPage = HqPage;

// ====================================================================
// PORTFOLIO TAB, KPIs, regions, services, table, distribution chart
// ====================================================================
function PortfolioTab({ data, onOpen }) {
  const rollup = data.hqRollup;
  const [filter, setFilter] = useStateH({ region: 'all', tier: 'all', label: 'all', readiness: 'all', sort: 'score' });
  const PORT_PAGE = 50;
  const [page, setPage] = useStateH(1);

  // KPIs
  const totals = useMemoH(() => {
    const totalLeads = rollup.reduce((s, r) => s + r.leads, 0);
    const totalSpend = rollup.reduce((s, r) => s + r.spend, 0);
    const avgScore = Math.round(rollup.reduce((s, r) => s + r.score, 0) / rollup.length);
    const onTrack = rollup.filter((r) => r.score >= 75).length;
    const attention = rollup.filter((r) => r.score < 75).length;
    const stars = rollup.filter((r) => r.tier === 'star').length;
    return { totalLeads, totalSpend, avgScore, onTrack, attention, stars };
  }, [rollup]);

  // Primary KPI = monthly leads vs the location's lead goal, modeled at the
  // network target CPL ($32, reconciles to data.network paid-media totals).
  // "Meeting" = leads at or above goal. This is deliberately independent of
  // LocalScore — corporate ranks regions on KPI attainment, not the composite.
  const kpiGoal = (r) => Math.max(1, Math.round(r.spend / 32));
  const kpiPct = (r) => r.leads / kpiGoal(r) * 100;

  // Regional aggregation
  const regions = useMemoH(() => {
    const map = {};
    rollup.forEach((r) => {
      if (!map[r.region]) map[r.region] = { name: r.region, locs: [], score: 0, leads: 0, spend: 0, rating: 0 };
      map[r.region].locs.push(r);
      map[r.region].leads += r.leads;
      map[r.region].spend += r.spend;
    });
    Object.values(map).forEach((rg) => {
      rg.score = Math.round(rg.locs.reduce((s, l) => s + l.score, 0) / rg.locs.length);
      rg.rating = (rg.locs.reduce((s, l) => s + l.rating, 0) / rg.locs.length).toFixed(2);
      rg.stars = rg.locs.filter((l) => l.tier === 'star').length;
      rg.attention = rg.locs.filter((l) => l.score < 75).length;
      rg.meeting = rg.locs.filter((l) => kpiPct(l) >= 100).length;
      rg.missing = rg.locs.length - rg.meeting;
      rg.meetingPct = Math.round(rg.meeting / rg.locs.length * 100);
    });
    return Object.values(map).sort((a, b) => b.meetingPct - a.meetingPct);
  }, [rollup]);

  // Distribution buckets — locations by how they pace against their lead-goal KPI.
  const buckets = useMemoH(() => {
    const b = [
    { label: 'Missing', sub: '<75% of goal', range: [0, 75], color: 'var(--terra)' },
    { label: 'Behind', sub: '75–99%', range: [75, 100], color: 'var(--marigold)' },
    { label: 'Meeting', sub: '100–124%', range: [100, 125], color: 'var(--sky)' },
    { label: 'Exceeding', sub: '125%+', range: [125, Infinity], color: 'var(--sage)' }];

    b.forEach((x) => x.count = rollup.filter((r) => { const p = kpiPct(r); return p >= x.range[0] && p < x.range[1]; }).length);
    return b;
  }, [rollup]);

  // Filtered/sorted table
  const filtered = useMemoH(() => {
    let rows = [...rollup];
    if (filter.region !== 'all') rows = rows.filter((r) => r.region === filter.region);
    if (filter.tier !== 'all') rows = rows.filter((r) => r.tier === filter.tier);
    if (filter.label !== 'all') rows = rows.filter((r) => r.labels.includes(filter.label));
    if (filter.readiness !== 'all') rows = rows.filter((r) => (r.readiness || 'ready') === filter.readiness);
    if (filter.sort === 'score') rows.sort((a, b) => b.score - a.score);
    if (filter.sort === 'leads') rows.sort((a, b) => b.leads - a.leads);
    if (filter.sort === 'spend') rows.sort((a, b) => b.spend - a.spend);
    if (filter.sort === 'rating') rows.sort((a, b) => b.rating - a.rating);
    if (filter.sort === 'trend') rows.sort((a, b) => b.trend - a.trend);
    return rows;
  }, [rollup, filter]);

  const allLabels = useMemoH(() => {
    const s = new Set();
    rollup.forEach((r) => r.labels.forEach((l) => s.add(l)));
    return Array.from(s);
  }, [rollup]);

  // Pagination over the filtered set (portfolio can be 700 rows).
  useEffectH(() => { setPage(1); }, [filter]);
  const pageCount = Math.max(1, Math.ceil(filtered.length / PORT_PAGE));
  const paged = useMemoH(() => filtered.slice((page - 1) * PORT_PAGE, page * PORT_PAGE), [filtered, page]);

  return (
    <div>
      {/* National vs Local investment KPI strip */}
      <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 14, marginBottom: 14 }}>
        {(() => {
          const n = data.network;
          return (
            <>
              <div className="card card-pad streak-panel" style={{ position: 'relative', overflow: 'hidden' }}>
                <div style={{ position: 'relative', zIndex: 1 }}>
                  <div style={{ fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'rgba(250,246,239,.65)', fontWeight: 600, marginBottom: 6, display: 'flex', alignItems: 'center', gap: 6 }}>
                    Corporate-funded baseline
                  </div>
                  <div style={{ fontFamily: 'var(--ff-display)', fontSize: 36, fontWeight: 500, lineHeight: 1, letterSpacing: '-0.02em' }}>${n.funding.corporateBaseline.toLocaleString()}<span style={{ fontSize: 13, color: 'rgba(250,246,239,.6)', fontWeight: 400 }}>/mo</span></div>
                  <div style={{ fontSize: 12, color: 'rgba(250,246,239,.7)', marginTop: 6 }}>All {n.totalLocations.toLocaleString()} locations on the Google Search baseline · $100/mo each · {n.baselinePct}% always on</div>
                  <div style={{ display: 'flex', gap: 6, marginTop: 14, flexWrap: 'wrap' }}>
                    {n.channels.baseline.map((c) =>
                    <span key={c} style={{ fontSize: 11, padding: '4px 9px', background: 'rgba(250,246,239,.12)', borderRadius: 999, color: 'var(--cream)' }}>{c}</span>
                    )}
                  </div>
                </div>
              </div>
              <div className="card card-pad" style={{ background: 'linear-gradient(135deg, var(--terra-soft), var(--cream-2))', border: '1px solid var(--cream-3)' }}>
                <div style={{ fontSize: 11, letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--ink-3)', fontWeight: 600, marginBottom: 6, display: 'flex', alignItems: 'center', gap: 6 }}>
                  Franchisee-funded incremental
                </div>
                <div style={{ fontFamily: 'var(--ff-display)', fontSize: 36, fontWeight: 500, lineHeight: 1, letterSpacing: '-0.02em', color: 'var(--ink)' }}>${n.funding.franchiseeIncremental.toLocaleString()}<span style={{ fontSize: 13, color: 'var(--ink-3)', fontWeight: 400 }}>/mo</span></div>
                <div style={{ fontSize: 12, color: 'var(--ink-3)', marginTop: 6 }}>{n.incrementalEnrolled} of {n.totalLocations} enrolled in paid services above baseline ({n.incrementalPct}%)</div>
                <div style={{ display: 'flex', gap: 12, marginTop: 14, fontSize: 11.5 }}>
                  <div style={{ padding: '6px 10px', background: 'var(--paper)', borderRadius: 8, flex: 1 }}>
                    <div style={{ color: 'var(--ink-4)', fontSize: 10, fontWeight: 600, letterSpacing: '0.04em', textTransform: 'uppercase' }}>Total media spend</div>
                    <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 13, fontWeight: 600 }}>${n.funding.totalMonthly.toLocaleString()}/mo</div>
                  </div>
                  <div style={{ padding: '6px 10px', background: 'var(--paper)', borderRadius: 8, flex: 1 }}>
                    <div style={{ color: 'var(--ink-4)', fontSize: 10, fontWeight: 600, letterSpacing: '0.04em', textTransform: 'uppercase' }}>Co-op programs</div>
                    <div style={{ fontFamily: 'var(--ff-mono)', fontSize: 13, fontWeight: 600 }}>{n.funding.coopLocations} locs · {n.funding.coopMarkets} markets</div>
                  </div>
                </div>
              </div>
            </>);

        })()}
      </div>

      <SourceNote>Source: Google Ads + FreshNest CRM · corporate baseline $70K + franchisee incremental $403K</SourceNote>

      {/* Network at a glance — structural facts, all from data.network (SoT) */}
      {(() => {
        const n = data.network;
        const Cell = ({ l, v, s }) => (
          <div style={{ padding: '2px 0' }}>
            <div style={{ fontSize: 10, color: 'var(--ink-4)', textTransform: 'uppercase', letterSpacing: '0.07em', fontWeight: 700 }}>{l}</div>
            <div style={{ fontFamily: 'var(--ff-display)', fontSize: 22, fontWeight: 500, color: 'var(--ink)', lineHeight: 1.15, marginTop: 3 }}>{v}</div>
            {s && <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 2 }}>{s}</div>}
          </div>
        );
        return (
          <div className="card card-pad" style={{ marginBottom: 24 }}>
            <div className="card-header" style={{ marginBottom: 10 }}>
              <div>
                <div className="card-title">Network at a glance</div>
                <div className="card-sub">{n.period} · data through {n.dataThrough} · demo data, fictional company</div>
              </div>
            </div>
            <div className="grid" style={{ gridTemplateColumns: 'repeat(4, 1fr)', gap: 18, rowGap: 16 }}>
              <Cell l="Total locations" v={n.totalLocations.toLocaleString()} s={`${n.corporateOwned} corporate · ${n.franchiseeOwned} franchisee · ~${n.franchiseOwners} owners`} />
              <Cell l="Location type" v={`${n.serviceOnly} / ${n.serviceRetail}`} s={`Service only (${n.serviceOnlyPct}%) · Service + Retail (${n.serviceRetailPct}%)`} />
              <Cell l="On Google Search baseline" v={`${n.baselineActive.toLocaleString()} · ${n.baselinePct}%`} s={`Corporate-funded $${n.baselinePerLoc}/mo each`} />
              <Cell l="Incremental enrolled" v={`${n.incrementalEnrolled} · ${n.incrementalPct}%`} s={`Goal ${n.enrollmentGoal} (${n.enrollmentGoalPct}%) · gap ${n.enrollmentGap}`} />
              <Cell l="Enrollment mix" v={`${n.mix.bareMinimum} / ${n.mix.inBetween} / ${n.mix.maximizers}`} s={`Bare (${n.mix.bareMinimumPct}%) · mid (${n.mix.inBetweenPct}%) · max (${n.mix.maximizersPct}%)`} />
              <Cell l="Monthly media spend" v={`$${(n.funding.totalMonthly / 1000).toFixed(0)}K`} s={`$${(n.funding.corporateBaseline / 1000).toFixed(0)}K corp + $${(n.funding.franchiseeIncremental / 1000).toFixed(0)}K franchisee`} />
              <Cell l="Attributed revenue" v={`$${(n.performance.totalRevenue / 1e6).toFixed(2)}M`} s={`$${(n.performance.jobRevenue / 1e6).toFixed(2)}M jobs + $${(n.performance.productRevenue / 1e6).toFixed(2)}M product`} />
              <Cell l="Booked jobs" v={`${n.performance.bookedJobs.toLocaleString()} · ${n.performance.bookedRate}%`} s={`Of ${n.performance.leads.toLocaleString()} leads · ${n.coverage.crmRevenuePct}% CRM coverage`} />
            </div>
            <div style={{ marginTop: 14, paddingTop: 12, borderTop: '1px solid var(--cream-2)', fontSize: 11.5, color: 'var(--ink-3)' }}>
              Co-op programs run across {n.funding.coopLocations} locations in {n.funding.coopMarkets} markets · {n.coverage.noValueLocations} locations ({n.coverage.noValuePct}%) have tracked conversions with no assigned value, so ROAS can't calculate for them.
            </div>
          </div>
        );
      })()}

      <SourceNote>Source: FreshNest CRM + Google Business Profile · LocalScore calculated by LOCALACT</SourceNote>

      {/* Regions + Distribution */}
      <div className="grid" style={{ gridTemplateColumns: '1.6fr 1fr', gap: 20, marginBottom: 24 }}>
        <div className="card card-pad">
          <div className="card-header">
            <div>
              <div className="card-title">Performance by region</div>
              <div className="card-sub">Locations meeting their lead-volume goal, ranked · groupings will be franchisor-configurable</div>
            </div>
          </div>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 10, marginTop: 6 }}>
            {regions.map((rg, i) => <RegionRow key={i} rg={rg} total={rollup.length} />)}
          </div>
        </div>

        <div className="card card-pad">
          <div className="card-header">
            <div>
              <div className="card-title">KPI attainment</div>
              <div className="card-sub">Locations by pace against their lead goal</div>
            </div>
          </div>
          <ScoreHistogram buckets={buckets} total={rollup.length} />
        </div>
      </div>

      <SourceNote>Source: FreshNest CRM · lead goals modeled at the network target CPL</SourceNote>

      {/* Location table with filters */}
      <div className="section-label">
        All locations
        <span className="count">Representative sample · {filtered.length} of {data.network.totalLocations.toLocaleString()} locations</span>
      </div>

      <div className="card card-pad" style={{ marginBottom: 12, padding: '14px 18px' }}>
        <div style={{ display: 'flex', gap: 10, alignItems: 'center', flexWrap: 'wrap' }}>
          <span style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-3)', fontWeight: 600 }}>Filter</span>
          <FilterPill label="Region" value={filter.region} options={[['all', 'All'], ...regions.map((r) => [r.name, r.name])]} onPick={(v) => setFilter((f) => ({ ...f, region: v }))} />
          <FilterPill label="Status" value={filter.tier} options={[['all', 'All'], ['star', '★ Top'], ['mid', '● On track'], ['low', '⚠ Attention']]} onPick={(v) => setFilter((f) => ({ ...f, tier: v }))} />
          <FilterPill label="Label" value={filter.label} options={[['all', 'All'], ...allLabels.map((l) => [l, l])]} onPick={(v) => setFilter((f) => ({ ...f, label: v }))} />
          <FilterPill label="Readiness" value={filter.readiness} options={[['all', 'All'], ['ready', 'Ready'], ['attention', 'Needs attention'], ['blocked', 'Blocked']]} onPick={(v) => setFilter((f) => ({ ...f, readiness: v }))} />
          <div style={{ flex: 1 }} />
          <FilterPill label="Sort" value={filter.sort} options={[['score', 'LocalScore'], ['leads', 'Leads'], ['spend', 'Spend'], ['rating', 'Rating'], ['trend', 'Trend']]} onPick={(v) => setFilter((f) => ({ ...f, sort: v }))} />
        </div>
      </div>

      <div className="card" style={{ overflow: 'hidden' }}>
        <table className="tbl">
          <thead>
            <tr>
              <th>Location</th>
              <th>Region</th>
              <th>Readiness</th>
              <th>LocalScore</th>
              <th>Leads</th>
              <th>Spend</th>
              <th>Rating</th>
              <th>Initiatives</th>
              <th>Trend</th>
              <th />
            </tr>
          </thead>
          <tbody>
            {paged.map((r, i) =>
            <tr key={i} onClick={() => onOpen(r)} style={{ cursor: 'pointer' }}>
                <td>
                  <div style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>
                    <span className="strong">{r.unit}</span>
                    <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>{r.city}</span>
                  </div>
                </td>
                <td className="muted">{r.region}</td>
                <td><ReadinessBadge status={r.readiness || 'ready'} /></td>
                <td>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                    <span style={{ fontFamily: 'var(--ff-display)', fontSize: 17, fontWeight: 500, minWidth: 24 }}>{r.score}</span>
                    <div style={{ width: 64, height: 4, background: 'var(--cream-2)', borderRadius: 2 }}>
                      <div style={{ width: r.score + '%', height: '100%', background: r.score >= 85 ? 'var(--sage)' : r.score >= 75 ? 'var(--sky)' : r.score >= 65 ? 'var(--marigold)' : 'var(--terra)', borderRadius: 2 }} />
                    </div>
                  </div>
                </td>
                <td className="mono">{r.leads}</td>
                <td className="mono">${r.spend.toLocaleString()}</td>
                <td>
                  <span style={{ fontFamily: 'var(--ff-display)', fontWeight: 500 }}>{r.rating.toFixed(1)}</span>
                  <span style={{ color: 'var(--marigold)', marginLeft: 2 }}>★</span>
                  <span style={{ fontSize: 11, color: 'var(--ink-3)', marginLeft: 6 }}>({r.reviews})</span>
                </td>
                <td>
                  <div style={{ display: 'flex', gap: 3 }}>
                    {['seo', 'ppc', 'meta', 'listings', 'web', 'reviews'].map((s) =>
                  <div key={s} title={data.hqServices[s].name} style={{
                    width: 18, height: 18, borderRadius: 4,
                    background: r.services.includes(s) ? data.hqServices[s].color : 'var(--cream-2)',
                    opacity: r.services.includes(s) ? 1 : 0.35,
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontSize: 9, fontWeight: 700,
                    color: r.services.includes(s) ? '#fff' : 'var(--ink-4)'
                  }}>{s[0].toUpperCase()}</div>
                  )}
                  </div>
                </td>
                <td>
                  <TrendChip trend={r.trend} />
                </td>
                <td><button className="btn btn-quiet btn-xs" onClick={(e) => {e.stopPropagation();onOpen(r);}}>Open →</button></td>
              </tr>
            )}
          </tbody>
        </table>
      </div>

      {pageCount > 1 &&
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginTop: 12 }}>
        <span style={{ fontSize: 11.5, color: 'var(--ink-4)' }}>
          Showing {filtered.length === 0 ? 0 : (page - 1) * PORT_PAGE + 1}–{Math.min(page * PORT_PAGE, filtered.length)} of {filtered.length.toLocaleString()} locations
        </span>
        <div style={{ flex: 1 }} />
        <button className="btn btn-ghost btn-xs" disabled={page === 1} onClick={() => setPage((p) => Math.max(1, p - 1))} style={page === 1 ? { opacity: 0.4 } : {}}>← Prev</button>
        <span style={{ fontSize: 11.5, color: 'var(--ink-3)', fontFamily: 'var(--ff-mono)' }}>Page {page} / {pageCount}</span>
        <button className="btn btn-ghost btn-xs" disabled={page === pageCount} onClick={() => setPage((p) => Math.min(pageCount, p + 1))} style={page === pageCount ? { opacity: 0.4 } : {}}>Next →</button>
      </div>
      }
    </div>);

}

// ====================================================================
// REGION ROW
// ====================================================================
function RegionRow({ rg, total }) {
  const pct = rg.locs.length / total * 100;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 16, padding: '12px 0', borderBottom: '1px dashed var(--cream-3)' }}>
      <div style={{ minWidth: 110 }}>
        <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>{rg.name}</div>
        <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>{rg.locs.length} locations</div>
      </div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
          <div style={{ fontFamily: 'var(--ff-display)', fontSize: 22, fontWeight: 500 }}>{rg.meetingPct}%</div>
          <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>meeting KPI</div>
          <div style={{ flex: 1 }} />
          <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>
            <span style={{ color: 'var(--sage)', fontWeight: 600 }}>{rg.meeting} meeting</span>
            {' · '}
            <span style={{ color: 'var(--terra)', fontWeight: 600 }}>{rg.missing} missing</span>
          </div>
        </div>
        <div style={{ width: '100%', height: 6, background: 'var(--cream-2)', borderRadius: 3, overflow: 'hidden' }}>
          <div style={{ width: rg.meetingPct + '%', height: '100%', background: rg.meetingPct >= 70 ? 'var(--sage)' : rg.meetingPct >= 50 ? 'var(--sky)' : 'var(--marigold)', borderRadius: 3 }} />
        </div>
      </div>
      <div style={{ textAlign: 'right', minWidth: 90 }}>
        <div style={{ fontFamily: 'var(--ff-display)', fontSize: 16, fontWeight: 500 }}>{rg.leads.toLocaleString()}</div>
        <div style={{ fontSize: 10, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>leads</div>
      </div>
      <div style={{ textAlign: 'right', minWidth: 90 }}>
        <div style={{ fontFamily: 'var(--ff-display)', fontSize: 16, fontWeight: 500 }}>{rg.rating}<span style={{ color: 'var(--marigold)' }}>★</span></div>
        <div style={{ fontSize: 10, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.06em' }}>rating</div>
      </div>
    </div>);

}

// ====================================================================
// SCORE HISTOGRAM
// ====================================================================
function ScoreHistogram({ buckets, total }) {
  const max = Math.max(...buckets.map((b) => b.count), 1);
  // Logic-driven summary (computed from the buckets, not generated text).
  const get = (l) => (buckets.find((b) => b.label === l) || { count: 0 }).count;
  const onOrAbove = get('Meeting') + get('Exceeding');
  const behind = get('Behind');
  const missing = get('Missing');
  const denom = total || buckets.reduce((s, b) => s + b.count, 0) || 1;
  const pct = Math.round(onOrAbove / denom * 100);
  return (
    <div>
      <div style={{ fontSize: 12.5, color: 'var(--ink-2)', lineHeight: 1.5, marginTop: 4, marginBottom: 6 }}>
        <strong style={{ color: 'var(--ink)' }}>{onOrAbove.toLocaleString()} of {denom.toLocaleString()} locations ({pct}%)</strong> are meeting or exceeding their lead goal · <span style={{ color: 'var(--terra)', fontWeight: 600 }}>{(behind + missing).toLocaleString()} behind</span>.
      </div>
      <div style={{ display: 'flex', alignItems: 'flex-end', gap: 12, height: 190, padding: '24px 4px 0' }}>
        {buckets.map((b, i) => {
          const h = b.count / max * 130;
          return (
            <div key={i} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'flex-end', gap: 8, height: '100%' }}>
              <div style={{ fontFamily: 'var(--ff-display)', fontSize: 18, fontWeight: 500, lineHeight: 1 }}>{b.count}</div>
              <div style={{ width: '100%', height: h, minHeight: 4, background: b.color, borderRadius: '6px 6px 2px 2px', transition: 'height .4s ease' }} />
              <div style={{ fontSize: 11, color: 'var(--ink-2)', fontWeight: 600 }}>{b.label}</div>
              {b.sub && <div style={{ fontSize: 9.5, color: 'var(--ink-4)', marginTop: -4 }}>{b.sub}</div>}
            </div>);

        })}
      </div>
    </div>);

}

// ====================================================================
// SERVICE ENROLL BAR
// ====================================================================
function ServiceEnrollBar({ s }) {
  const pct = s.enrolled / s.total * 100;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '8px 0' }}>
      <div style={{ minWidth: 130, fontSize: 13, fontWeight: 600 }}>{s.name}</div>
      <div style={{ flex: 1, height: 8, background: 'var(--cream-2)', borderRadius: 4, overflow: 'hidden' }}>
        <div style={{ width: pct + '%', height: '100%', background: s.color, borderRadius: 4 }} />
      </div>
      <div style={{ minWidth: 68, textAlign: 'right', fontSize: 12, color: 'var(--ink-3)' }}>
        <span style={{ fontFamily: 'var(--ff-display)', fontSize: 14, fontWeight: 500, color: 'var(--ink)' }}>{s.enrolled}</span>
        <span style={{ color: 'var(--ink-4)' }}> / {s.total}</span>
      </div>
      <div style={{ minWidth: 42, textAlign: 'right', fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--ff-display)', fontWeight: 500 }}>{Math.round(pct)}%</div>
    </div>);

}

// ====================================================================
// TREND CHIP
// ====================================================================
// READINESS BADGE — concept-level marketing-readiness status
// ====================================================================
const READINESS_META = {
  ready:     { label: 'Ready',           dot: 'var(--sage)',     bg: 'var(--sage-soft)',     fg: 'var(--sage-ink, #2f5d3a)' },
  attention: { label: 'Needs attention', dot: 'var(--marigold)', bg: 'var(--marigold-soft)', fg: '#8a5a10' },
  blocked:   { label: 'Blocked',         dot: 'var(--terra)',    bg: 'var(--terra-soft)',    fg: '#8c2f22' },
};
function ReadinessBadge({ status }) {
  const m = READINESS_META[status] || READINESS_META.ready;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '3px 9px 3px 8px', borderRadius: 999, background: m.bg, color: m.fg, fontSize: 11, fontWeight: 600, whiteSpace: 'nowrap', lineHeight: 1.4 }}>
      <span style={{ width: 7, height: 7, borderRadius: '50%', background: m.dot, flexShrink: 0 }} />
      {m.label}
    </span>);

}

// ====================================================================
function TrendChip({ trend }) {
  const up = trend > 0;
  const flat = trend === 0;
  const color = flat ? 'var(--ink-3)' : up ? 'var(--sage)' : 'var(--terra)';
  const arrow = flat ? '–' : up ? '▲' : '▼';
  return (
    <span style={{ fontFamily: 'var(--ff-display)', fontSize: 13, fontWeight: 500, color }}>
      {arrow} {Math.abs(trend)}
    </span>);

}

// ====================================================================
// FILTER PILL
// ====================================================================
function FilterPill({ label, value, options, onPick }) {
  const current = options.find((o) => o[0] === value);
  return (
    <div style={{ display: 'inline-flex', alignItems: 'center', gap: 0 }}>
      <span style={{ fontSize: 11, color: 'var(--ink-3)', marginRight: 6 }}>{label}:</span>
      <DropMenu value={value} onPick={onPick} options={options.map((o) => ({ v: o[0], l: o[1] }))} />
    </div>);

}

// ====================================================================
// LISTINGS & REVIEWS INTEL TAB
// ====================================================================
function ListingsIntelTab({ data, onOpen }) {
  const rollup = data.hqRollup;
  const themes = data.hqReviewThemes;

  const totals = useMemoH(() => {
    const totalReviews = rollup.reduce((s, r) => s + r.reviews, 0);
    const weightedRating = rollup.reduce((s, r) => s + r.rating * r.reviews, 0) / totalReviews;
    const topPerf = rollup.filter((r) => r.rating >= 4.5).length;
    const strugglers = rollup.filter((r) => r.rating < 4.0).length;
    const mid = rollup.length - topPerf - strugglers;
    return { totalReviews, weightedRating, topPerf, mid, strugglers };
  }, [rollup]);

  const tiers = useMemoH(() => ({
    top: rollup.filter((r) => r.rating >= 4.5).sort((a, b) => b.rating - a.rating),
    mid: rollup.filter((r) => r.rating >= 4.0 && r.rating < 4.5).sort((a, b) => b.rating - a.rating),
    low: rollup.filter((r) => r.rating < 4.0).sort((a, b) => a.rating - b.rating)
  }), [rollup]);

  return (
    <div>
      {/* KPI strip */}
      <div className="grid grid-4" style={{ marginBottom: 24 }}>
        <StatCard l="Total reviews" v={totals.totalReviews.toLocaleString()} sub={`+${Math.round(totals.totalReviews * 0.05).toLocaleString()} this month`} c="var(--ink)" />
        <StatCard l="Portfolio rating" v={totals.weightedRating.toFixed(2) + '★'} sub="weighted by volume" c="var(--marigold)" />
        <StatCard l="Top performers" v={totals.topPerf} sub="4.5★ or higher" c="var(--sage)" bar={totals.topPerf / rollup.length * 100} />
        <StatCard l="Needs coaching" v={totals.strugglers} sub="below 4.0★" c="var(--warn)" bar={totals.strugglers / rollup.length * 100} />
      </div>

      <SourceNote>Source: Google Business Profile · portfolio review rollup calculated by LOCALACT</SourceNote>

      {/* Three tier cards */}
      <div className="section-label">Performance tiers <span className="count">ranked by review rating</span></div>
      <div className="grid grid-3" style={{ marginBottom: 24 }}>
        <TierCard title="Top performers" subtitle="4.5★ and above" count={tiers.top.length} locs={tiers.top.slice(0, 6)} color="var(--sage)" icon="★" onOpen={onOpen} />
        <TierCard title="Steady middle" subtitle="4.0★ – 4.4★" count={tiers.mid.length} locs={tiers.mid.slice(0, 6)} color="var(--sky)" icon="●" onOpen={onOpen} />
        <TierCard title="Needs coaching" subtitle="Below 4.0★" count={tiers.low.length} locs={tiers.low.slice(0, 6)} color="var(--terra)" icon="⚠" onOpen={onOpen} urgent />
      </div>

      <SourceNote>Source: Google Business Profile</SourceNote>

      {/* Review themes intelligence */}
      <div className="section-label">Review themes <span className="count">AI-extracted from {totals.totalReviews.toLocaleString()} reviews</span></div>
      <div className="grid grid-2" style={{ marginBottom: 24 }}>
        <ThemesCard
          title="What customers love"
          subtitle="Mentioned in 5★ and 4★ reviews"
          color="var(--sage)"
          themes={themes.positive}
          tone="positive" />
        
        <ThemesCard
          title="Common complaints"
          subtitle="Mentioned in 2★ and 1★ reviews"
          color="var(--terra)"
          themes={themes.negative}
          tone="negative" />
        
      </div>

      <SourceNote>Source: Google Business Profile · themes extracted by LOCALACT</SourceNote>

      {/* Lenny insight callout */}
      <div className="card card-pad" style={{ background: 'var(--cream)', border: '1px solid var(--line-2)', marginBottom: 24 }}>
        <div style={{ display: 'flex', gap: 18, alignItems: 'flex-start' }}>
          <div style={{ flexShrink: 0, width: 48, height: 48, borderRadius: 14, background: 'var(--terra-soft)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 22 }}>🦙</div>
          <div style={{ flex: 1 }}>
            <div style={{ fontFamily: 'var(--ff-display)', fontSize: 16, fontWeight: 600, marginBottom: 4 }}>Lenny spotted a pattern</div>
            <div style={{ fontSize: 13.5, color: 'var(--ink-2)', lineHeight: 1.65, marginBottom: 12 }}>
              {Math.round(rollup.length * 0.55).toLocaleString()} of your {rollup.length.toLocaleString()} locations get complaints about <strong>wait times at peak hours</strong>. That's the #1 negative theme portfolio-wide. Locations that added <strong>Yelp Waitlist</strong> (Austin Downtown, Houston Galleria) dropped those mentions 62% in 90 days.
            </div>
            <div style={{ display: 'flex', gap: 8 }}>
              <button className="btn btn-primary btn-sm" onClick={() => T('Playbook queued', `Waitlist rollout plan drafting, ${Math.round(rollup.length * 0.55).toLocaleString()} locations.`, 'ok')}>See the rollout plan →</button>
              <button className="btn btn-quiet btn-sm" onClick={() => T('Locations listed', `Filtered to ${Math.round(rollup.length * 0.55).toLocaleString()} locations with peak-wait complaints.`, 'info')}>Which locations?</button>
            </div>
          </div>
        </div>
      </div>

      {/* Listings health rollup */}
      <div className="section-label">Listings health <span className="count">directory accuracy across portfolio</span></div>
      <div className="grid grid-4" style={{ marginBottom: 0 }}>
        <StatCard l="Directories live" v={Math.round(rollup.length * 42 * 0.99).toLocaleString()} sub={`of ${(rollup.length * 42).toLocaleString()} · 42 per loc`} c="var(--sage)" bar={99} />
        <StatCard l="NAP accuracy" v="97%" sub="portfolio avg" c="var(--sage)" bar={97} />
        <StatCard l="Open issues" v={Math.round(rollup.length * 0.09).toLocaleString()} sub={`across ${Math.round(rollup.length * 0.06)} locations`} c="var(--warn)" />
        <StatCard l="Hours consistency" v="94%" sub={`${Math.round(rollup.length * 0.06)} locations flagged`} c="var(--marigold)" bar={94} />
      </div>
    </div>);

}

// ====================================================================
// TIER CARD
// ====================================================================
function TierCard({ title, subtitle, count, locs, color, icon, urgent, onOpen }) {
  return (
    <div className="card card-pad" style={urgent ? { border: '1px solid var(--terra-soft)' } : {}}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
        <div style={{ width: 26, height: 26, borderRadius: 7, background: color, color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 13, fontWeight: 700 }}>{icon}</div>
        <div style={{ fontFamily: 'var(--ff-display)', fontSize: 15, fontWeight: 600 }}>{title}</div>
      </div>
      <div style={{ fontSize: 12, color: 'var(--ink-3)', marginBottom: 2 }}>{subtitle}</div>
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 6, marginBottom: 14 }}>
        <span style={{ fontFamily: 'var(--ff-display)', fontSize: 36, fontWeight: 500, lineHeight: 1 }}>{count}</span>
        <span style={{ fontSize: 12, color: 'var(--ink-3)' }}>locations</span>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 2, borderTop: '1px dashed var(--cream-3)', paddingTop: 10 }}>
        {locs.map((l, i) =>
        <div key={i} onClick={() => onOpen(l)} style={{ display: 'flex', alignItems: 'center', gap: 10, padding: '6px 8px', borderRadius: 6, cursor: 'pointer', margin: '0 -8px' }}
        onMouseEnter={(e) => e.currentTarget.style.background = 'var(--cream)'}
        onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 12.5, fontWeight: 600, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{l.unit}</div>
              <div style={{ fontSize: 10.5, color: 'var(--ink-3)' }}>{l.reviews} reviews</div>
            </div>
            <div style={{ fontFamily: 'var(--ff-display)', fontSize: 15, fontWeight: 500 }}>
              {l.rating.toFixed(1)}<span style={{ color: 'var(--marigold)' }}>★</span>
            </div>
          </div>
        )}
      </div>
    </div>);

}

// ====================================================================
// THEMES CARD (positive/negative)
// ====================================================================
function ThemesCard({ title, subtitle, color, themes, tone }) {
  const [expanded, setExpanded] = useStateH(null);
  const max = Math.max(...themes.map((t) => t.count));

  return (
    <div className="card card-pad">
      <div className="card-header">
        <div>
          <div className="card-title">{title}</div>
          <div className="card-sub">{subtitle}</div>
        </div>
      </div>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 2, marginTop: 8 }}>
        {themes.map((t, i) => {
          const open = expanded === i;
          const pct = t.count / max * 100;
          return (
            <div key={i}>
              <div onClick={() => setExpanded(open ? null : i)} style={{ padding: '12px 10px', cursor: 'pointer', borderRadius: 8, margin: '0 -10px' }}
              onMouseEnter={(e) => !open && (e.currentTarget.style.background = 'var(--cream)')}
              onMouseLeave={(e) => !open && (e.currentTarget.style.background = 'transparent')}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 6 }}>
                  <div style={{ flex: 1, fontSize: 13, fontWeight: 600 }}>{t.theme}</div>
                  <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>{t.locations} locations</div>
                  <div style={{ fontFamily: 'var(--ff-display)', fontSize: 15, fontWeight: 500, minWidth: 40, textAlign: 'right' }}>{t.count}</div>
                  <div style={{ fontSize: 11, color: 'var(--ink-4)', transform: open ? 'rotate(90deg)' : 'rotate(0)', transition: 'transform .2s' }}>›</div>
                </div>
                <div style={{ width: '100%', height: 4, background: 'var(--cream-2)', borderRadius: 2, overflow: 'hidden' }}>
                  <div style={{ width: pct + '%', height: '100%', background: color, borderRadius: 2 }} />
                </div>
              </div>
              {open &&
              <div style={{ padding: '10px 14px', background: 'var(--cream)', borderRadius: 8, fontSize: 12.5, color: 'var(--ink-2)', lineHeight: 1.6, marginBottom: 4, borderLeft: `3px solid ${color}` }}>
                  <div style={{ fontStyle: 'italic', marginBottom: 8 }}>"{t.sample}"</div>
                  <div style={{ display: 'flex', gap: 8 }}>
                    <button className="btn btn-quiet btn-xs" onClick={(e) => {e.stopPropagation();T('Drill-through', `Showing ${t.count} reviews mentioning "${t.theme}".`, 'info');}}>See all {t.count} reviews</button>
                    {tone === 'negative' && <button className="btn btn-quiet btn-xs" onClick={(e) => {e.stopPropagation();T('Playbook queued', `Lenny drafting coaching plan for "${t.theme}".`, 'ok');}}>Draft playbook</button>}
                  </div>
                </div>
              }
            </div>);

        })}
      </div>
    </div>);

}

// ====================================================================
// OFFERS TAB
// ====================================================================
function OffersTab({ data, onNewOffer, onManageLabels }) {
  return (
    <div>
      <div style={{ background: 'var(--sky-soft)', border: '1px solid var(--sky)', borderRadius: 14, padding: '14px 18px', marginBottom: 24, fontSize: 12.5, color: '#001e40' }}>
        <strong>Corporate-pushed offers</strong> appear on every enrolled location's Google Business Profile, website, and paid ads. Individual franchisees can opt out per-offer.
      </div>

      {/* KPIs */}
      <div className="grid grid-4" style={{ marginBottom: 24 }}>
        <StatCard l="Active offers" v="2" sub="240 location-pushes" c="var(--terra)" />
        <StatCard l="Redemptions MTD" v="1,896" sub="-9% vs last month" c="var(--warn)" />
        <StatCard l="Avg uplift" v="+18%" sub="on enrolled locations" c="var(--sage)" />
        <StatCard l="Scheduled" v="1" sub="Mother's Day BOGO" c="var(--marigold)" />
      </div>

      <SourceNote>Source: FreshNest CRM · redemptions tracked by LOCALACT</SourceNote>

      {/* Offers table */}
      <div className="section-label">
        Portfolio offers
        <span className="count">{data.hqOffers.length} total</span>
        <div style={{ flex: 1 }} />
        <button className="btn btn-primary btn-sm" onClick={onNewOffer}>{Icon.plus} New offer</button>
      </div>
      <div className="card" style={{ overflow: 'hidden', marginBottom: 24 }}>
        <table className="tbl">
          <thead><tr><th>Offer</th><th>Status</th><th>Locations</th><th>Redemptions</th><th>Dates</th><th /></tr></thead>
          <tbody>
            {data.hqOffers.map((o, i) =>
            <tr key={i} onClick={() => T('Offer detail', `${o.name} · ${o.redemptions} redemptions across ${o.locations} locations.`, 'info')} style={{ cursor: 'pointer' }}>
                <td className="strong">{o.name}</td>
                <td><span className={`badge ${o.status === 'active' ? 'badge-ok' : o.status === 'scheduled' ? 'badge-info' : 'badge-neutral'}`}>{o.status}</span></td>
                <td className="mono">{o.locations} / 142</td>
                <td className="mono">{o.redemptions.toLocaleString()}</td>
                <td className="muted">{o.start} → {o.end}</td>
                <td>
                  <button className="btn btn-quiet btn-xs" onClick={(e) => {e.stopPropagation();T('Edit offer', `Opening ${o.name} in editor.`, 'info');}}>Edit</button>
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>

      {/* Labels management */}
      <div className="section-label">
        Custom labels
        <span className="count">segment your portfolio</span>
        <div style={{ flex: 1 }} />
        <button className="btn btn-ghost btn-sm" onClick={onManageLabels}>Manage labels</button>
      </div>
      <div className="card card-pad">
        <div style={{ fontSize: 13, color: 'var(--ink-2)', lineHeight: 1.65, marginBottom: 16 }}>
          Labels let you segment reporting and target actions, filter dashboards, push budget to a cohort, run offers on a subset. Labels are free-form; add whatever maps to how <em>you</em> think about your portfolio.
        </div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 10 }}>
          {[
          ['Flagship', 4, 'var(--terra)'],
          ['Urban', 12, 'var(--sky)'],
          ['Suburban', 5, 'var(--sage)'],
          ['Tourist', 5, 'var(--marigold)'],
          ['New opens', 0, 'var(--ink-4)'],
          ['Recovery', 0, 'var(--ink-4)']].
          map(([name, count, color], i) =>
          <div key={i} style={{
            display: 'inline-flex', alignItems: 'center', gap: 8,
            padding: '8px 14px',
            background: count > 0 ? 'var(--cream)' : 'transparent',
            border: count > 0 ? '1px solid var(--line)' : '1px dashed var(--line-2)',
            borderRadius: 999,
            cursor: 'pointer'
          }} onClick={() => T(`Filtered to "${name}"`, `${count} locations · report refreshing.`, 'info')}>
              <div style={{ width: 8, height: 8, borderRadius: '50%', background: color }} />
              <span style={{ fontSize: 12.5, fontWeight: 600 }}>{name}</span>
              <span style={{ fontSize: 11, color: 'var(--ink-3)' }}>{count}</span>
            </div>
          )}
          <button onClick={onManageLabels} style={{
            display: 'inline-flex', alignItems: 'center', gap: 6,
            padding: '8px 14px',
            background: 'transparent',
            border: '1px dashed var(--line-2)',
            borderRadius: 999,
            fontSize: 12.5, color: 'var(--ink-3)',
            cursor: 'pointer', fontWeight: 500
          }}>+ Add label</button>
        </div>
      </div>
    </div>);

}

// ====================================================================
// LOCATION DETAIL MODAL
// ====================================================================
function LocationModal({ loc, onClose }) {
  if (!loc) return <Modal open={false} onClose={onClose} />;
  return (
    <Modal open={!!loc} onClose={onClose} title={loc.unit} sub={`${loc.city} · ${loc.region} region`} width={640}
    footer={<>
        <button className="btn btn-ghost btn-sm" onClick={onClose}>Close</button>
        <button className="btn btn-primary btn-sm" onClick={() => {onClose();T('Switched to location view', `Now viewing ${loc.unit}`, 'ok');}}>Open location dashboard →</button>
      </>}>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10, marginBottom: 18 }}>
        {[
        ['LocalScore', loc.score, loc.score >= 85 ? 'var(--sage)' : loc.score >= 75 ? 'var(--sky)' : 'var(--terra)'],
        ['Leads', loc.leads, 'var(--ink)'],
        ['Spend', '$' + loc.spend.toLocaleString(), 'var(--ink)'],
        ['Rating', loc.rating.toFixed(1) + '★', 'var(--marigold)']].
        map(([l, v, c], i) =>
        <div key={i} style={{ padding: 12, background: 'var(--cream)', borderRadius: 10 }}>
            <div style={{ fontSize: 10, textTransform: 'uppercase', color: 'var(--ink-3)', fontWeight: 600, letterSpacing: '0.06em' }}>{l}</div>
            <div style={{ fontFamily: 'var(--ff-display)', fontSize: 22, fontWeight: 500, color: c }}>{v}</div>
          </div>
        )}
      </div>

      <div style={{ marginBottom: 16 }}>
        <div style={{ fontSize: 11, textTransform: 'uppercase', color: 'var(--ink-3)', fontWeight: 600, letterSpacing: '0.06em', marginBottom: 8 }}>Labels</div>
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
          {loc.labels.map((l) => <span key={l} className="badge badge-terra">{l}</span>)}
        </div>
      </div>

      <div style={{ marginBottom: 14 }}>
        <div style={{ fontSize: 11, textTransform: 'uppercase', color: 'var(--ink-3)', fontWeight: 600, letterSpacing: '0.06em', marginBottom: 8, display: 'flex', alignItems: 'center', gap: 6 }}>
          National initiatives <span style={{ color: 'var(--ink-4)', fontWeight: 500 }}>· inherited portfolio-wide</span>
        </div>
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
          <span className="badge badge-info" style={{ background: 'var(--brand-navy)', color: 'var(--cream)' }}>National Brand Search</span>
          <span className="badge badge-info" style={{ background: '#4d6989', color: 'var(--cream)' }}>Enterprise Programmatic</span>
        </div>
      </div>

      <div style={{ marginBottom: 16 }}>
        <div style={{ fontSize: 11, textTransform: 'uppercase', color: 'var(--ink-3)', fontWeight: 600, letterSpacing: '0.06em', marginBottom: 8, display: 'flex', alignItems: 'center', gap: 6 }}>
          Local initiatives <span style={{ color: 'var(--ink-4)', fontWeight: 500 }}>· enrolled at this location</span>
        </div>
        <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
          {loc.services.map((s) => <span key={s} className="badge badge-info">{s.toUpperCase()}</span>)}
          {loc.tier === 'star' && <span className="badge" style={{ background: '#e46c63', color: 'var(--cream)' }}>Mother's Day Promo</span>}
        </div>
      </div>

      <div style={{ padding: 14, background: 'var(--cream)', borderRadius: 12, fontSize: 12.5, color: 'var(--ink-2)', lineHeight: 1.65 }}>
        <strong>Lenny's take:</strong> 
        {loc.tier === 'star' ? 'Outperforming on all key channels. Great template for the system.' :
        loc.status === 'attention' ? 'Flagged for review, score dropped and CPL rising. Recovery plan drafted.' :
        'Performing in line with portfolio median. No urgent intervention needed.'}
      </div>
    </Modal>);

}

// ====================================================================
// NEW OFFER MODAL
// ====================================================================
function NewOfferModal({ open, onClose, data }) {
  const [form, setForm] = useStateH({ name: '', discount: '$5 off', startDate: 'May 15', endDate: 'May 31', scope: 'all' });
  const set = (k, v) => setForm((f) => ({ ...f, [k]: v }));

  return (
    <Modal open={open} onClose={onClose} title="New portfolio offer" sub="Pushes to all enrolled locations' GBP, web, and ads" width={560}
    footer={<>
        <button className="btn btn-ghost btn-sm" onClick={onClose}>Cancel</button>
        <button className="btn btn-primary btn-sm" onClick={() => {onClose();T('Offer scheduled', `${form.name || 'New offer'} launching ${form.startDate}.`, 'ok');}}>Schedule offer</button>
      </>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        <FormRow label="Offer name">
          <input className="inp" type="text" placeholder="e.g. Mother's Day BOGO" value={form.name} onChange={(e) => set('name', e.target.value)} />
        </FormRow>
        <FormRow label="Discount / headline">
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {['$5 off', '$10 off', 'BOGO', 'Free side', '20% off', 'Custom'].map((d) =>
            <button key={d} onClick={() => set('discount', d)} style={{
              padding: '7px 14px', borderRadius: 999,
              background: form.discount === d ? 'var(--ink)' : 'transparent',
              color: form.discount === d ? 'var(--cream)' : 'var(--ink-2)',
              border: form.discount === d ? '1px solid var(--ink)' : '1px solid var(--line)',
              fontSize: 12.5, fontWeight: 500, cursor: 'pointer'
            }}>{d}</button>
            )}
          </div>
        </FormRow>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
          <FormRow label="Start">
            <input className="inp" type="text" value={form.startDate} onChange={(e) => set('startDate', e.target.value)} />
          </FormRow>
          <FormRow label="End">
            <input className="inp" type="text" value={form.endDate} onChange={(e) => set('endDate', e.target.value)} />
          </FormRow>
        </div>
        <FormRow label="Push to">
          <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
            {[['all', 'All 700 locations'], ['star', 'Top performers (7)'], ['urban', 'Urban (12)'], ['tourist', 'Tourist (5)']].map(([v, l]) =>
            <button key={v} onClick={() => set('scope', v)} style={{
              padding: '7px 14px', borderRadius: 999,
              background: form.scope === v ? 'var(--terra-soft)' : 'transparent',
              color: form.scope === v ? 'var(--brand-navy)' : 'var(--ink-2)',
              border: form.scope === v ? '1px solid var(--terra)' : '1px solid var(--line)',
              fontSize: 12.5, fontWeight: 500, cursor: 'pointer'
            }}>{l}</button>
            )}
          </div>
        </FormRow>
        <div style={{ padding: 12, background: 'var(--sky-soft)', borderRadius: 10, fontSize: 12, color: '#001e40', lineHeight: 1.55 }}>
          Franchisees will be notified and can opt out within 48h. Creative assets (image + copy) can be uploaded after scheduling.
        </div>
      </div>
    </Modal>);

}

// ====================================================================
// LABEL MANAGER MODAL
// ====================================================================
function LabelManagerModal({ open, onClose }) {
  const [labels, setLabels] = useStateH([
  { name: 'Flagship', count: 4, color: 'var(--terra)' },
  { name: 'Urban', count: 12, color: 'var(--sky)' },
  { name: 'Suburban', count: 5, color: 'var(--sage)' },
  { name: 'Tourist', count: 5, color: 'var(--marigold)' }]
  );
  const [newName, setNewName] = useStateH('');

  const add = () => {
    if (!newName.trim()) return;
    setLabels((l) => [...l, { name: newName, count: 0, color: 'var(--ink-4)' }]);
    setNewName('');
    T('Label created', `"${newName}" added. Assign it to locations from each location's page.`, 'ok');
  };

  return (
    <Modal open={open} onClose={onClose} title="Manage labels" sub="Segment your portfolio however you think about it" width={540}
    footer={<>
        <button className="btn btn-ghost btn-sm" onClick={onClose}>Close</button>
      </>}>
      <div style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
        <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
          {labels.map((l, i) =>
          <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '10px 14px', background: 'var(--cream)', borderRadius: 10 }}>
              <div style={{ width: 10, height: 10, borderRadius: '50%', background: l.color }} />
              <div style={{ flex: 1, fontSize: 13, fontWeight: 600 }}>{l.name}</div>
              <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>{l.count} locations</div>
              <button className="btn btn-quiet btn-xs" onClick={() => T('Renaming', 'Inline rename coming soon.', 'info')}>Rename</button>
              <button className="btn btn-quiet btn-xs" onClick={() => {setLabels((ls) => ls.filter((_, ix) => ix !== i));T('Label removed', `"${l.name}" unassigned.`, 'warn');}} style={{ color: 'var(--terra)' }}>Remove</button>
            </div>
          )}
        </div>
        <div style={{ display: 'flex', gap: 8, paddingTop: 12, borderTop: '1px dashed var(--cream-3)' }}>
          <input className="inp" type="text" placeholder="New label name…" value={newName} onChange={(e) => setNewName(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && add()} style={{ flex: 1 }} />
          <button className="btn btn-primary btn-sm" onClick={add}>{Icon.plus} Add</button>
        </div>
      </div>
    </Modal>);

}

// ====================================================================
// Helpers
// ====================================================================
function FormRow({ label, children }) {
  return (
    <div>
      <div style={{ fontSize: 11, textTransform: 'uppercase', color: 'var(--ink-3)', fontWeight: 600, letterSpacing: '0.06em', marginBottom: 6 }}>{label}</div>
      {children}
    </div>);

}

function SegButton({ active, onClick, children }) {
  return (
    <button onClick={onClick} style={{
      padding: '7px 16px', borderRadius: 8,
      background: active ? 'var(--ink)' : 'transparent',
      color: active ? 'var(--cream)' : 'var(--ink-2)',
      border: active ? '1px solid var(--ink)' : '1px solid var(--line)',
      fontSize: 12.5, fontWeight: 500, cursor: 'pointer'
    }}>{children}</button>);

}