// ====================================================================
// CORPORATE FIELD TEAM, coaching view (reuses the renamed "Corporate
// Field Team" seat — no separate persona). Stays in the corporate
// experience but SCOPES the portfolio to one field member's territory
// (e.g. Tom Reynolds · TX + OK · 38 locations): territory vs system
// average, at-risk filtering, top/bottom performers, and a Lenny
// "what should I discuss with this franchisee" moment.
//
// Corporate reporting is untouched; this is a filtered lens over the
// same hqRollup source of truth. All coaching copy is rule-derived
// (canned), not a live model call.
// ====================================================================
const { useState: useStateFT, useMemo: useMemoFT } = React;
const T = (...a) => (window.toast || (() => {}))(...a);

// The field-team seats (mirror the HQ_TEAM 'regional' rows in pages.jsx).
const FIELD_SEATS = [
  { id: 'tom',   name: 'Tom Reynolds',    initials: 'TR', email: 'tom@freshnest.com',    territory: 'TX + OK', count: 38, states: ['TX', 'OK'], region: 'Central' },
  { id: 'aisha', name: 'Aisha Williams',  initials: 'AW', email: 'aisha@freshnest.com',  territory: 'CA',      count: 22, states: ['CA'],       region: 'West' },
  { id: 'brett', name: 'Brett Tanaka',    initials: 'BT', email: 'brett@freshnest.com',  territory: 'FL + GA', count: 18, states: ['FL', 'GA'], region: 'Southeast' },
];

const FT_READY = {
  ready:     { label: 'Ready',            dot: 'var(--sage)',     bg: 'var(--sage-soft)',     fg: '#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 FtReadyBadge({ status }) {
  const m = FT_READY[status] || FT_READY.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>);
}

// Build a stable talking-points list for a franchisee coaching call. Pure
// rules over the location's own row — no model call.
function coachingPoints(loc, systemAvg) {
  const pts = [];
  const gap = loc.score - systemAvg;
  if (loc.score < 68) {
    pts.push({ tone: 'terra', t: `LocalScore ${loc.score} is ${Math.abs(gap)} below the ${systemAvg} system average`, d: 'Open with the "why it matters" — lead flow, not the score itself. Walk the 90-day path back to average.' });
  } else if (gap < 0) {
    pts.push({ tone: 'marigold', t: `Running ${Math.abs(gap)} points under the ${systemAvg} system average`, d: 'Close and steady, but there is clear headroom. Frame one concrete move this month.' });
  } else {
    pts.push({ tone: 'sage', t: `Beating the system average by ${gap}`, d: 'Recognize the win first, then talk about protecting it and sharing what works with peers.' });
  }
  if (!loc.services.includes('ppc')) {
    pts.push({ tone: 'terra', t: 'Not on the Local Google Search Program', d: 'The #1 playbook channel and the single biggest lever. This is the conversation to have first.' });
  }
  if (!loc.services.includes('seo')) {
    pts.push({ tone: 'marigold', t: 'Local SEO is off', d: 'Ranking organically would pull blended cost-per-lead down. Low-lift, compounding.' });
  }
  if (!loc.services.includes('meta')) {
    pts.push({ tone: 'sky', t: 'Meta Ads not enrolled', d: 'Good seasonal-promo fit; pair it with the next Fall bundle push.' });
  }
  if (loc.rating < 4.2) {
    pts.push({ tone: 'marigold', t: `Rating ${loc.rating.toFixed(1)}★ is dragging discovery`, d: 'Check review-reply cadence — LOCALACT drafts them, the operator just needs to approve.' });
  }
  if (loc.trend < 0) {
    pts.push({ tone: 'terra', t: `Leads trending down (${loc.trend})`, d: 'Look at budget pacing together before the next cycle locks.' });
  }
  if (loc.services.length <= 1) {
    pts.push({ tone: 'sky', t: 'Only running the corporate baseline', d: 'The full-plan upside conversation — modeled lift is the hook, not the fee.' });
  }
  if (pts.length < 3) {
    pts.push({ tone: 'sage', t: 'Ask what is working locally', d: 'Strong operators surface plays worth spreading across the territory.' });
  }
  return pts.slice(0, 4);
}

