/* ELEV8 ATS - shared visual-hierarchy primitives.
   Extracted from two hierarchy audits (Today, Candidate record) that independently hit the
   same issues. These enforce the fixes as reusable components so they are never re-implemented
   ad hoc. See docs/adr/action-hierarchy.md and docs/adr/type-scale.md.

   All are assigned to window (matching flex.jsx) and referenced as window.X at render time, so
   load order among the screen files does not matter. */

const P_DS = window.Stand8DesignSystem_b5c975;

/* FitScoreChip - the elevated, tier-colored match/fit indicator for any scored primary entity
   (candidate match, job fit, ranked result). Owns the large-numeral + tier-color treatment so a
   score is never re-rendered as a small equal-weight badge. */
function FitScoreChip({ score, tier, label, size }) {
  if (score == null || score === '') return null;
  const t = ((P_DS && P_DS.MATCH_TIERS) || []).find((x) => x.id === tier) || {};
  return (
    <span
      className={'e8-fitchip' + (size === 'sm' ? ' e8-fitchip-sm' : '')}
      title="Match score - the primary fit signal"
      style={{ '--fit': 'var(--ui-tier-' + tier + ')', '--fitbg': 'var(--ui-tier-' + tier + '-tint)', '--fitbr': 'var(--ui-tier-' + tier + '-br)' }}
    >
      <span className="e8-fitchip-score tnum">{score}</span>
      <span className="e8-fitchip-label">{label || t.label || 'match'}</span>
    </span>
  );
}

/* InlineBanner - tone x emphasis matrix for in-page banners (dedup flags, warnings, notices).
   emphasis defaults to 'stripe' (left-accent, low weight) so a secondary concern never hijacks
   the top of a screen; 'fill' is reserved for true blockers. */
function InlineBanner({ tone = 'warning', emphasis = 'stripe', icon, title, sub, children, actions, role, label }) {
  return (
    <div className={'e8-inlinebanner tone-' + tone + ' emph-' + emphasis} role={role || 'region'} aria-label={label}>
      {icon ? <span className="material-symbols-outlined e8-inlinebanner-ico" aria-hidden="true">{icon}</span> : null}
      <div className="e8-inlinebanner-body">
        {title ? <div className="e8-inlinebanner-t">{title}</div> : null}
        {sub ? <div className="e8-inlinebanner-sub">{sub}</div> : null}
        {children}
      </div>
      {actions ? <div className="e8-inlinebanner-acts">{actions}</div> : null}
    </div>
  );
}

/* StatTile - the frameless, optionally clickable dashboard stat. No box by default (grouped by
   whitespace); when a route/onClick is given it gets cursor + hover + focus ring + keyboard. */
function StatTile({ icon, value, label, tone = 'neutral', route, onClick }) {
  const act = route ? () => window.navigate(route) : onClick;
  return (
    <div
      className={'e8-stattile tone-' + tone + (act ? ' is-link' : '')}
      onClick={act || undefined}
      role={act ? 'button' : undefined}
      tabIndex={act ? 0 : undefined}
      title={act && label ? 'Open ' + String(label).toLowerCase() : undefined}
      onKeyDown={act ? (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); act(); } } : undefined}
    >
      {icon ? <span className="e8-stattile-ic"><span className="material-symbols-outlined" aria-hidden="true">{icon}</span></span> : null}
      <div style={{ minWidth: 0 }}>
        <div className="e8-stattile-v">{value}</div>
        <div className="e8-stattile-l">{label}</div>
      </div>
    </div>
  );
}

/* ActionBar - enforces the "exactly one dominant action" rule. Actions:
     { key, label, icon, emphasis: 'primary'|'secondary'|'quiet', destructive?, variant?, onClick, kbd? }
   - Dev-time warning if more than one action is marked primary.
   - Destructive actions are always quiet-styled and separated from the positive actions by a
     divider (the Accept/Reject pattern proven on the candidate record), never adjacent at equal
     weight. Pass `variant` to override (e.g. 'accept' for a green affirmative primary). */
function ActionBar({ actions = [], className, ariaLabel }) {
  const primaries = actions.filter((a) => a.emphasis === 'primary' && !a.destructive);
  if (primaries.length > 1) {
    console.warn('[ActionBar] ' + primaries.length + ' primary actions (' + primaries.map((a) => a.label).join(', ') +
      '). Exactly one action per bar may be primary — demote the rest to secondary/quiet. See docs/adr/action-hierarchy.md');
  }
  const variantFor = (a) => a.variant || (a.destructive ? 'reject' : a.emphasis === 'primary' ? 'primary' : a.emphasis === 'quiet' ? 'ghost' : 'secondary');
  const positive = actions.filter((a) => !a.destructive);
  const destructive = actions.filter((a) => a.destructive);
  const render = (a) => (
    <React.Fragment key={a.key || a.label}>
      <P_DS.Button variant={variantFor(a)} size={a.size || 'sm'} icon={a.icon} onClick={a.onClick}>{a.label}</P_DS.Button>
      {a.kbd ? <span className="e8-kbd e8-rb-kbd">{a.kbd}</span> : null}
    </React.Fragment>
  );
  return (
    <div className={'e8-actionbar' + (className ? ' ' + className : '')} role="group" aria-label={ariaLabel}>
      {positive.map(render)}
      {destructive.length ? <span className="e8-actionbar-div" aria-hidden="true"></span> : null}
      {destructive.map(render)}
    </div>
  );
}

Object.assign(window, { FitScoreChip, InlineBanner, StatTile, ActionBar });
