/* eslint-disable */
/* =========================================================
   TEO IoT Dashboard — primitives.
   All shared atoms used across screens. TEO tokens only:
   - radius 0 (except pill/circle)
   - hairline borders (#EDEDED on light, rgba(255,255,255,.12) on dark)
   - IBM Plex Sans + Mono
   - accent #3A6FF8 used sparingly
   ========================================================= */

const COLORS = {
  ok:   '#3A6FF8',
  warn: '#E0A13B',
  crit: '#C44A4A',
  idle: '#878787',
  info: '#5A5E6E',
  down: '#C44A4A',
};

const STATE_LABEL = {
  ok:'Online', warn:'Degraded', down:'Offline', idle:'Idle',
  crit:'Critical', info:'Info',
};

const Eyebrow = ({ children, accent, style }) => (
  <div style={{ fontSize:11, letterSpacing:'0.08em', textTransform:'uppercase', color: accent?'#3A6FF8':'#5A5E6E', fontWeight:500, ...style }}>{children}</div>
);

const Hairline = ({ vertical, color='#EDEDED', size=14, style }) =>
  vertical
    ? <span style={{ display:'inline-block', width:1, height:size, background:color, ...style }} />
    : <hr style={{ height:1, background:color, border:0, margin:0, ...style }} />;

const StatusDot = ({ state='ok', size=8, pulse }) => {
  const c = COLORS[state] || COLORS.ok;
  return (
    <span style={{
      width:size, height:size, borderRadius:'50%', background:c, display:'inline-block',
      boxShadow: pulse ? `0 0 0 ${Math.max(2,size/2)}px ${c}22` : 'none',
    }} />
  );
};

const StatusPill = ({ state='ok', children, mono }) => {
  const c = COLORS[state] || COLORS.ok;
  return (
    <span style={{ display:'inline-flex', alignItems:'center', gap:8, font: mono ? "500 12px 'IBM Plex Mono', monospace" : "400 13px 'IBM Plex Sans'", color:'#0A0F1F' }}>
      <StatusDot state={state} pulse={state==='ok'||state==='warn'||state==='crit'} />
      {children || STATE_LABEL[state] || state}
    </span>
  );
};

const Sev = ({ s }) => {
  const map = { info:['INFO','#5A5E6E','#F6F7F9'], warn:['WARN','#E0A13B','#FBF1DD'], crit:['CRIT','#C44A4A','#FADEDE'], ok:['OK','#3A6FF8','#E2EAFD'] };
  const [l,col,bg] = map[s] || map.info;
  return <span style={{ display:'inline-block', padding:'2px 8px', background:bg, color:col, fontFamily:'IBM Plex Mono, monospace', fontSize:11, letterSpacing:'0.04em' }}>{l}</span>;
};

const Tag = ({ children, dark }) => (
  <span style={{
    display:'inline-block', padding:'3px 10px 2px', borderRadius:100,
    background: dark ? 'rgba(255,255,255,0.16)' : 'rgba(10,15,31,0.04)',
    border: '1px solid '+(dark ? 'rgba(255,255,255,.4)' : 'rgba(10,15,31,.2)'),
    color: dark ? '#FFF' : '#0A0F1F', font:"400 12px 'IBM Plex Sans'"
  }}>{children}</span>
);

const Button = ({ kind='primary', children, style, ...r }) => {
  const styles = {
    primary: { background:'#0A0F1F', color:'#FFF', border:'1px solid #0A0F1F' },
    ghost:   { background:'#FFF', color:'#0A0F1F', border:'1px solid #0A0F1F' },
    accent:  { background:'#3A6FF8', color:'#FFF', border:'1px solid #3A6FF8' },
    subtle:  { background:'transparent', color:'#0A0F1F', border:'1px solid #EBEBEB' },
    danger:  { background:'#FFF', color:'#C44A4A', border:'1px solid #C44A4A' },
  };
  return (
    <button {...r} style={{
      padding:'10px 16px', borderRadius:0, cursor:'pointer',
      font:"400 13px 'IBM Plex Sans'", letterSpacing:'0.3px',
      transition:'background 200ms cubic-bezier(0.68,0.01,0.58,0.75)',
      ...styles[kind], ...style
    }}>{children}</button>
  );
};

