// Developer Profile · first-class destination.
// Sections: Hero strip → Stat strip → Personal Gantt →
// Signals firing → ETA Calibration → Meeting Map → Five-Gate State → Trend Lines.

function DevProfile({ navigate, openSidePanel, openTicketList, id, selfMode }) {
  const dev = DATA.devById(id);
  if (!dev) {
    return (
      <div className="page page-fade">
        <h1>Developer not found</h1>
        <p>No engineer with id {id}.</p>
        <a className="btn" href="#/dashboard">Back to dashboard</a>
      </div>
    );
  }

  const personalGanttRows = DATA.tickets
    .filter(t => t.assignee === dev.id && t.history && t.history.length > 0)
    .filter(t => t.history[0].startDay >= -28)
    .sort((a, b) => a.history[0].startDay - b.history[0].startDay)
    .slice(0, 8);

  const signalsFiring = DATA.signals.filter(s => s.devId === dev.id);
  const gatesOpen = DATA.disengagement.gateKeys.filter(k => dev.gates[k]).length;

  return (
    <div className="page page-fade">
      {/* Hero */}
      <div className="card toned-card tone-accent profile-hero">
        <Avatar initials={dev.initials} size={68} glow={selfMode} />
        <div className="ph-identity">
          <div className="ph-eyebrow">Developer profile {selfMode ? '· My theSitrep' : ''}</div>
          <div className="ph-name">{dev.name}</div>
          <div className="ph-meta">
            <span>{dev.role}</span>
            <span className="ph-dot">·</span>
            <span>{dev.team}</span>
            <span className="ph-dot">·</span>
            <span>Reports to {DATA.devById(dev.managerId)?.name || 'Alex Chen'}</span>
          </div>
          <div className="ph-status">
            {dev.ramp && <span className="status-chip ramp"><span className="sc-dot" />Ramp</span>}
            <span className="status-chip"><span className="sc-dot" />Joined {new Date(dev.joined).toLocaleDateString(undefined, { month: 'short', year: 'numeric' })}</span>
          </div>
        </div>
      </div>

      {/* What's happening now · scoped to this engineer */}
      <div style={{ marginBottom: 16 }}>
        <NowSnapshot devId={dev.id} openTicketList={openTicketList} navigate={navigate} />
      </div>

      {/* Personal Gantt */}
      {personalGanttRows.length > 0 && (
        <>
          <div className="section-head">
            <div>
              <div className="section-eyebrow">Last 4 weeks · this engineer</div>
              <div className="section-title">Personal lifecycle Gantt</div>
            </div>
          </div>
          <GanttForensics navigate={navigate} rows={personalGanttRows} days={28} startDay={-28} />
        </>
      )}

      {/* Signals firing */}
      {signalsFiring.length > 0 && (
        <>
          <div className="section-head">
            <div>
              <div className="section-eyebrow">Signals firing on this developer</div>
              <div className="section-title">{signalsFiring.length} signal{signalsFiring.length === 1 ? '' : 's'} this week</div>
            </div>
          </div>
          <div className="card">
            <div className="coach-list">
              {signalsFiring.map(s => (
                <div key={s.id} className="coach-row" onClick={() => openSidePanel({ kind: 'signal-evidence', signal: s, title: s.name })}>
                  <Avatar initials={dev.initials} size={26} />
                  <div className="cr-body">
                    <div className="cr-signal">
                      <span>{s.name}</span>
                    </div>
                    <div style={{ fontSize: 11.5, color: 'var(--text-3)' }}>{s.description}</div>
                  </div>
                  <div className="cr-meta">
                    <span className="cr-count">{s.evidence.length} evidence</span>
                    <Icon name="chevron-right" size={12} />
                  </div>
                </div>
              ))}
            </div>
          </div>
        </>
      )}

      {/* Meeting load vs focus time */}
      <div className="section-head">
        <div>
          <div className="section-eyebrow">This week · are meetings crowding out deep work?</div>
          <div className="section-title">Meeting load + focus time</div>
        </div>
      </div>
      <MeetingLoadFocus dev={dev} />

      {/* Five-gate state */}
      <div className="section-head">
        <div>
          <div className="section-eyebrow">Engagement composite · this week</div>
          <div className="section-title">Five gates · {gatesOpen} of 5 open</div>
        </div>
      </div>
      <GatePanel devId={dev.id} />
    </div>
  );
}

// Helpers used only here ------------------------------------------------

