import React, { useState, useEffect, useCallback } from 'react';

const API_BASE = "";

function App() {
  const [overview, setOverview] = useState(null);
  const [selectedDrive, setSelectedDrive] = useState(null);
  const [driveDetail, setDriveDetail] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [lastUpdated, setLastUpdated] = useState(null);

  const fetchOverview = useCallback(async () => {
    try {
      const res = await fetch(`${API_BASE}/api/overview`);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = await res.json();
      setOverview(data);
      setError(null);
      setLastUpdated(new Date());
    } catch (err) {
      setError(err.message);
    } finally {
      setLoading(false);
    }
  }, []);

  useEffect(() => {
    fetchOverview();
    const interval = setInterval(fetchOverview, 30000);
    return () => clearInterval(interval);
  }, [fetchOverview]);

  const fetchDriveDetail = async (device) => {
    setSelectedDrive(device);
    setDriveDetail(null);
    try {
      const res = await fetch(`${API_BASE}/api/drives/${device}`);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      setDriveDetail(await res.json());
    } catch (err) {
      setDriveDetail({ error: err.message });
    }
  };

  if (loading) return <div style={styles.loading}>Loading...</div>;
  if (error && !overview) return <div style={styles.error}>Error: {error}</div>;

  return (
    <div style={styles.container}>
      <header style={styles.header}>
        <h1 style={styles.title}>JBOD Monitor</h1>
        <div style={styles.headerRight}>
          <StatusBadge healthy={overview?.healthy} />
          {lastUpdated && (
            <span style={styles.timestamp}>
              Updated {lastUpdated.toLocaleTimeString()}
            </span>
          )}
          <button onClick={fetchOverview} style={styles.refreshBtn}>Refresh</button>
        </div>
      </header>

      {overview && (
        <div style={styles.summaryBar}>
          <SummaryCard label="Drives" value={overview.drive_count} />
          <SummaryCard label="Warnings" value={overview.warning_count} color={overview.warning_count > 0 ? '#f59e0b' : undefined} />
          <SummaryCard label="Errors" value={overview.error_count} color={overview.error_count > 0 ? '#ef4444' : undefined} />
          <SummaryCard label="Enclosures" value={overview.enclosures.length} />
        </div>
      )}

      {overview?.enclosures.map((enc) => (
        <EnclosureCard
          key={enc.id}
          enclosure={enc}
          onDriveClick={fetchDriveDetail}
          selectedDrive={selectedDrive}
        />
      ))}

      {selectedDrive && (
        <DriveDetailPanel
          device={selectedDrive}
          detail={driveDetail}
          onClose={() => { setSelectedDrive(null); setDriveDetail(null); }}
        />
      )}
    </div>
  );
}

function StatusBadge({ healthy }) {
  const color = healthy ? '#22c55e' : '#ef4444';
  const text = healthy ? 'HEALTHY' : 'DEGRADED';
  return (
    <span style={{ ...styles.badge, backgroundColor: color }}>{text}</span>
  );
}

function SummaryCard({ label, value, color }) {
  return (
    <div style={styles.summaryCard}>
      <div style={{ ...styles.summaryValue, color: color || '#e2e8f0' }}>{value}</div>
      <div style={styles.summaryLabel}>{label}</div>
    </div>
  );
}

function EnclosureCard({ enclosure, onDriveClick, selectedDrive }) {
  const [expanded, setExpanded] = useState(true);
  const enc = enclosure;

  return (
    <div style={styles.enclosure}>
      <div style={styles.enclosureHeader} onClick={() => setExpanded(!expanded)}>
        <div>
          <span style={styles.enclosureTitle}>
            {enc.vendor.trim()} {enc.model.trim()}
          </span>
          <span style={styles.enclosureId}>{enc.id}</span>
          {enc.sg_device && <span style={styles.enclosureSg}>{enc.sg_device}</span>}
        </div>
        <div style={styles.slotCount}>
          {enc.populated_slots}/{enc.total_slots} slots
          <span style={styles.expandIcon}>{expanded ? '\u25BC' : '\u25B6'}</span>
        </div>
      </div>

      {expanded && (
        <div style={styles.slotGrid}>
          {enc.slots.map((slot) => (
            <SlotCell
              key={slot.slot}
              slot={slot}
              selected={selectedDrive === slot.device}
              onClick={() => slot.device && onDriveClick(slot.device)}
            />
          ))}
        </div>
      )}
    </div>
  );
}