const SegmentedControl = ({ value, onChange, options }) => (
  <div style={{ display:'inline-flex', border:'1px solid #EDEDED' }}>
    {options.map((o,i) => (
      <button key={o} onClick={() => onChange(o)}
        style={{
          padding:'6px 12px',
          background: value===o ? '#0A0F1F' : 'transparent',
          color: value===o ? '#FFF' : '#242739',
          border:'none', borderLeft: i? '1px solid #EDEDED' : 'none',
          borderRadius:0, cursor:'pointer', font:"400 12px 'IBM Plex Sans'"
        }}>{o}</button>
    ))}
  </div>
);

const Card = ({ children, dark, pad=24, style }) => (
  <div style={{
    background: dark ? '#11172B' : '#FFF',
    color: dark ? '#FFF' : '#0A0F1F',
    border: '1px solid '+(dark ? 'rgba(255,255,255,.12)' : '#EDEDED'),
    padding: pad,
    ...style
  }}>{children}</div>
);

const MetricTile = ({ label, value, unit, delta, sub, big, mono }) => {
  const isMobile = useIsMobile();
  const baseSize = big ? 56 : 48;
  const valSize = isMobile ? Math.round(baseSize * 0.65) : baseSize;
  const unitSize = isMobile ? 14 : 18;
  return (
    <div style={{ padding: isMobile ? '16px' : '24px', borderRight:'1px solid #EDEDED' }}>
      <Eyebrow>{label}</Eyebrow>
      <div style={{
        fontSize: valSize, fontWeight:300, letterSpacing:'-0.06em',
        lineHeight:1, color:'#0A0F1F', margin: isMobile ? '10px 0 0' : '16px 0 0',
        fontVariantNumeric:'tabular-nums',
        fontFamily: mono ? "'IBM Plex Mono', monospace" : "'IBM Plex Sans'"
      }}>
        {value}
        {unit && <span style={{ fontSize: unitSize, color:'#5A5E6E', marginLeft:6, letterSpacing:0 }}>{unit}</span>}
      </div>
      <div style={{ display:'flex', alignItems:'center', gap:8, marginTop: isMobile ? 6 : 12, fontSize:12, color:'#242739', flexWrap:'wrap' }}>
        {delta && <span style={{ color: delta.startsWith('-')?'#C44A4A':'#3A6FF8', fontVariantNumeric:'tabular-nums' }}>{delta}</span>}
        <span style={{ color:'#5A5E6E' }}>{sub}</span>
      </div>
    </div>
  );
};

// Threshold bar — shows a metric inside its operating envelope with warn/crit zones.
const ThresholdBar = ({ value, min=0, max=100, warn, crit, unit='', height=8 }) => {
  const pct = (v) => Math.max(0, Math.min(100, (v-min)/(max-min)*100));
  const warnAt = warn!=null ? pct(warn) : null;
  const critAt = crit!=null ? pct(crit) : null;
  const valAt  = pct(value);
  // colour the value dot based on zone
  const dotColor = crit!=null && value>=crit ? '#C44A4A'
                  : warn!=null && value>=warn ? '#E0A13B'
                  : '#3A6FF8';
  return (
    <div>
      <div style={{ position:'relative', height, background:'#F6F7F9', border:'1px solid #EDEDED' }}>
        {warnAt!=null && <div style={{ position:'absolute', inset:`0 0 0 ${warnAt}%`, background:'rgba(224,161,59,.18)' }} />}
        {critAt!=null && <div style={{ position:'absolute', inset:`0 0 0 ${critAt}%`, background:'rgba(196,74,74,.22)' }} />}
        <div style={{ position:'absolute', top:-3, bottom:-3, left:`calc(${valAt}% - 1px)`, width:2, background:dotColor }} />
      </div>
      <div style={{ display:'flex', justifyContent:'space-between', fontSize:11, color:'#5A5E6E', marginTop:6, fontVariantNumeric:'tabular-nums', fontFamily:"'IBM Plex Mono', monospace" }}>
        <span>{min}{unit}</span>
        <span>{max}{unit}</span>
      </div>
    </div>
  );
};

