// home/lib.jsx — "Today" tab primitives (locked redesign spec).
//
// Exports (window.*):
//   TabBar5    — the single global navigator: Today · Calendar · ✛ · Health · You
//   TodayHero  — full-viewport greeting hero: eyebrow · narrative · signature
//                metric · one thin stat row
//   TSection   — Today section header (editorial)
//   TArc       — today-only event timeline with a Now marker
//   ModuleTile — shelf tile: domain chip + label + exactly one live datum
//   CreateOpt  — a row inside the Create sheet
//
// Voice: quiet, plain, declarative. Sentence case. Em-dashes for pivots.

// ────────────────────────────────────────────────────────────
// Time-of-day greeting gradients. The hero's midnight identity shifts gently
// through the day — the same idea as the web Home greeting. Each palette is a
// soft, mid-tone family (no near-black) so white type rests on it without a
// harsh edge. gradientFor(palette, timeOfDay) → a CSS background string.
// Palettes are exposed as a Tweak; "Auto" reads the real clock.
// ────────────────────────────────────────────────────────────
const HERO_PALETTES = {
  'Soft purple': {
    rep: ['#6E5C99', '#4E4391', '#2F2866'],
    dawn:      ['#4A3B6E', '#5B4A82', '#6E5C99'],
    morning:   ['#3E3470', '#4E4391', '#6256A8'],
    afternoon: ['#3A3E80', '#4A52A0', '#5E6BBE'],
    evening:   ['#46306E', '#5E3F88', '#7A52A0'],
    night:     ['#241E4E', '#2F2866', '#3C3480'],
  },
  'Twilight': {
    rep: ['#9A5E72', '#6A4A7E', '#3E2A55'],
    dawn:      ['#5E3A63', '#7A4A6E', '#9A5E72'],
    morning:   ['#4E3A66', '#6A4A7E', '#8A5E92'],
    afternoon: ['#4A3E72', '#64508E', '#8466A8'],
    evening:   ['#5A2E5E', '#7E3E72', '#A05284'],
    night:     ['#2E1E44', '#3E2A55', '#4E3568'],
  },
  'Cool indigo': {
    rep: ['#5E73A6', '#3E4E8E', '#26305E'],
    dawn:      ['#39456E', '#4A5A88', '#5E73A6'],
    morning:   ['#2E3A66', '#3E4E8E', '#5266B0'],
    afternoon: ['#2C4078', '#3A55A0', '#4E72C4'],
    evening:   ['#33356E', '#454088', '#5A52A8'],
    night:     ['#1C2244', '#26305E', '#323F7A'],
  },
};
const HERO_PALETTE_LIST = Object.keys(HERO_PALETTES);
const HERO_PALETTE_REPS = HERO_PALETTE_LIST.map(function (n) { return HERO_PALETTES[n].rep; });
const HERO_REP_TO_NAME = {};
HERO_PALETTE_LIST.forEach(function (n) {
  HERO_REP_TO_NAME[JSON.stringify(HERO_PALETTES[n].rep).toLowerCase()] = n;
});

function _heroHexToRgb(h) {
  h = String(h).replace('#', '');
  if (h.length === 3) h = h.split('').map(function (c) { return c + c; }).join('');
  const n = parseInt(h, 16);
  return [(n >> 16) & 255, (n >> 8) & 255, n & 255];
}
function _heroLightenRgba(h, amt, a) {
  const c = _heroHexToRgb(h);
  const f = function (v) { return Math.round(v + (255 - v) * amt); };
  return 'rgba(' + f(c[0]) + ',' + f(c[1]) + ',' + f(c[2]) + ',' + a + ')';
}

function resolveTimeOfDay(tod) {
  if (tod && tod !== 'Auto') return String(tod).toLowerCase();
  const h = new Date().getHours();
  if (h < 5) return 'night';
  if (h < 8) return 'dawn';
  if (h < 12) return 'morning';
  if (h < 17) return 'afternoon';
  if (h < 21) return 'evening';
  return 'night';
}

function paletteNameFrom(palette) {
  if (Array.isArray(palette)) return HERO_REP_TO_NAME[JSON.stringify(palette).toLowerCase()] || 'Soft purple';
  return HERO_PALETTES[palette] ? palette : 'Soft purple';
}