function SlotCell({ slot, selected, onClick }) {
  let bg = '#1e293b'; // empty
  let border = '#334155';
  if (slot.populated && slot.drive) {
    if (slot.drive.smart_healthy === false) {
      bg = '#7f1d1d'; border = '#ef4444';
    } else if (slot.drive.smart_healthy === null) {
      bg = '#78350f'; border = '#f59e0b';
    } else {
      bg = '#14532d'; border = '#22c55e';
    }
  } else if (slot.populated) {
    bg = '#1e3a5f'; border = '#3b82f6';
  }
  if (selected) border = '#fff';

  return (
    <div
      style={{
        ...styles.slot,
        backgroundColor: bg,
        borderColor: border,
        cursor: slot.device ? 'pointer' : 'default',
      }}
      onClick={onClick}
      title={slot.device ? `${slot.device} - Slot ${slot.slot}` : `Slot ${slot.slot} (empty)`}
    >
      <div style={styles.slotNum}>{slot.slot}</div>
      {slot.device && <div style={styles.slotDev}>{slot.device}</div>}
      {slot.drive && (
        <div style={styles.slotTemp}>
          {slot.drive.temperature_c != null ? `${slot.drive.temperature_c}C` : ''}
        </div>
      )}
    </div>
  );
}

function DriveDetailPanel({ device, detail, onClose }) {
  return (
    <div style={styles.overlay} onClick={onClose}>
      <div style={styles.detailPanel} onClick={(e) => e.stopPropagation()}>
        <div style={styles.detailHeader}>
          <h2 style={styles.detailTitle}>/dev/{device}</h2>
          <button onClick={onClose} style={styles.closeBtn}>X</button>
        </div>
        {!detail ? (
          <div style={styles.loading}>Loading SMART data...</div>
        ) : detail.error ? (
          <div style={styles.error}>Error: {detail.error}</div>
        ) : (
          <div style={styles.detailBody}>
            <DetailRow label="Model" value={detail.model} />
            <DetailRow label="Serial" value={detail.serial} />
            <DetailRow label="WWN" value={detail.wwn} />
            <DetailRow label="Firmware" value={detail.firmware} />
            <DetailRow label="Capacity" value={detail.capacity_bytes ? formatBytes(detail.capacity_bytes) : null} />
            <DetailRow label="SMART Healthy" value={detail.smart_healthy == null ? 'Unknown' : detail.smart_healthy ? 'Yes' : 'NO'} />
            <DetailRow label="Temperature" value={detail.temperature_c != null ? `${detail.temperature_c} C` : null} />
            <DetailRow label="Power-On Hours" value={detail.power_on_hours != null ? detail.power_on_hours.toLocaleString() : null} />
            <DetailRow label="Reallocated Sectors" value={detail.reallocated_sectors} />
            <DetailRow label="Pending Sectors" value={detail.pending_sectors} />
            <DetailRow label="Uncorrectable Errors" value={detail.uncorrectable_errors} />
            {detail.wear_leveling_percent != null && (
              <DetailRow label="Wear Leveling" value={`${detail.wear_leveling_percent}%`} />
            )}
            {detail.zfs_pool && <DetailRow label="ZFS Pool" value={detail.zfs_pool} />}
          </div>
        )}
      </div>
    </div>
  );
}

function DetailRow({ label, value }) {
  if (value == null) return null;
  return (
    <div style={styles.detailRow}>
      <span style={styles.detailLabel}>{label}</span>
      <span style={styles.detailValue}>{String(value)}</span>
    </div>
  );
}

function formatBytes(bytes) {
  const units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
  let i = 0;
  let val = bytes;
  while (val >= 1000 && i < units.length - 1) { val /= 1000; i++; }
  return `${val.toFixed(1)} ${units[i]}`;
}

