/* eslint-disable */
/* =========================================================
   TEO IoT Dashboard — Overview screen.
   ========================================================= */

// Mobile-only hero card above the KPI strip. Punches up the
// above-the-fold with site identity + overall status + a fleet
// state mix bar. Hidden on desktop where the KPI strip leads.
const MobileSiteHero = ({ site, devices, alerts }) => {
  const siteDevices = devices.filter(d => d.site === site.id);
  const counts = { ok:0, warn:0, down:0, idle:0 };
  siteDevices.forEach(d => { counts[d.state] = (counts[d.state]||0)+1; });
  const total = siteDevices.length;
  const openAlerts = alerts.filter(a => !a.ack && a.site === site.id).length;
  const overall = counts.down > 0 ? 'down' : counts.warn > 0 ? 'warn' : 'ok';
  const statusLabel = overall === 'ok' ? 'All systems operational'
                    : overall === 'warn' ? 'Degraded · attention needed'
                    : 'Critical · action required';
  const onlinePct = total ? Math.round((counts.ok / total) * 100) : 0;

  return (
    <div style={{
      background:'#0A0F1F', color:'#FFF',
      padding:'18px 16px 20px', borderBottom:'1px solid rgba(255,255,255,.12)',
      position:'relative', overflow:'hidden'
    }}>
      {/* Subtle radial accent in the background */}
      <div style={{
        position:'absolute', top:-40, right:-40, width:180, height:180,
        background:'radial-gradient(circle at center, rgba(58,111,248,.22), transparent 70%)',
        pointerEvents:'none'
      }} />
      <div style={{ position:'relative', zIndex:1 }}>
        <div style={{
          fontSize:10, letterSpacing:'0.14em', textTransform:'uppercase',
          color:'rgba(255,255,255,.55)', fontWeight:500
        }}>
          {site.customer || site.sector || 'Workspace'} · {site.id}
        </div>
        <div style={{
          fontSize:24, fontWeight:300, letterSpacing:'-0.04em',
          color:'#FFF', margin:'8px 0 16px', lineHeight:1.2
        }}>
          {site.name.replace(/^[^·]+·\s/, '')}
        </div>

        {/* Status row */}
        <div style={{ display:'flex', alignItems:'center', gap:10, marginBottom:14 }}>
          <span style={{
            width:8, height:8, borderRadius:'50%',
            background: overall==='ok'?'#3A6FF8':overall==='warn'?'#E0A13B':'#C44A4A',
            boxShadow:`0 0 0 4px ${overall==='ok'?'rgba(58,111,248,.25)':overall==='warn'?'rgba(224,161,59,.25)':'rgba(196,74,74,.25)'}`
          }} />
          <span style={{ fontSize:13, color:'#FFF', fontWeight:400 }}>{statusLabel}</span>
        </div>

        {/* Fleet state mix bar */}
        <div style={{ display:'flex', height:6, background:'rgba(255,255,255,.08)', marginBottom:10 }}>
          {counts.ok   > 0 && <div style={{ flex:counts.ok,   background:'#3A6FF8' }} />}
          {counts.warn > 0 && <div style={{ flex:counts.warn, background:'#E0A13B' }} />}
          {counts.down > 0 && <div style={{ flex:counts.down, background:'#C44A4A' }} />}
          {counts.idle > 0 && <div style={{ flex:counts.idle, background:'#878787' }} />}
        </div>

        {/* Stat row */}
        <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', gap:8, fontFamily:'IBM Plex Mono, monospace', fontSize:11, color:'rgba(255,255,255,.65)' }}>
          <span>
            <strong style={{ color:'#FFF', fontWeight:500, marginRight:4 }}>{onlinePct}%</strong>
            online
          </span>
          <span>{counts.ok}/{total} devices</span>
          <span style={{ color: openAlerts > 0 ? '#E0A13B' : 'rgba(255,255,255,.65)' }}>
            {openAlerts} alert{openAlerts !== 1 ? 's' : ''}
          </span>
        </div>
      </div>
    </div>
  );
};

