/* eslint-disable */
/* =========================================================
   TEO IoT Dashboard — Digital Twin schematic.
   A 2D top-down floor plan with live overlay for the
   currently selected site. Each device renders as a node
   on the schematic, coloured by state, with a hover card.
   ========================================================= */

// Layout: site zones positioned on a 1200x640 schematic.
// Coordinates are arbitrary — replace with real CAD/BIM positions when integrating.
const ZONE_LAYOUT = {
  'Transformer bay': { x: 60,  y: 60,  w: 380, h: 240 },
  'Battery storage': { x: 460, y: 60,  w: 320, h: 240 },
  'Sensor mesh':     { x: 800, y: 60,  w: 340, h: 240 },
  'Loading bay':     { x: 60,  y: 340, w: 540, h: 260 },
  'Sortation':       { x: 620, y: 340, w: 520, h: 260 },
};

// Device positions within zones — relative, evenly spaced.
function positionDevices(siteDevices) {
  const groups = {};
  siteDevices.forEach(d => {
    if (!groups[d.zone]) groups[d.zone] = [];
    groups[d.zone].push(d);
  });
  const out = [];
  Object.entries(groups).forEach(([zone, list]) => {
    const z = ZONE_LAYOUT[zone];
    if (!z) return;
    const cols = Math.ceil(Math.sqrt(list.length));
    const rows = Math.ceil(list.length / cols);
    const padX = 36, padY = 50;
    list.forEach((d, i) => {
      const col = i % cols, row = Math.floor(i / cols);
      const x = z.x + padX + col * ((z.w - padX*2) / Math.max(1,cols-1) || 0);
      const y = z.y + padY + row * ((z.h - padY*2) / Math.max(1,rows-1) || 0);
      out.push({ ...d, x: cols===1 ? z.x + z.w/2 : x, y: rows===1 ? z.y + z.h/2 + 8 : y, zone });
    });
  });
  return out;
}

const TwinLegend = () => (
  <div style={{ display:'flex', gap:20, alignItems:'center', flexWrap:'wrap' }}>
    {[['ok','Online'],['warn','Degraded'],['down','Offline'],['idle','Idle']].map(([s,l]) => (
      <div key={s} style={{ display:'flex', alignItems:'center', gap:8, fontSize:12, color:'#5A5E6E' }}>
        <StatusDot state={s} />{l}
      </div>
    ))}
  </div>
);

const TwinNode = ({ d, onClick, selected }) => {
  const color = COLORS[d.state] || COLORS.ok;
  const valuePct = Math.max(0, Math.min(1, (d.metric.value - d.metric.min) / (d.metric.max - d.metric.min)));
  return (
    <g transform={`translate(${d.x}, ${d.y})`} onClick={() => onClick(d)} style={{ cursor:'pointer' }}>
      {selected && <rect x={-28} y={-28} width={56} height={56} fill="none" stroke="#3A6FF8" strokeWidth="1" />}
      {/* outer ring (state) */}
      <circle r="18" fill="#FFF" stroke={color} strokeWidth="1.5" />
      {/* fill arc proportional to metric */}
      <circle r="13" fill="none" stroke={color} strokeOpacity="0.18" strokeWidth="6" />
      <circle r="13" fill="none" stroke={color} strokeWidth="6"
              strokeDasharray={`${valuePct * 81.6} 81.6`} transform="rotate(-90)" />
      {/* center dot */}
      <circle r="3" fill={color} />
      {/* label */}
      <text x={0} y={36} textAnchor="middle" style={{ font:"500 10px 'IBM Plex Mono', monospace", fill:'#0A0F1F' }}>{d.id}</text>
      <text x={0} y={48} textAnchor="middle" style={{ font:"400 9px 'IBM Plex Sans'", fill:'#5A5E6E' }}>
        {d.metric.value}{d.metric.unit}
      </text>
    </g>
  );
};

const Twin2D = ({ devices, site, selectedId, onSelect }) => {
  const siteDevices = devices.filter(d => d.site === site.id);
  const positioned = positionDevices(siteDevices);
  const zones = Array.from(new Set(siteDevices.map(d => d.zone)));

  return (
      <svg viewBox="0 0 1200 640" preserveAspectRatio="xMidYMid meet" style={{ display:'block', width:'100%', height:'auto', background:'#FAFBFC' }}>
        {/* hairline grid */}
        <defs>
          <pattern id="twinGrid" width="40" height="40" patternUnits="userSpaceOnUse">
            <path d="M 40 0 L 0 0 0 40" fill="none" stroke="#EDEDED" strokeWidth="0.5"/>
          </pattern>
        </defs>
        <rect width="1200" height="640" fill="url(#twinGrid)" />

        {/* zones */}
        {zones.map(z => {
          const layout = ZONE_LAYOUT[z];
          if (!layout) return null;
          return (
            <g key={z}>
              <rect x={layout.x} y={layout.y} width={layout.w} height={layout.h} fill="#FFF" stroke="#0A0F1F" strokeWidth="1" />
              <rect x={layout.x} y={layout.y} width={layout.w} height={28} fill="#0A0F1F" />
              <text x={layout.x + 12} y={layout.y + 19} style={{ font:"500 11px 'IBM Plex Sans'", fill:'#FFF', letterSpacing:'0.08em', textTransform:'uppercase' }}>
                {z.toUpperCase()}
              </text>
            </g>
          );
        })}

        {/* devices */}
        {positioned.map(d => (
          <TwinNode key={d.id} d={d} onClick={onSelect} selected={d.id === selectedId} />
        ))}
      </svg>
  );
};