// Sparkline — tiny inline trend used in tables.
const Sparkline = ({ data, w=80, h=22, color='#3A6FF8' }) => {
  if (!data || !data.length) return null;
  const max = Math.max(...data), min = Math.min(...data);
  const pts = data.map((v,i)=>[i*(w/(data.length-1)), h - (v-min)/(max-min||1)*h]);
  const d = pts.map((p,i)=> (i?'L':'M')+p[0].toFixed(1)+' '+p[1].toFixed(1)).join(' ');
  return <svg width={w} height={h} style={{ display:'block' }}><path d={d} fill="none" stroke={color} strokeWidth="1.25" /></svg>
};

// LiveDot — animated "live" indicator for stream headers.
const LiveDot = () => (
  <span style={{ display:'inline-flex', alignItems:'center', gap:8, fontSize:12, color:'#0A0F1F' }}>
    <span style={{ width:8, height:8, borderRadius:'50%', background:'#3A6FF8', boxShadow:'0 0 0 4px rgba(58,111,248,.18)' }} />
    Live
  </span>
);

const KindIcon = ({ kind, size=14 }) => {
  const map = {
    // Energy / logistics (original)
    transformer:'zap', switchgear:'toggle-right', battery:'battery-charging',
    inverter:'power', sensor:'radio', gateway:'router',
    vehicle:'truck', conveyor:'move-right',
    // Manufacturing
    cnc:'cog', robot:'bot', paint:'paintbrush', ahu:'wind',
    plant:'gauge', meter:'gauge-circle',
    // HVAC
    'vrf-outdoor':'air-vent', 'vrf-indoor':'snowflake', chiller:'thermometer-snowflake',
    // Campus
    occupancy:'users', projector:'projector', ap:'wifi',
  };
  return <i data-lucide={map[kind]||'cpu'} style={{ width:size, height:size, color:'#5A5E6E' }} />;
};

// Match against the same 768px breakpoint used in the responsive CSS.
function useIsMobile(query = '(max-width: 768px)') {
  const [m, setM] = React.useState(
    () => typeof window !== 'undefined' && window.matchMedia(query).matches
  );
  React.useEffect(() => {
    const mq = window.matchMedia(query);
    const onChange = (e) => setM(e.matches);
    mq.addEventListener ? mq.addEventListener('change', onChange) : mq.addListener(onChange);
    return () => mq.removeEventListener ? mq.removeEventListener('change', onChange) : mq.removeListener(onChange);
  }, [query]);
  return m;
}

// Generic "field with label" used inside mobile cards.
const Field = ({ label, children, align='left', mono }) => (
  <div style={{ display:'flex', flexDirection:'column', gap:2, textAlign:align }}>
    <span style={{ fontSize:10, letterSpacing:'0.08em', textTransform:'uppercase', color:'#5A5E6E', fontWeight:500 }}>{label}</span>
    <span style={{ fontSize:14, color:'#0A0F1F', fontFamily: mono ? "'IBM Plex Mono', monospace" : "'IBM Plex Sans'" }}>{children}</span>
  </div>
);

// Mobile-friendly section heading used at the top of a card-stack list.
const MobileCardListHeader = ({ eyebrow, title, right }) => (
  <div style={{
    padding:'14px 16px', borderBottom:'1px solid #EDEDED',
    display:'flex', justifyContent:'space-between', alignItems:'center', gap:12, flexWrap:'wrap'
  }}>
    <div>
      <Eyebrow>{eyebrow}</Eyebrow>
      <div style={{ fontSize:16, color:'#0A0F1F', marginTop:4 }}>{title}</div>
    </div>
    {right}
  </div>
);

Object.assign(window, {
  COLORS, Eyebrow, Hairline, StatusDot, StatusPill, Sev, Tag, Button,
  SegmentedControl, Card, MetricTile, ThresholdBar, Sparkline, LiveDot, KindIcon,
  useIsMobile, Field, MobileCardListHeader,
});