const KPIStrip = ({ devices, alerts }) => {
  const total = devices.length;
  const online = devices.filter(d => d.state === 'ok').length;
  const warn   = devices.filter(d => d.state === 'warn').length;
  const down   = devices.filter(d => d.state === 'down').length;
  const openAlerts = alerts.filter(a => !a.ack).length;
  return (
    <div data-kpi-strip style={{ display:'grid', gridTemplateColumns:'repeat(4,1fr)', borderTop:'1px solid #EDEDED', borderBottom:'1px solid #EDEDED', background:'#FFF' }}>
      <MetricTile label="Devices online"    value={`${online}`} unit={`/ ${total}`} delta={down ? `-${down}` : '+0'} sub={down ? `${down} offline · ${warn} degraded` : 'All operational'} />
      <MetricTile label="Telemetry rate"    value="842"  unit="msg/s" delta="+8.1%" sub="vs prior hour" />
      <MetricTile label="Open alerts"       value={`${openAlerts}`} delta={openAlerts ? `+${openAlerts}` : '+0'} sub="0 critical pending ack" />
      <MetricTile label="Mean time to ack"  value="1m"   unit="12s"   delta="-34%" sub="30-day rolling" />
    </div>
  );
};

const FleetStatusDonut = ({ devices }) => {
  const counts = { ok:0, warn:0, down:0, idle:0 };
  devices.forEach(d => { counts[d.state] = (counts[d.state]||0)+1; });
  const slices = [
    { label:'Online',   value:counts.ok,   color:'#3A6FF8' },
    { label:'Degraded', value:counts.warn, color:'#E0A13B' },
    { label:'Offline',  value:counts.down, color:'#C44A4A' },
    { label:'Idle',     value:counts.idle, color:'#878787' },
  ].filter(s => s.value > 0);
  return (
    <Donut
      title="Fleet status"
      total={devices.length}
      totalLabel="devices"
      slices={slices}
    />
  );
};

const SectorBreakdown = ({ devices }) => {
  // Aggregate by kind, take top 6
  const byKind = {};
  devices.forEach(d => { byKind[d.kind] = (byKind[d.kind]||0)+1; });
  const palette = ['#0A0F1F','#3A6FF8','#7A9CFF','#23459E','#5A5E6E','#878787'];
  const slices = Object.entries(byKind)
    .sort((a,b) => b[1]-a[1])
    .slice(0, 6)
    .map(([k,v], i) => ({ label: k.charAt(0).toUpperCase()+k.slice(1).replace('-',' '), value:v, color:palette[i % palette.length] }));
  return (
    <Donut
      title="Devices by class"
      total={devices.length}
      totalLabel="total"
      slices={slices}
    />
  );
};