// Answers two questions a developer cares about at a glance:
//   1. Do I have too many meetings this week?
//   2. Is my focus time too short/fragmented to do deep work?
// Headline gauges use the hand-tuned weekly per-engineer fields; the grid
// below is the qualitative "where meetings landed" fragmentation picture.
function MeetingLoadFocus({ dev }) {
  const days14 = DATA.meetingDays14[dev.id];

  // Meeting load · weekly hours. Comfortable ≤6h; past 8h it crowds out deep work.
  const MEET_CAP = 12, MEET_OK = 6, MEET_HEAVY = 8;
  const meetHrs = dev.meetingHrs;
  const meetTone = meetHrs > MEET_HEAVY ? 'bad' : meetHrs > MEET_OK ? 'warn' : 'good';
  const meetVerdict = meetTone === 'bad' ? 'Too many meetings' : meetTone === 'warn' ? 'Getting heavy' : 'Manageable';
  const meetNote = meetTone === 'bad'
    ? `${meetHrs}h booked this week, past the ${MEET_HEAVY}h line where focus suffers. Decline or delegate recurring status meetings.`
    : meetTone === 'warn'
    ? `${meetHrs}h this week is climbing toward the ${MEET_HEAVY}h overload line. Watch for status meetings you could skip.`
    : `${meetHrs}h this week, comfortably under the ${MEET_OK}h line, with room left to focus.`;

  // Focus time · longest uninterrupted block. Deep work needs 2h+ stretches.
  const FOCUS_MAX = 4, FOCUS_MIN = 2, FOCUS_GOOD = 3;
  const focusHrs = dev.focusBlockHrs;
  const focusTone = focusHrs < FOCUS_MIN ? 'bad' : focusHrs < FOCUS_GOOD ? 'warn' : 'good';
  const focusVerdict = focusTone === 'bad' ? 'Too fragmented' : focusTone === 'warn' ? 'Tight' : 'Protected';
  const focusNote = focusTone === 'bad'
    ? `Longest uninterrupted block is just ${focusHrs}h. Deep work needs ${FOCUS_MIN}h+, block a no-meeting morning to recover a real focus run.`
    : focusTone === 'warn'
    ? `${focusHrs}h longest block, room for one deep-work session, but little slack against interruptions.`
    : `${focusHrs}h of uninterrupted focus, a solid runway for deep work.`;

  const switches = dev.contextSwitches;
  const switchTone = switches > 9 ? 'bad' : switches > 5 ? 'warn' : 'good';

  return (
    <div className="card" style={{ padding: 14 }}>
      <div className="mlf-assess">
        {/* Meeting load · higher is worse */}
        <div className="mlf-tile">
          <div className="mlf-head">
            <span className="mlf-label"><Icon name="calendar" size={12} /> Meeting load</span>
            <span className={`tag mono tone-${meetTone}`}>{meetVerdict}</span>
          </div>
          <div className={`mlf-value tone-${meetTone}`}>{meetHrs}<span className="mlf-unit">h / wk</span></div>
          <div className="mlf-gauge" title={`Comfortable ≤ ${MEET_OK}h · overload > ${MEET_HEAVY}h`}>
            <div className={`mlf-gauge-fill tone-${meetTone}`} style={{ width: Math.min(100, (meetHrs / MEET_CAP) * 100) + '%' }} />
            <span className="mlf-gauge-tick" style={{ left: (MEET_HEAVY / MEET_CAP) * 100 + '%' }} />
          </div>
          <div className="mlf-scale"><span>0h</span><span>{MEET_HEAVY}h overload</span><span>{MEET_CAP}h</span></div>
          <div className="mlf-note">{meetNote}</div>
        </div>

        {/* Focus time · higher is better */}
        <div className="mlf-tile">
          <div className="mlf-head">
            <span className="mlf-label"><Icon name="zap" size={12} /> Focus time</span>
            <span className={`tag mono tone-${focusTone}`}>{focusVerdict}</span>
          </div>
          <div className={`mlf-value tone-${focusTone}`}>{focusHrs}<span className="mlf-unit">h longest block</span></div>
          <div className="mlf-gauge" title={`Deep-work minimum ${FOCUS_MIN}h`}>
            <div className={`mlf-gauge-fill tone-${focusTone}`} style={{ width: Math.min(100, (focusHrs / FOCUS_MAX) * 100) + '%' }} />
            <span className="mlf-gauge-tick" style={{ left: (FOCUS_MIN / FOCUS_MAX) * 100 + '%' }} />
          </div>
          <div className="mlf-scale"><span>0h</span><span>{FOCUS_MIN}h min</span><span>{FOCUS_MAX}h</span></div>
          <div className="mlf-note">{focusNote}</div>
        </div>
      </div>

      {/* Fragmentation driver */}
      <div className="mlf-meta">
        <Icon name="shuffle" size={12} />
        <span className={`tone-${switchTone}`} style={{ fontWeight: 600 }}>{switches} context switches / day,</span>
        <span style={{ color: 'var(--text-3)' }}>the more you're pulled away, the harder those focus blocks are to hold.</span>
      </div>

      {/* Past 7 days vs next 7 days · per-day meeting load */}
      {days14 && (
        <MeetingWeekStrip days14={days14} />
      )}
    </div>
  );
}