const styles = {
  container: {
    fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace',
    backgroundColor: '#0f172a',
    color: '#e2e8f0',
    minHeight: '100vh',
    padding: '20px',
  },
  header: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: '20px',
    paddingBottom: '16px',
    borderBottom: '1px solid #334155',
  },
  title: { fontSize: '24px', fontWeight: 'bold', color: '#f8fafc' },
  headerRight: { display: 'flex', alignItems: 'center', gap: '12px' },
  badge: {
    padding: '4px 12px',
    borderRadius: '4px',
    fontSize: '12px',
    fontWeight: 'bold',
    color: '#fff',
  },
  timestamp: { fontSize: '12px', color: '#94a3b8' },
  refreshBtn: {
    padding: '6px 14px',
    backgroundColor: '#334155',
    color: '#e2e8f0',
    border: '1px solid #475569',
    borderRadius: '4px',
    cursor: 'pointer',
    fontSize: '13px',
  },
  summaryBar: {
    display: 'flex',
    gap: '16px',
    marginBottom: '24px',
  },
  summaryCard: {
    backgroundColor: '#1e293b',
    padding: '16px 24px',
    borderRadius: '8px',
    border: '1px solid #334155',
    textAlign: 'center',
    flex: 1,
  },
  summaryValue: { fontSize: '28px', fontWeight: 'bold' },
  summaryLabel: { fontSize: '12px', color: '#94a3b8', marginTop: '4px', textTransform: 'uppercase' },
  enclosure: {
    backgroundColor: '#1e293b',
    borderRadius: '8px',
    border: '1px solid #334155',
    marginBottom: '16px',
    overflow: 'hidden',
  },
  enclosureHeader: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    padding: '14px 18px',
    cursor: 'pointer',
    borderBottom: '1px solid #334155',
  },
  enclosureTitle: { fontSize: '16px', fontWeight: 'bold', color: '#f8fafc' },
  enclosureId: { fontSize: '12px', color: '#64748b', marginLeft: '12px' },
  enclosureSg: { fontSize: '12px', color: '#64748b', marginLeft: '8px' },
  slotCount: { fontSize: '14px', color: '#94a3b8' },
  expandIcon: { marginLeft: '8px', fontSize: '10px' },
  slotGrid: {
    display: 'grid',
    gridTemplateColumns: 'repeat(auto-fill, minmax(70px, 1fr))',
    gap: '6px',
    padding: '12px',
  },
  slot: {
    border: '2px solid',
    borderRadius: '6px',
    padding: '6px',
    textAlign: 'center',
    minHeight: '60px',
    display: 'flex',
    flexDirection: 'column',
    justifyContent: 'center',
    transition: 'border-color 0.15s',
  },
  slotNum: { fontSize: '11px', color: '#94a3b8' },
  slotDev: { fontSize: '12px', fontWeight: 'bold', color: '#f8fafc' },
  slotTemp: { fontSize: '10px', color: '#94a3b8' },
  overlay: {
    position: 'fixed',
    top: 0, left: 0, right: 0, bottom: 0,
    backgroundColor: 'rgba(0,0,0,0.6)',
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 1000,
  },
  detailPanel: {
    backgroundColor: '#1e293b',
    border: '1px solid #475569',
    borderRadius: '12px',
    padding: '24px',
    width: '450px',
    maxHeight: '80vh',
    overflowY: 'auto',
  },
  detailHeader: {
    display: 'flex',
    justifyContent: 'space-between',
    alignItems: 'center',
    marginBottom: '20px',
    borderBottom: '1px solid #334155',
    paddingBottom: '12px',
  },
  detailTitle: { fontSize: '18px', color: '#f8fafc' },
  closeBtn: {
    background: 'none',
    border: 'none',
    color: '#94a3b8',
    fontSize: '18px',
    cursor: 'pointer',
  },
  detailBody: {},
  detailRow: {
    display: 'flex',
    justifyContent: 'space-between',
    padding: '8px 0',
    borderBottom: '1px solid #1e293b',
  },
  detailLabel: { color: '#94a3b8', fontSize: '13px' },
  detailValue: { color: '#f8fafc', fontSize: '13px', fontWeight: '500' },
  loading: {
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100vh',
    fontSize: '18px',
    color: '#94a3b8',
  },
  error: {
    display: 'flex',
    justifyContent: 'center',
    alignItems: 'center',
    height: '100vh',
    fontSize: '18px',
    color: '#ef4444',
  },
};

export default App;