// Compact "today's snapshot" card — sector-aware so workspace sites
// show occupancy / air quality, energy sites show throughput / cost, etc.
// Fills the visual gap next to the Fleet Status donut.
const TodaySnapshot = ({ site, devices }) => {
  const siteDevices = devices.filter(d => d.site === site.id);

  // Compute relevant stats from real device data
  const occupancy = siteDevices.filter(d => d.kind === 'occupancy');
  const co2 = siteDevices.filter(d => d.kind === 'sensor' && (d.metric.label === 'CO₂' || d.metric.unit === 'ppm'));
  const meters = siteDevices.filter(d => d.kind === 'meter');
  const meetings = siteDevices.filter(d => d.kind === 'meeting-room');
  const hotDesks = siteDevices.filter(d => d.kind === 'hot-desk');

  const totalPeople = occupancy.reduce((s, d) => s + d.metric.value, 0);
  const peakPpl = occupancy.length ? Math.max(...occupancy.map(d => d.metric.value)) : 0;
  const avgCo2 = co2.length ? Math.round(co2.reduce((s, d) => s + d.metric.value, 0) / co2.length) : null;
  const totalKw = Math.round(meters.reduce((s, d) => s + d.metric.value, 0));
  const avgBooked = meetings.length ? Math.round(meetings.reduce((s, d) => s + d.metric.value, 0) / meetings.length) : null;
  const deskTotal = hotDesks.reduce((s, d) => s + d.metric.value, 0);
  const deskCap = hotDesks.reduce((s, d) => s + d.metric.max, 0);

  const isWorkspace = site.sector === 'Workspace' || site.customer === 'Form Property';

  // Pick 4 relevant stats based on sector
  let stats;
  if (isWorkspace) {
    stats = [
      { label:'People on site',  value:totalPeople,  unit:'',     hint:'across occupancy sensors' },
      { label:'Air quality',     value:avgCo2 || '—', unit:'ppm', hint:`avg CO₂ · ${avgCo2 > 1000 ? 'elevated' : 'good'}` },
      { label:'Energy use',      value:totalKw,      unit:'kW',   hint:'current draw' },
      ...(meetings.length
        ? [{ label:'Meeting rooms', value:avgBooked,  unit:'%',   hint:'avg utilisation today' }]
        : hotDesks.length
        ? [{ label:'Hot desks',     value:deskTotal,  unit:`/${deskCap}`, hint:'occupied · capacity' }]
        : [{ label:'Active sensors', value:siteDevices.length, unit:'', hint:'across the site' }]
      ),
    ];
  } else {
    stats = [
      { label:'Devices',  value:siteDevices.length, unit:'', hint:'on this site' },
      { label:'Energy',   value:totalKw || '—',     unit:'kW', hint:'current draw' },
      { label:'Avg CO₂',  value:avgCo2 || '—',      unit:'ppm', hint:avgCo2 > 1000 ? 'review ventilation' : 'within range' },
      { label:'Active',   value:siteDevices.filter(d => d.state==='ok').length, unit:'', hint:'online now' },
    ];
  }

  return (
    <Card pad={0}>
      <div style={{ padding:'18px 24px', borderBottom:'1px solid #EDEDED' }}>
        <Eyebrow>Today · live snapshot</Eyebrow>
        <div style={{ fontSize:16, color:'#0A0F1F', marginTop:4 }}>{isWorkspace ? 'Workspace activity' : 'Site activity'}</div>
      </div>
      <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr' }}>
        {stats.map((s, i) => (
          <div key={i} style={{
            padding:'18px 24px',
            borderRight: i % 2 === 0 ? '1px solid #EDEDED' : 'none',
            borderBottom: i < 2 ? '1px solid #EDEDED' : 'none'
          }}>
            <Eyebrow>{s.label}</Eyebrow>
            <div style={{
              fontSize:30, fontWeight:300, letterSpacing:'-0.04em', color:'#0A0F1F',
              marginTop:8, fontVariantNumeric:'tabular-nums', lineHeight:1
            }}>
              {s.value}{s.unit && <span style={{ fontSize:13, color:'#5A5E6E', marginLeft:4, letterSpacing:0 }}>{s.unit}</span>}
            </div>
            <div style={{ fontSize:12, color:'#5A5E6E', marginTop:8 }}>{s.hint}</div>
          </div>
        ))}
      </div>
    </Card>
  );
};

// Synthetic 24h x 7d alert-volume heatmap
const AlertHeatmap = () => {
  // deterministic pseudo-random based on (row, col) so it doesn't jitter every render
  const cols = ['00','03','06','09','12','15','18','21'];
  const rows = ['Mon','Tue','Wed','Thu','Fri','Sat','Sun'];
  const matrix = rows.map((_, r) => cols.map((_, c) => {
    // peak around 09-15 weekdays
    const peakHour = c >= 3 && c <= 5 ? 1 : 0.3;
    const weekday  = r < 5 ? 1 : 0.4;
    const noise = ((r * 7 + c * 13) % 7) / 10;
    return Math.round(peakHour * weekday * (3 + noise * 5));
  }));
  return <Heatmap title="Alert volume · last 7 days" matrix={matrix} rows={rows} cols={cols} palette="warn" />;
};