const TwinInspector = ({ device, onOpen, onCommand }) => {
  if (!device) {
    return (
      <Card pad={32}>
        <Eyebrow>Inspector</Eyebrow>
        <div style={{ fontSize:14, color:'#5A5E6E', marginTop:16 }}>Select a device on the schematic to view live state.</div>
      </Card>
    );
  }
  return (
    <Card pad={0}>
      <div style={{ padding:'24px', borderBottom:'1px solid #EDEDED' }}>
        <Eyebrow accent>{device.id}</Eyebrow>
        <div style={{ fontSize:21, fontWeight:400, color:'#0A0F1F', margin:'6px 0 10px' }}>{device.name}</div>
        <div style={{ display:'flex', alignItems:'center', gap:12, color:'#5A5E6E', fontSize:13 }}>
          <StatusPill state={device.state} />
          <Hairline vertical />
          <span>{device.zone}</span>
        </div>
      </div>
      <div style={{ padding:'24px', borderBottom:'1px solid #EDEDED' }}>
        <Eyebrow>{device.metric.label}</Eyebrow>
        <div style={{ display:'flex', alignItems:'baseline', gap:6, margin:'10px 0 16px', fontVariantNumeric:'tabular-nums' }}>
          <span style={{ fontSize:40, fontWeight:300, letterSpacing:'-0.06em', color:'#0A0F1F' }}>{device.metric.value}</span>
          <span style={{ fontSize:14, color:'#5A5E6E' }}>{device.metric.unit}</span>
        </div>
        <ThresholdBar value={device.metric.value} min={device.metric.min} max={device.metric.max} warn={device.metric.warn} crit={device.metric.crit} unit={device.metric.unit} />
      </div>
      <div style={{ padding:'24px', borderBottom:'1px solid #EDEDED' }}>
        <Eyebrow>Metadata</Eyebrow>
        <div style={{ marginTop:12, display:'grid', gridTemplateColumns:'80px 1fr', gap:'8px 16px', fontSize:13, color:'#0A0F1F' }}>
          <span style={{ color:'#5A5E6E' }}>Kind</span><span style={{ textTransform:'capitalize' }}>{device.kind}</span>
          <span style={{ color:'#5A5E6E' }}>Model</span><span style={{ fontFamily:'IBM Plex Mono, monospace', fontSize:12 }}>{device.model}</span>
          <span style={{ color:'#5A5E6E' }}>Firmware</span><span style={{ fontFamily:'IBM Plex Mono, monospace', fontSize:12 }}>{device.firmware}</span>
          <span style={{ color:'#5A5E6E' }}>Site</span><span style={{ fontFamily:'IBM Plex Mono, monospace', fontSize:12 }}>{device.site}</span>
        </div>
      </div>
      <div style={{ padding:'24px', display:'flex', gap:8 }}>
        <Button kind="ghost" onClick={() => onOpen(device)}>Open detail</Button>
        <Button kind="primary" onClick={() => onCommand(device, 'restart')}>Restart</Button>
      </div>
    </Card>
  );
};

const Twin = ({ devices, site, onOpenDevice, onCommand }) => {
  const [selected, setSelected] = React.useState(null);
  const [view, setView] = React.useState('3D');
  const selectedDevice = selected ? devices.find(d => d.id === selected) : null;
  const onSelectFromCanvas = (d) => setSelected(d.id);
  return (
    <div data-pad-md data-collapse-md style={{ padding:32, background:'#F6F7F9', display:'grid', gridTemplateColumns:'1fr 360px', gap:24, alignItems:'start' }}>
      <div style={{ background:'#FFF', border:'1px solid #EDEDED', position:'relative' }}>
        <div style={{ padding:'18px 24px', borderBottom:'1px solid #EDEDED', display:'flex', justifyContent:'space-between', alignItems:'center', flexWrap:'wrap', gap:12 }}>
          <div>
            <Eyebrow accent>{site.id}</Eyebrow>
            <div style={{ fontSize:21, fontWeight:400, color:'#0A0F1F', marginTop:6 }}>{site.name}</div>
          </div>
          <div style={{ display:'flex', alignItems:'center', gap:24 }}>
            {view === '2D' && <TwinLegend />}
            <SegmentedControl value={view} onChange={setView} options={['2D','3D']} />
          </div>
        </div>
        {view === '2D' && (
          <Twin2D devices={devices} site={site} selectedId={selected} onSelect={onSelectFromCanvas} />
        )}
        {view === '3D' && (
          <Twin3D devices={devices} site={site} selectedId={selected} onSelect={onSelectFromCanvas} />
        )}
      </div>
      <TwinInspector device={selectedDevice} onOpen={onOpenDevice} onCommand={onCommand} />
    </div>
  );
};

Object.assign(window, { Twin });