function gradientFor(palette, tod) {
  const name = paletteNameFrom(palette);
  const key = resolveTimeOfDay(tod);
  const stops = HERO_PALETTES[name][key] || HERO_PALETTES[name].morning;
  const a = stops[0], b = stops[1], c = stops[2];
  const topGlow = _heroLightenRgba(c, 0.32, 0.42);
  const botGlow = _heroLightenRgba(b, 0.06, 0.30);
  return 'radial-gradient(120% 75% at 82% -8%, ' + topGlow + ', transparent 58%), '
       + 'radial-gradient(90% 70% at 6% 108%, ' + botGlow + ', transparent 60%), '
       + 'linear-gradient(157deg, ' + a + ' 0%, ' + b + ' 52%, ' + c + ' 100%)';
}

function greetingForTod(tod, name) {
  const key = resolveTimeOfDay(tod);
  const g = key === 'afternoon' ? 'Good afternoon'
          : key === 'evening' ? 'Good evening'
          : key === 'night' ? 'Winding down'
          : 'Good morning';
  return g + ', ' + name;
}

// ─────────────────────────────────────────────────────────────
// 5-item tab bar. The center ✛ is a primary action (blue), not a
// destination — no selected state. Destination tabs swap to a filled
// glyph when active. Active tint defaults to a single blue accent
// (single-accent discipline); `tint="domain"` previews per-domain.
// ─────────────────────────────────────────────────────────────
const TAB5 = [
  { id: 'today',    label: 'Today',    icon: 'home',     iconActive: 'home-filled',     domain: 'var(--io-indigo)' },
  { id: 'calendar', label: 'Calendar', icon: 'calendar', iconActive: 'calendar-filled', domain: 'var(--io-blue)' },
  { id: 'health',   label: 'Health',   icon: 'heart',    iconActive: 'heart-filled',    domain: 'var(--io-red)' },
  { id: 'you',      label: 'You',      icon: 'user',     iconActive: 'person-filled',   domain: 'var(--io-label)' },
];

const TabBar5 = ({ active = 'today', tint = 'blue', onCreate }) => {
  const renderTab = (t) => {
    const isActive = t.id === active;
    const perDomain = tint === 'domain';
    const style = perDomain && isActive ? { '--tab-tint': t.domain } : undefined;
    return (
      <div key={t.id}
        className={'tab' + (isActive ? ' active' : '') + (perDomain ? ' tinted' : '')}
        style={style}>
        <div className="ic">
          <Icon name={isActive ? t.iconActive : t.icon} size={27} stroke={isActive ? 2.3 : 2}/>
        </div>
        <div className="lb">{t.label}</div>
      </div>
    );
  };
  return (
    <div className="tabbar5">
      {renderTab(TAB5[0])}
      {renderTab(TAB5[1])}
      <div className="create" onClick={onCreate}>
        <div className="fab"><Icon name="plus" size={24} stroke={2.6}/></div>
        <div className="lb">Create</div>
      </div>
      {renderTab(TAB5[2])}
      {renderTab(TAB5[3])}
    </div>
  );
};

// ─────────────────────────────────────────────────────────────
// Full-viewport greeting hero. Earned midnight: greetingGradient lives
// only here. One eyebrow, one narrative line, one signature metric, one
// thin stat row — nothing else competes in the first viewport.
// ─────────────────────────────────────────────────────────────
const TodayHero = ({
  name = 'Lukas',
  date = 'Sun · Mar 16',
  greeting,
  narrative = 'Three things matter today.',
  metricLabel = "Tonight's bedtime",
  metric = '10:30',
  metricUnit = 'PM',
  metricSub = 'Worked back from tomorrow — wake 6:15, an 8-hour night.',
  stats = [],
  empty = false,
  showMoon = true,
  grad,
}) => (
  <div className={'today-hero' + (empty ? ' empty' : '')} style={grad ? { background: grad } : undefined}>
    <div className="hero-top">
      <div className="hero-date" data-num>{date}</div>
      <div className="hero-actions">
        <div className="glass-btn"><Icon name="search" size={17} stroke={2.4}/></div>
        <div className="glass-btn avatar">{name[0]}</div>
      </div>
    </div>

    <div className="hero-eyebrow">{greeting || `Good morning, ${name}`}</div>
    <div className="hero-narrative">{narrative}</div>

    <div className="hero-spacer"/>

    <div className="hero-metric-lbl">
      {showMoon && <span className="moon" aria-hidden="true"/>}
      {metricLabel}
    </div>
    <div className="hero-metric" data-num>
      {metric}{metricUnit && <span className="unit">{metricUnit}</span>}
    </div>
    {metricSub && <div className="hero-metric-sub">{metricSub}</div>}

    {stats.length > 0 && (
      <div className="hero-stats">
        {stats.map((s, i) => (
          <div key={i} className="st">
            <div className="l">{s.l}</div>
            <div className="v" data-num>{s.v}</div>
            <div className="s">{s.s}</div>
          </div>
        ))}
      </div>
    )}
  </div>
);