const LiveEventStream = ({ events }) => {
  const isMobile = useIsMobile();
  return (
    <Card dark pad={isMobile ? 16 : 24} style={{ height:'100%' }}>
      <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:16 }}>
        <div>
          <div style={{ fontSize:11, letterSpacing:'0.08em', textTransform:'uppercase', color:'rgba(255,255,255,.5)' }}>Event stream</div>
          <div style={{ fontSize:16, fontWeight:400, marginTop:4, display:'flex', alignItems:'center', gap:8 }}>
            <span style={{ width:6, height:6, borderRadius:'50%', background:'#7A9CFF', boxShadow:'0 0 0 4px rgba(122,156,255,.25)' }} />
            Following
          </div>
        </div>
        <Button kind="subtle" style={{ background:'transparent', borderColor:'rgba(255,255,255,.25)', color:'#FFF' }}>Pause</Button>
      </div>
      <div style={{ fontFamily:'IBM Plex Mono, monospace', fontSize:12, lineHeight:1.7 }}>
        {events.map(([t,lvl,src,msg],i) => {
          if (isMobile) {
            return (
              <div key={i} style={{
                padding:'10px 0', borderBottom:'1px solid rgba(255,255,255,.08)',
                display:'flex', flexDirection:'column', gap:4
              }}>
                <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', fontSize:11 }}>
                  <span style={{ color: lvl==='crit'?'#C44A4A':lvl==='warn'?'#E0A13B':'#7A9CFF' }}>{lvl.toUpperCase()}</span>
                  <span style={{ color:'rgba(255,255,255,.4)' }}>{t}</span>
                </div>
                <div style={{ color:'rgba(255,255,255,.92)', fontSize:12, lineHeight:1.4 }}>{msg}</div>
                <div style={{ color:'rgba(255,255,255,.55)', fontSize:11 }}>{src}</div>
              </div>
            );
          }
          return (
            <div key={i} style={{
              display:'grid', gridTemplateColumns:'70px 50px 110px 1fr', gap:12,
              padding:'8px 0', borderBottom:'1px solid rgba(255,255,255,.08)'
            }}>
              <span style={{ color:'rgba(255,255,255,.4)' }}>{t}</span>
              <span style={{ color: lvl==='crit'?'#C44A4A':lvl==='warn'?'#E0A13B':'rgba(255,255,255,.6)' }}>{lvl.toUpperCase()}</span>
              <span style={{ color:'rgba(255,255,255,.7)' }}>{src}</span>
              <span style={{ color:'rgba(255,255,255,.92)' }}>{msg}</span>
            </div>
          );
        })}
      </div>
    </Card>
  );
};

const HealthTrend = () => {
  const series = [
    { label:'Throughput', unit:'msg/s', color:'#3A6FF8', data: MOCK.makeSeries(800, 60) },
    { label:'Errors',     unit:'/min',  color:'#C44A4A', data: MOCK.makeSeries(2, 1) },
  ];
  const [range, setRange] = React.useState('24h');
  return <TimeSeriesChart series={series} height={200} range={range} onRange={setRange} />;
};

const ZoneSummary = ({ devices, site, onZoneClick }) => {
  const isMobile = useIsMobile();
  const siteDevices = devices.filter(d => d.site === site.id);
  const zones = {};
  siteDevices.forEach(d => {
    if (!zones[d.zone]) zones[d.zone] = { total:0, ok:0, warn:0, down:0, idle:0 };
    zones[d.zone].total++;
    zones[d.zone][d.state]++;
  });
  return (
    <Card pad={0}>
      <div style={{
        padding: isMobile ? '14px 16px' : '18px 24px',
        borderBottom:'1px solid #EDEDED',
        display:'flex', justifyContent:'space-between', alignItems:'center', gap:12, flexWrap:'wrap'
      }}>
        <div>
          <Eyebrow>Site rollup</Eyebrow>
          <div style={{ fontSize:16, color:'#0A0F1F', marginTop:4 }}>{site.name}</div>
        </div>
        <Button kind="subtle" onClick={() => onZoneClick && onZoneClick()}>Open twin</Button>
      </div>
      {Object.entries(zones).map(([zone, s]) => (
        <div key={zone} style={{
          padding: isMobile ? '14px 16px' : '16px 24px',
          borderBottom:'1px solid #EDEDED'
        }}>
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', gap:12 }}>
            <div style={{ minWidth:0, flex:1 }}>
              <div style={{ fontSize:14, color:'#0A0F1F' }}>{zone}</div>
              <div style={{ fontSize:12, color:'#5A5E6E', marginTop:2 }}>{s.total} devices</div>
            </div>
            <div style={{ display:'flex', gap:12, fontSize:12, fontVariantNumeric:'tabular-nums', fontFamily:'IBM Plex Mono, monospace' }}>
              {s.ok>0   && <span style={{ display:'inline-flex', alignItems:'center', gap:4 }}><StatusDot state="ok" />{s.ok}</span>}
              {s.warn>0 && <span style={{ display:'inline-flex', alignItems:'center', gap:4 }}><StatusDot state="warn" />{s.warn}</span>}
              {s.down>0 && <span style={{ display:'inline-flex', alignItems:'center', gap:4 }}><StatusDot state="down" />{s.down}</span>}
              {s.idle>0 && <span style={{ display:'inline-flex', alignItems:'center', gap:4 }}><StatusDot state="idle" />{s.idle}</span>}
            </div>
          </div>
        </div>
      ))}
    </Card>
  );
};