function FieldTeamCoachPage({ data }) {
  const [seatId, setSeatId] = useStateFT('tom');
  const [atRiskOnly, setAtRiskOnly] = useStateFT(false);
  const seat = FIELD_SEATS.find(s => s.id === seatId) || FIELD_SEATS[0];

  const systemAvg = (data.network && data.network.performance && data.network.performance.localScoreAvg) || 72;
  const totalLocations = (data.network && data.network.totalLocations) || 700;

  // Scope the shared portfolio to this seat's territory. Corporate reporting
  // is unchanged — this just filters the same rollup to the seat's states.
  const territory = useMemoFT(() => {
    const full = window.buildPortfolio ? window.buildPortfolio(data.hqRollup || [], 700) : (data.hqRollup || []);
    const suffixes = seat.states.map(s => ', ' + s);
    let list = full.filter(r => r.region === seat.region && suffixes.some(suf => (r.city || '').endsWith(suf)));
    // pad from the seat's region if the state filter comes up short
    if (list.length < seat.count) {
      const extra = full.filter(r => r.region === seat.region && !list.includes(r));
      list = list.concat(extra);
    }
    return [...list].sort((a, b) => a.unit.localeCompare(b.unit)).slice(0, seat.count);
  }, [data.hqRollup, seatId]);

  const stats = useMemoFT(() => {
    const n = territory.length || 1;
    const avg = Math.round(territory.reduce((s, r) => s + r.score, 0) / n);
    const atRisk = territory.filter(r => r.score < 68);
    const belowAvg = territory.filter(r => r.score < systemAvg).length;
    const totalLeads = territory.reduce((s, r) => s + r.leads, 0);
    const sorted = [...territory].sort((a, b) => b.score - a.score);
    const top = sorted.slice(0, 5);
    const bottom = sorted.slice(-5).reverse();
    return { avg, atRisk, belowAvg, totalLeads, top, bottom };
  }, [territory, systemAvg]);

  // Selected franchisee for the coaching moment: default to the lowest scorer.
  const [selUnit, setSelUnit] = useStateFT(null);
  const selected = useMemoFT(() => {
    if (selUnit) { const m = territory.find(r => r.unit === selUnit); if (m) return m; }
    return stats.bottom[0] || territory[0];
  }, [territory, selUnit, stats]);

  const shown = atRiskOnly ? territory.filter(r => r.score < 68) : territory;
  const avgGap = stats.avg - systemAvg;

  const readinessFor = (r) => (r.readiness || (window.marketingReadinessFor ? window.marketingReadinessFor(r.unit, r.score) : 'ready'));
  const scoreColor = (s) => s >= 80 ? 'var(--sage)' : s >= 68 ? 'var(--marigold)' : 'var(--terra)';

  return (
    <div className="page active">
      {/* Field-mode scope banner */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 14, padding: '14px 18px', marginBottom: 18, borderRadius: 14,
                    background: 'linear-gradient(135deg, var(--brand-navy), #33506e)', color: 'var(--cream)' }}>
        <div style={{ width: 40, height: 40, borderRadius: '50%', background: 'rgba(255,255,255,0.14)', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: 'var(--ff-display)', fontWeight: 600, flexShrink: 0 }}>{seat.initials}</div>
        <div style={{ flex: 1, minWidth: 0 }}>
          <div style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'rgba(250,246,239,0.6)', fontWeight: 700 }}>Corporate Field Team · scoped view</div>
          <div style={{ fontFamily: 'var(--ff-display)', fontSize: 18, fontWeight: 600 }}>{seat.name} · {seat.territory} · {territory.length} locations</div>
        </div>
        <div style={{ display: 'flex', gap: 6 }}>
          {FIELD_SEATS.map(s => (
            <button key={s.id} onClick={() => { setSeatId(s.id); setSelUnit(null); setAtRiskOnly(false); }}
              style={{ padding: '6px 11px', borderRadius: 999, fontSize: 11.5, fontWeight: 600, cursor: 'pointer', border: '1px solid ' + (s.id === seatId ? 'var(--cream)' : 'rgba(255,255,255,0.22)'),
                       background: s.id === seatId ? 'var(--cream)' : 'transparent', color: s.id === seatId ? 'var(--brand-navy)' : 'var(--cream)' }}>
              {s.territory}
            </button>
          ))}
        </div>
      </div>

      <div className="page-header" style={{ marginBottom: 16 }}>
        <div>
          <div className="page-title">Field coaching.</div>
          <div className="page-sub">Everything below is filtered to {seat.name}'s {territory.length} locations, measured against the {totalLocations}-location system average.</div>
        </div>
      </div>

      {/* Territory vs system average */}
      <div className="grid grid-4" style={{ marginBottom: 12 }}>
        <div className="card card-pad">
          <div style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-4)', fontWeight: 700, marginBottom: 6 }}>Territory avg score</div>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 8 }}>
            <div style={{ fontFamily: 'var(--ff-display)', fontSize: 30, fontWeight: 600, color: scoreColor(stats.avg), lineHeight: 1 }}>{stats.avg}</div>
            <span style={{ fontSize: 12, fontWeight: 700, color: avgGap >= 0 ? 'var(--sage)' : 'var(--terra)' }}>{avgGap >= 0 ? '↑' : '↓'} {Math.abs(avgGap)} vs system</span>
          </div>
          <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 6 }}>System average is {systemAvg}</div>
        </div>
        <div className="card card-pad">
          <div style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-4)', fontWeight: 700, marginBottom: 6 }}>At-risk locations</div>
          <div style={{ fontFamily: 'var(--ff-display)', fontSize: 30, fontWeight: 600, color: 'var(--terra)', lineHeight: 1 }}>{stats.atRisk.length}</div>
          <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 6 }}>Score below 68 · {stats.belowAvg} under system avg</div>
        </div>
        <div className="card card-pad">
          <div style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-4)', fontWeight: 700, marginBottom: 6 }}>Monthly leads</div>
          <div style={{ fontFamily: 'var(--ff-display)', fontSize: 30, fontWeight: 600, color: 'var(--ink)', lineHeight: 1 }}>{stats.totalLeads.toLocaleString()}</div>
          <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 6 }}>Across the territory</div>
        </div>
        <div className="card card-pad">
          <div style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-4)', fontWeight: 700, marginBottom: 6 }}>Locations</div>
          <div style={{ fontFamily: 'var(--ff-display)', fontSize: 30, fontWeight: 600, color: 'var(--ink)', lineHeight: 1 }}>{territory.length}</div>
          <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 6 }}>{seat.territory} territory</div>
        </div>
      </div>

      <SourceNote>Source: FreshNest CRM · LocalScore calculated by LOCALACT · filtered to {seat.territory}</SourceNote>

      {/* Top & bottom vs system average */}
      <div className="grid" style={{ gridTemplateColumns: '1fr 1fr', gap: 16, marginBottom: 20 }}>
        {[['Top performers', stats.top, 'var(--sage)'], ['Needs the most help', stats.bottom, 'var(--terra)']].map(([title, rows, accent]) => (
          <div key={title} className="card card-pad">
            <div className="card-header" style={{ marginBottom: 8 }}>
              <div><div className="card-title">{title}</div><div className="card-sub">vs {systemAvg} system average</div></div>
            </div>
            <div style={{ display: 'flex', flexDirection: 'column' }}>
              {rows.map((r, i) => {
                const g = r.score - systemAvg;
                return (
                  <div key={r.unit} onClick={() => setSelUnit(r.unit)} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '10px 0', borderBottom: i === rows.length - 1 ? 'none' : '1px dashed var(--cream-3)', cursor: 'pointer' }}>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)' }}>{r.unit}</div>
                      <div style={{ fontSize: 11, color: 'var(--ink-3)' }}>{r.city}</div>
                    </div>
                    <FtReadyBadge status={readinessFor(r)} />
                    <div style={{ textAlign: 'right', minWidth: 58 }}>
                      <div style={{ fontFamily: 'var(--ff-display)', fontSize: 17, fontWeight: 600, color: scoreColor(r.score), lineHeight: 1 }}>{r.score}</div>
                      <div style={{ fontSize: 10.5, fontWeight: 700, color: g >= 0 ? 'var(--sage)' : 'var(--terra)' }}>{g >= 0 ? '+' : ''}{g}</div>
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        ))}
      </div>

      {/* Lenny coaching moment */}
      <div className="card" style={{ marginBottom: 20, overflow: 'hidden', border: '1px solid var(--violet)' }}>
        <div style={{ display: 'flex', gap: 14, alignItems: 'flex-start', padding: '18px 22px', background: 'linear-gradient(135deg, var(--violet-soft) 0%, var(--paper) 55%)', borderBottom: '1px solid var(--cream-2)' }}>
          <div style={{ width: 46, height: 46, borderRadius: '50%', overflow: 'hidden', flexShrink: 0, background: 'var(--paper)', border: '2px solid var(--cream-3)' }}>
            <window.LennyLlama size={46} mood="thinking" bg="circle"/>
          </div>
          <div style={{ flex: 1, minWidth: 0 }}>
            <div style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--violet)', fontWeight: 700, marginBottom: 3 }}>What should I discuss with this franchisee?</div>
            <div style={{ fontFamily: 'var(--ff-display)', fontSize: 18, fontWeight: 600, color: 'var(--ink)' }}>{selected ? selected.unit : '—'} <span style={{ fontWeight: 400, fontSize: 13, color: 'var(--ink-3)' }}>· {selected ? selected.city : ''}</span></div>
          </div>
          <window.DropMenu value={selected ? selected.unit : ''} onPick={setSelUnit}
            options={territory.map(r => ({ v: r.unit, l: `${r.unit} · ${r.score}` }))}/>
        </div>
        {selected && (
          <div style={{ padding: '18px 22px' }}>
            <div style={{ fontSize: 13, color: 'var(--ink-2)', lineHeight: 1.55, marginBottom: 16 }}>
              Lenny's read for your call with <strong>{selected.unit}</strong>: {selected.score >= systemAvg
                ? 'a strong operator — open with the win, then talk about protecting and scaling it.'
                : `${systemAvg - selected.score} points under the system average — lead with lead flow, not the score.`}
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10 }}>
              {coachingPoints(selected, systemAvg).map((p, i) => {
                const tone = { terra: 'var(--terra)', marigold: 'var(--marigold)', sky: 'var(--sky)', sage: 'var(--sage)' }[p.tone] || 'var(--ink-3)';
                return (
                  <div key={i} style={{ display: 'flex', gap: 10, padding: '12px 14px', borderRadius: 10, background: 'var(--cream)', border: '1px solid var(--cream-3)' }}>
                    <span style={{ width: 22, height: 22, borderRadius: '50%', background: tone, color: '#fff', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 12, fontWeight: 700, flexShrink: 0 }}>{i + 1}</span>
                    <div style={{ minWidth: 0 }}>
                      <div style={{ fontSize: 13, fontWeight: 600, color: 'var(--ink)', lineHeight: 1.35 }}>{p.t}</div>
                      <div style={{ fontSize: 11.5, color: 'var(--ink-3)', marginTop: 3, lineHeight: 1.45 }}>{p.d}</div>
                    </div>
                  </div>
                );
              })}
            </div>
            <div style={{ display: 'flex', gap: 8, marginTop: 16 }}>
              <button className="btn btn-primary btn-sm" onClick={() => window.dispatchEvent(new CustomEvent('open-location', { detail: selected }))}>Open {selected.unit} →</button>
              <button className="btn btn-ghost btn-sm" onClick={() => T('Prep sheet queued', `Lenny is packaging a one-pager for your ${selected.unit} call.`, 'ok')}>Send me a prep sheet</button>
            </div>
          </div>
        )}
      </div>

      {/* Territory roster with at-risk filter */}
      <div className="section-label">
        {seat.territory} locations
        <span className="count">{shown.length} shown{atRiskOnly ? ' · at-risk only' : ''}</span>
      </div>
      <div className="card card-pad" style={{ marginBottom: 12, padding: '12px 16px', display: 'flex', gap: 10, alignItems: 'center' }}>
        <span style={{ fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.08em', color: 'var(--ink-3)', fontWeight: 600 }}>Filter</span>
        <button onClick={() => setAtRiskOnly(false)} style={{ padding: '6px 12px', borderRadius: 999, fontSize: 12, fontWeight: 600, cursor: 'pointer', border: '1px solid ' + (!atRiskOnly ? 'var(--ink-3)' : 'var(--cream-3)'), background: !atRiskOnly ? 'var(--ink)' : 'var(--paper)', color: !atRiskOnly ? 'var(--paper)' : 'var(--ink-3)' }}>All {territory.length}</button>
        <button onClick={() => setAtRiskOnly(true)} style={{ padding: '6px 12px', borderRadius: 999, fontSize: 12, fontWeight: 600, cursor: 'pointer', border: '1px solid ' + (atRiskOnly ? 'var(--terra)' : 'var(--cream-3)'), background: atRiskOnly ? 'var(--terra-soft)' : 'var(--paper)', color: atRiskOnly ? '#8c2f22' : 'var(--ink-3)' }}>⚠ At-risk {stats.atRisk.length}</button>
      </div>
      <div className="card" style={{ overflow: 'hidden' }}>
        <table className="tbl">
          <thead>
            <tr><th>Location</th><th>Readiness</th><th>LocalScore</th><th>vs system</th><th>Leads</th><th>Rating</th><th /></tr>
          </thead>
          <tbody>
            {shown.map((r, i) => {
              const g = r.score - systemAvg;
              return (
                <tr key={i} onClick={() => setSelUnit(r.unit)} 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><FtReadyBadge status={readinessFor(r)} /></td>
                  <td><span style={{ fontFamily: 'var(--ff-display)', fontSize: 16, fontWeight: 600, color: scoreColor(r.score) }}>{r.score}</span></td>
                  <td><span style={{ fontFamily: 'var(--ff-display)', fontWeight: 600, color: g >= 0 ? 'var(--sage)' : 'var(--terra)' }}>{g >= 0 ? '+' : ''}{g}</span></td>
                  <td className="mono">{r.leads}</td>
                  <td><span style={{ fontFamily: 'var(--ff-display)', fontWeight: 500 }}>{r.rating.toFixed(1)}</span><span style={{ color: 'var(--marigold)', marginLeft: 2 }}>★</span></td>
                  <td><button className="btn btn-quiet btn-xs" onClick={(e) => { e.stopPropagation(); setSelUnit(r.unit); }}>Discuss →</button></td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {/* Evolving-model note — this scoped lens is a first cut, not the finished coach model */}
      <div style={{ display: 'flex', gap: 12, alignItems: 'flex-start', marginTop: 16, padding: '14px 18px', borderRadius: 14, background: 'var(--sky-soft)', border: '1px dashed var(--sky)' }}>
        <span style={{ width: 26, height: 26, borderRadius: '50%', background: 'var(--sky)', color: '#001e40', display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 13, fontWeight: 700, flexShrink: 0 }}>→</span>
        <div style={{ minWidth: 0 }}>
          <div style={{ fontSize: 10.5, textTransform: 'uppercase', letterSpacing: '0.08em', color: '#00437f', fontWeight: 700, marginBottom: 3 }}>Evolving · next release</div>
          <div style={{ fontSize: 12.5, color: 'var(--ink-2)', lineHeight: 1.55 }}>
            This is today's coaching lens — a territory scoped over the shared network data. The fuller coach model is on the way: each coach signs in to their <strong>own portfolio across their book of locations</strong>, with <strong>action tracking</strong> so talking points become commitments you follow to close. We're shaping it now, and this view will grow into it.
          </div>
        </div>
      </div>
    </div>);
}
window.FieldTeamCoachPage = FieldTeamCoachPage;