// ─────────────────────────────────────────────────────────────
// Section header
// ─────────────────────────────────────────────────────────────
const TSection = ({ title, count, see }) => (
  <div className="t-secthd">
    <div className="ttl">
      {title}{count !== undefined && <span className="ct" data-num>{count}</span>}
    </div>
    {see && <a className="see">{see} <Icon name="chevron-right" size={15} stroke={2.2}/></a>}
  </div>
);

// ─────────────────────────────────────────────────────────────
// Today's arc — today-only timeline, past dimmed, Now marker.
// ─────────────────────────────────────────────────────────────
const TArcRow = ({ kind = 'next', time, suffix, title, location, feed }) => (
  <div className={`arc-r ${kind}`}>
    <div className="when">
      <span className="h" data-num>{time}</span>
      <span className="s">{suffix}</span>
    </div>
    <div className="sw" style={{ background: FEED_HEX[feed] || 'var(--io-blue)' }}/>
    <div className="body">
      <div className="t">{title}</div>
      {location && <div className="l">{location}</div>}
    </div>
    <div className="right"><Icon name="chevron-right" size={14} stroke={2.4}/></div>
  </div>
);

const TArc = ({ items, nowLabel = '10:14', nowAfter }) => {
  let idx = nowAfter;
  if (idx === undefined) {
    const firstNext = items.findIndex(i => i.kind !== 'past');
    idx = firstNext - 1;
  }
  return (
    <div className="t-arc">
      {items.map((it, i) => (
        <React.Fragment key={i}>
          <TArcRow {...it}/>
          {i === idx && (
            <div className="now-line">
              <div className="lbl" data-num>{nowLabel}</div>
              <div className="bar"/>
            </div>
          )}
        </React.Fragment>
      ))}
    </div>
  );
};

// ─────────────────────────────────────────────────────────────
// Module tile — chip + label + exactly one live datum. Never an icon
// alone: the datum is what makes the shelf a command centre.
// ─────────────────────────────────────────────────────────────
const ModuleTile = ({ icon, chip, label, datumValue, datumRest, empty = false }) => (
  <div className="tile2">
    <div className="head">
      <div className="chip" style={{ background: chip }}>
        <Icon name={icon} size={18} stroke={2.3}/>
      </div>
      <span className="cv"><Icon name="chevron-right" size={15} stroke={2.4}/></span>
    </div>
    <div className="tl">{label}</div>
    <div className={'datum' + (empty ? ' empty' : '')}>
      <span className="v" data-num>{datumValue}</span>
      {datumRest && <span>{datumRest}</span>}
    </div>
  </div>
);

// ─────────────────────────────────────────────────────────────
// Create sheet option row
// ─────────────────────────────────────────────────────────────
const CreateOpt = ({ icon, color, title, sub }) => (
  <div className="create-opt">
    <div className="ci" style={{ background: color }}><Icon name={icon} size={19} stroke={2.3}/></div>
    <div className="ct">
      <div className="t">{title}</div>
      <div className="s">{sub}</div>
    </div>
    <span className="cv"><Icon name="chevron-right" size={16} stroke={2.4}/></span>
  </div>
);

Object.assign(window, {
  TAB5, TabBar5, TodayHero, TSection, TArc, TArcRow, ModuleTile, CreateOpt,
  HERO_PALETTES, HERO_PALETTE_LIST, HERO_PALETTE_REPS,
  gradientFor, greetingForTod, resolveTimeOfDay, paletteNameFrom,
});