const Overview = ({ site, devices, alerts, events, onNav, sites }) => {
  const isMobile = useIsMobile();
  const [scope, setScope] = React.useState('This building');

  // If on a customer with multiple sites, expose a scope toggle for aggregation.
  const groupSites = site.customer
    ? sites.filter(s => s.customer === site.customer)
    : [];
  const showAggregateToggle = groupSites.length > 1;
  const scopedSiteIds = (showAggregateToggle && scope === 'All buildings')
    ? new Set(groupSites.map(s => s.id))
    : new Set([site.id]);
  const scopedDevices = devices.filter(d => scopedSiteIds.has(d.site));
  const scopedAlerts  = alerts.filter(a => scopedSiteIds.has(a.site));
  const scopedEvents  = events; // events feed not site-scoped

  return (
    <div>
      {isMobile && <MobileSiteHero site={site} devices={devices} alerts={alerts} />}
      {showAggregateToggle && (
        <div style={{
          padding: isMobile ? '12px 16px' : '14px 32px',
          background:'#FFF', borderBottom:'1px solid #EDEDED',
          display:'flex', justifyContent:'space-between', alignItems:'center', gap:12, flexWrap:'wrap'
        }}>
          <div style={{ display:'flex', alignItems:'center', gap:10, minWidth:0 }}>
            <i data-lucide="layers" style={{ width:14, height:14, color:'#3A6FF8' }} />
            <span style={{ fontSize:12, color:'#5A5E6E', letterSpacing:'0.04em' }}>
              <strong style={{ color:'#0A0F1F', fontWeight:500 }}>{site.customer}</strong> · {groupSites.length} buildings
            </span>
          </div>
          <SegmentedControl
            value={scope}
            onChange={setScope}
            options={['This building','All buildings']}
          />
        </div>
      )}
      <KPIStrip devices={scopedDevices} alerts={scopedAlerts} />
      <div data-collapse-md style={{ display:'grid', gridTemplateColumns:'2fr 1fr', borderBottom:'1px solid #EDEDED' }}>
        <HealthTrend />
        <SectorBreakdown devices={scopedDevices} />
      </div>
      <div data-pad-md style={{ padding:32, background:'#F6F7F9', display:'flex', flexDirection:'column', gap:24 }}>
        {/* Row 1: donut (1/3) | heatmap (2/3) */}
        <div data-collapse-md style={{ display:'grid', gridTemplateColumns:'1fr 2fr', gap:24, alignItems:'stretch' }}>
          <FleetStatusDonut devices={scopedDevices} />
          <AlertHeatmap />
        </div>
        {/* Row 2: snapshot (1/2) | zone summary (1/2) */}
        <div data-collapse-md style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:24, alignItems:'start' }}>
          <TodaySnapshot site={site} devices={scopedDevices} />
          <ZoneSummary site={site} devices={devices} onZoneClick={() => onNav('twin')} />
        </div>
        {/* Row 3: live event stream full-width */}
        <LiveEventStream events={scopedEvents} />
      </div>
    </div>
  );
};

Object.assign(window, { Overview });