// 14-day strip showing how busy the past 7 days were vs how busy the next 7
// look. Each day is a vertical bar whose height = meeting hours; tone steps
// from accent (light) → warn → bad as the day fills up. Future days render
// with a dashed border + lower fill opacity to mark "planned, not actual".
function MeetingWeekStrip({ days14 }) {
  const past7 = days14.slice(0, 7);
  const next7 = days14.slice(7);
  const sum = (arr) => arr.reduce((s, d) => s + d.meetHrs, 0);
  const busyCount = (arr) => arr.filter(d => d.meetHrs >= 4).length;
  const pastTotal = sum(past7);
  const nextTotal = sum(next7);
  const pastBusy = busyCount(past7);
  const nextBusy = busyCount(next7);
  const weekTone = (h) => h > 30 ? 'bad' : h > 20 ? 'warn' : 'good';
  const pastTone = weekTone(pastTotal);
  const nextTone = weekTone(nextTotal);
  const pastVerdict = pastTone === 'bad' ? 'Overloaded' : pastTone === 'warn' ? 'Heavy' : 'Manageable';
  const nextVerdict = nextTone === 'bad' ? 'Overloaded' : nextTone === 'warn' ? 'Heavy' : 'Manageable';

  const MAX_HRS = 8;
  const dayTone = (h) => h >= 6 ? 'bad' : h >= 4 ? 'warn' : h >= 1 ? 'accent' : 'empty';

  return (
    <>
      <div className="mlf-grid-head">Meeting density · last 7 days vs next 7 days</div>
      <div className="mlf-week-summary">
        <div className="mlf-wk-chip">
          <div className="mlf-wk-row">
            <span className="mlf-wk-eyebrow">Past 7 days · actual</span>
            <span className={`tag mono tone-${pastTone}`}>{pastVerdict}</span>
          </div>
          <div className={`mlf-wk-val tone-${pastTone}`}>{pastTotal}<span className="mlf-wk-unit">h in meetings</span></div>
          <div className="mlf-wk-sub">{pastBusy} day{pastBusy === 1 ? '' : 's'} over 4h · avg {(pastTotal / 7).toFixed(1)}h / day</div>
        </div>
        <div className="mlf-wk-chip">
          <div className="mlf-wk-row">
            <span className="mlf-wk-eyebrow">Next 7 days · planned</span>
            <span className={`tag mono tone-${nextTone}`}>{nextVerdict}</span>
          </div>
          <div className={`mlf-wk-val tone-${nextTone}`}>{nextTotal}<span className="mlf-wk-unit">h booked</span></div>
          <div className="mlf-wk-sub">{nextBusy} day{nextBusy === 1 ? '' : 's'} over 4h · avg {(nextTotal / 7).toFixed(1)}h / day</div>
        </div>
      </div>
      <div className="mlf-week">
        {days14.map((d, i) => {
          const tone = dayTone(d.meetHrs);
          const heightPct = (d.meetHrs / MAX_HRS) * 100;
          const tip = `${d.dow} ${d.dayNum}${d.isToday ? ' · today' : ''} · ${d.meetHrs}h in meetings${d.isFuture ? ' (planned)' : ''}`;
          const cls = [
            'mlf-day',
            `tone-${tone}`,
            d.isToday ? 'mlf-day-today' : '',
            d.isFuture ? 'mlf-day-future' : 'mlf-day-past',
            d.isWeekend ? 'mlf-day-weekend' : '',
            i === 7 ? 'mlf-day-pivot' : '',
          ].filter(Boolean).join(' ');
          return (
            <div key={i} className={cls} title={tip}>
              <div className="mlf-day-label">
                <span>{d.dow}</span>
                <span className="mlf-day-num">{d.dayNum}</span>
              </div>
              <div className="mlf-day-track">
                <div className="mlf-day-fill" style={{ height: heightPct + '%' }} />
              </div>
              <div className="mlf-day-hrs">{d.meetHrs > 0 ? `${d.meetHrs}h` : '-'}</div>
            </div>
          );
        })}
      </div>
      <div className="mlf-week-legend">
        <span className="mlf-legend-item"><span className="mlf-swatch tone-accent" />Light (&lt; 4h)</span>
        <span className="mlf-legend-item"><span className="mlf-swatch tone-warn" />Heavy (4–6h)</span>
        <span className="mlf-legend-item"><span className="mlf-swatch tone-bad" />Overloaded (6h+)</span>
        <span className="mlf-legend-item"><span className="mlf-swatch outlined" />Planned (future)</span>
      </div>
    </>
  );
}

Object.assign(window, { DevProfile });
