// Shared components & utilities for physics experiments
const { useState, useEffect, useRef, useCallback, useMemo } = React;

// ========== SVG Icon Library ==========
// All line-style icons with consistent stroke-width
const Icons = {
  // App logo
  Atom: () => (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <ellipse cx="12" cy="12" rx="9" ry="3.5" />
      <ellipse cx="12" cy="12" rx="9" ry="3.5" transform="rotate(60 12 12)" />
      <ellipse cx="12" cy="12" rx="9" ry="3.5" transform="rotate(-60 12 12)" />
      <circle cx="12" cy="12" r="2" fill="currentColor" stroke="none" />
    </svg>
  ),
  ArrowLeft: () => (
    <svg viewBox="0 0 24 24">
      <path d="M19 12H5" />
      <path d="M12 19l-7-7 7-7" />
    </svg>
  ),
  ArrowRight: () => (
    <svg viewBox="0 0 24 24">
      <path d="M5 12h14" />
      <path d="M12 5l7 7-7 7" />
    </svg>
  ),
  Play: () => (
    <svg viewBox="0 0 24 24">
      <polygon points="8,5 19,12 8,19" fill="currentColor" stroke="currentColor" strokeWidth="1" />
    </svg>
  ),
  Pause: () => (
    <svg viewBox="0 0 24 24">
      <line x1="8" y1="5" x2="8" y2="19" strokeLinecap="round" />
      <line x1="16" y1="5" x2="16" y2="19" strokeLinecap="round" />
    </svg>
  ),
  Refresh: () => (
    <svg viewBox="0 0 24 24">
      <path d="M23 4v6h-6" />
      <path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10" />
    </svg>
  ),
  Fire: () => (
    <svg viewBox="0 0 24 24">
      <path d="M12 2s4 4 4 8a4 4 0 0 1-8 0c0-2 1-3 1-3s3 2 3 0c0-2-2-3.5 0-5z" />
      <path d="M8 14a4 4 0 0 0 8 0" fill="none" />
      <path d="M12 22a7 7 0 0 0 7-7" />
    </svg>
  ),
  Bell: () => (
    <svg viewBox="0 0 24 24">
      <path d="M18 8a6 6 0 0 0-12 0c0 7-3 9-3 9h18s-3-2-3-9" />
      <path d="M13.73 21a2 2 0 0 1-3.46 0" />
    </svg>
  ),
  BellOff: () => (
    <svg viewBox="0 0 24 24">
      <path d="M18.8 14A8.3 8.3 0 0 0 18 8a6 6 0 0 0-9.3-5M10 2h4" />
      <path d="M2 2l20 20" />
      <path d="M6 8s-3 2-3 9h13" />
      <path d="M13.73 21a2 2 0 0 1-3.46 0" />
    </svg>
  ),
  Check: () => (
    <svg viewBox="0 0 24 24">
      <polyline points="20 6 9 17 4 12" />
    </svg>
  ),
  Shuffle: () => (
    <svg viewBox="0 0 24 24">
      <polyline points="16 3 21 3 21 8" />
      <line x1="4" y1="20" x2="21" y2="3" />
      <polyline points="21 16 21 21 16 21" />
      <line x1="15" y1="15" x2="21" y2="21" />
      <line x1="4" y1="4" x2="9" y2="9" />
    </svg>
  ),
  Grid3x3: () => (
    <svg viewBox="0 0 24 24">
      <rect x="3" y="3" width="7" height="7" rx="1" />
      <rect x="14" y="3" width="7" height="7" rx="1" />
      <rect x="3" y="14" width="7" height="7" rx="1" />
      <rect x="14" y="14" width="7" height="7" rx="1" />
    </svg>
  ),
  X: () => (
    <svg viewBox="0 0 24 24">
      <line x1="18" y1="6" x2="6" y2="18" />
      <line x1="6" y1="6" x2="18" y2="18" />
    </svg>
  ),
  Warning: () => (
    <svg viewBox="0 0 24 24">
      <path d="M10.29 3.86L1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z" />
      <line x1="12" y1="9" x2="12" y2="13" />
      <line x1="12" y1="17" x2="12.01" y2="17" />
    </svg>
  ),

  // Category icons
  CatAcoustics: () => (
    <svg viewBox="0 0 24 24">
      <path d="M2 12h3l5-5v10l-5-5H2z" />
      <path d="M14 8a5 5 0 0 1 0 8" />
      <path d="M17 5a9 9 0 0 1 0 14" />
    </svg>
  ),
  CatOptics: () => (
    <svg viewBox="0 0 24 24">
      <circle cx="12" cy="12" r="3" />
      <path d="M12 2v2" />
      <path d="M12 20v2" />
      <path d="M4.93 4.93l1.41 1.41" />
      <path d="M17.66 17.66l1.41 1.41" />
      <path d="M2 12h2" />
      <path d="M20 12h2" />
      <path d="M6.34 17.66l-1.41 1.41" />
      <path d="M19.07 4.93l-1.41 1.41" />
    </svg>
  ),
  CatThermal: () => (
    <svg viewBox="0 0 24 24">
      <path d="M14 14.76V3.5a2.5 2.5 0 0 0-5 0v11.26a4.5 4.5 0 1 0 5 0z" />
    </svg>
  ),
  CatMechanics: () => (
    <svg viewBox="0 0 24 24">
      <line x1="12" y1="2" x2="12" y2="22" strokeWidth="2" />
      <line x1="2" y1="8" x2="22" y2="8" />
      <line x1="5" y1="8" x2="5" y2="18" />
      <line x1="19" y1="8" x2="19" y2="18" />
      <path d="M3 18h4" />
      <path d="M17 18h4" />
      <circle cx="12" cy="8" r="2" fill="currentColor" stroke="none" />
    </svg>
  ),
  CatElectricity: () => (
    <svg viewBox="0 0 24 24">
      <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
    </svg>
  ),
  CatElectromagnetism: () => (
    <svg viewBox="0 0 24 24">
      <path d="M4 14a8 8 0 0 1 16 0v2a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4v-2z" />
      <path d="M9 7V4h6v3" />
      <line x1="9" y1="18" x2="9" y2="22" />
      <line x1="15" y1="18" x2="15" y2="22" />
    </svg>
  ),
};

// Simple icon component
function Icon({ name, size = 16, color, style }) {
  const Comp = Icons[name];
  if (!Comp) return null;
  return (
    <span className="icon-svg" style={{ width: size, height: size, color, ...style }}>
      <Comp />
    </span>
  );
}

// ========== Category config ==========
const CATEGORIES = {
  acoustics: {
    name: '声学',
    subtitle: 'Acoustics',
    color: '#111114',
    icon: 'CatAcoustics',
    experiments: [
      { id: 'sound-propagation', name: '声音的产生与传播' },
      { id: 'pitch-frequency', name: '音调与频率' },
      { id: 'loudness-amplitude', name: '响度与振幅' },
    ]
  },
  optics: {
    name: '光学',
    subtitle: 'Optics',
    color: '#111114',
    icon: 'CatOptics',
    experiments: [
      { id: 'pinhole', name: '小孔成像' },
      { id: 'reflection', name: '光的反射定律' },
      { id: 'refraction', name: '光的折射' },
      { id: 'convex-lens', name: '凸透镜成像规律' },
      { id: 'dispersion', name: '光的色散' },
    ]
  },
  thermal: {
    name: '热学',
    subtitle: 'Thermal Physics',
    color: '#111114',
    icon: 'CatThermal',
    experiments: [
      { id: 'thermometer', name: '温度计的使用' },
      { id: 'melting', name: '晶体与非晶体熔化' },
      { id: 'boiling', name: '水的沸腾' },
      { id: 'specific-heat', name: '比热容实验' },
    ]
  },
  mechanics: {
    name: '力学',
    subtitle: 'Mechanics',
    color: '#111114',
    icon: 'CatMechanics',
    experiments: [
      { id: 'measurement', name: '长度与质量测量' },
      { id: 'gravity', name: '重力与质量关系' },
      { id: 'friction', name: '滑动摩擦力' },
      { id: 'inertia', name: '阻力对运动的影响' },
      { id: 'buoyancy', name: '浮力与阿基米德原理' },
      { id: 'liquid-pressure', name: '液体压强' },
      { id: 'lever', name: '杠杆平衡条件' },
      { id: 'pulley', name: '滑轮与滑轮组' },
    ]
  },
  electricity: {
    name: '电学',
    subtitle: 'Electricity',
    color: '#111114',
    icon: 'CatElectricity',
    experiments: [
      { id: 'simple-circuit', name: '简单电路' },
      { id: 'ohms-law', name: '欧姆定律 / 伏安法' },
      { id: 'series-parallel', name: '串并联电路规律' },
      { id: 'rheostat', name: '滑动变阻器' },
      { id: 'electric-power', name: '电功率 P=UI' },
    ]
  },
  electromagnetism: {
    name: '电磁学',
    subtitle: 'Electromagnetism',
    color: '#111114',
    icon: 'CatElectromagnetism',
    experiments: [
      { id: 'magnetic-field', name: '磁体与磁感线' },
      { id: 'oersted', name: '奥斯特实验' },
      { id: 'electromagnet', name: '电磁铁' },
      { id: 'motor', name: '磁场对通电导体的作用' },
      { id: 'induction', name: '电磁感应' },
    ]
  },
};

// ========== Floating formula decor for portal ==========
const FORMULAS = [
  'v = s / t',
  'ρ = m / V',
  'G = m g',
  'p = F / S',
  'p = ρ g h',
  'F浮 = ρ液 g V排',
  'F₁L₁ = F₂L₂',
  'W = F s',
  'P = W / t',
  'η = W有 / W总',
  'Q = c m Δt',
  'I = U / R',
  'W = U I t',
  'P = U I',
  'Q = I² R t',
  'v = λ f',
  'F = B I L',
  'ε = N ΔΦ / Δt',
  'f = 1 / T',
  'n = c / v',
  '1/f = 1/u + 1/v',
  'E = m c²',
  'F = k x',
  'W = ½ m v²',
  'Eₚ = m g h',
];

function FormulaBackground() {
  // Pre-compute positions (deterministic)
  const items = useMemo(() => {
    const arr = [];
    for (let i = 0; i < FORMULAS.length; i++) {
      const formula = FORMULAS[i];
      const left = (i * 37 + 13) % 95; // 0-95%
      const top = (i * 23 + 7) % 90; // 0-90%
      const size = 16 + (i % 5) * 4; // 16-32px
      const delay = (i * 0.7) % 12;
      const duration = 14 + (i % 8) * 1.5;
      const rotate = ((i * 13) % 14) - 7; // -7 to 7 deg
      arr.push({ formula, left, top, size, delay, duration, rotate });
    }
    return arr;
  }, []);

  return (
    <div className="formula-bg">
      {items.map((item, i) => (
        <div key={i} className="formula-item"
          style={{
            left: item.left + '%',
            top: item.top + '%',
            fontSize: item.size,
            animationDelay: -item.delay + 's',
            animationDuration: item.duration + 's',
            transform: `rotate(${item.rotate}deg)`,
          }}>
          {item.formula}
        </div>
      ))}
    </div>
  );
}

// ========== Reusable UI Components ==========

function ControlSlider({ label, value, onChange, min, max, step = 1, unit = '' }) {
  return (
    <div className="control-group">
      <div className="control-label">
        <span>{label}</span>
        <span className="control-value">{value}{unit}</span>
      </div>
      <input type="range" min={min} max={max} step={step} value={value}
        onChange={e => onChange(parseFloat(e.target.value))} />
    </div>
  );
}

function ControlToggle({ label, checked, onChange }) {
  return (
    <div className="control-group" style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
      <span style={{ fontSize: 13, color: 'var(--text-secondary)' }}>{label}</span>
      <label className="switch">
        <input type="checkbox" checked={checked} onChange={e => onChange(e.target.checked)} />
        <span className="switch-slider"></span>
      </label>
    </div>
  );
}

function MeterCard({ label, value, unit, sub, full }) {
  return (
    <div className={`meter-card ${full ? 'full' : ''}`}>
      <div className="meter-label">{label}</div>
      <div className="meter-value">{value}<span className="meter-unit">{unit}</span></div>
      {sub && <div className="meter-sub">{sub}</div>}
    </div>
  );
}

function FormulaBox({ expr, subs }) {
  return (
    <div className="formula-box">
      <div className="formula-expr">{expr}</div>
      {subs && subs.map((s, i) => (
        <div key={i} className="formula-sub" dangerouslySetInnerHTML={{ __html: s }} />
      ))}
    </div>
  );
}

function ExplainBox({ title, children }) {
  return (
    <div className="explain-box">
      <h4>{title}</h4>
      {children}
    </div>
  );
}

function PanelTabBar({ tabs, active, onChange }) {
  return (
    <div className="panel-tabs">
      {tabs.map(t => (
        <button key={t.id}
          className={`panel-tab ${active === t.id ? 'active' : ''}`}
          onClick={() => onChange(t.id)}>
          {t.label}
        </button>
      ))}
    </div>
  );
}

// ========== Mini Chart ==========
function MiniChart({ data, xLabel, yLabel, color, height = 160, yMin, yMax }) {
  const ref = useRef(null);
  const chartRef = useRef(null);

  useEffect(() => {
    if (!ref.current) return;
    if (!chartRef.current) {
      chartRef.current = echarts.init(ref.current);
    }
    const chart = chartRef.current;
    const lineColor = color || '#111114';
    chart.setOption({
      grid: { left: 40, right: 12, top: 12, bottom: 24 },
      xAxis: {
        type: 'category',
        name: xLabel || '',
        nameLocation: 'end',
        nameTextStyle: { fontSize: 10, color: '#8a94a6' },
        data: data.map((_, i) => i),
        axisLine: { lineStyle: { color: '#e4e7ec' } },
        axisLabel: { color: '#8a94a6', fontSize: 10 },
        splitLine: { show: false },
        axisTick: { show: false },
      },
      yAxis: {
        type: 'value',
        name: yLabel || '',
        nameTextStyle: { fontSize: 10, color: '#8a94a6' },
        min: yMin,
        max: yMax,
        axisLine: { show: false },
        axisLabel: { color: '#8a94a6', fontSize: 10 },
        splitLine: { lineStyle: { color: '#eef0f3', type: 'dashed' } },
        axisTick: { show: false },
      },
      series: [{
        type: 'line',
        data: data,
        showSymbol: false,
        smooth: true,
        lineStyle: { color: lineColor, width: 2 },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: lineColor + '33' },
            { offset: 1, color: lineColor + '08' },
          ])
        },
      }],
      tooltip: {
        trigger: 'axis',
        backgroundColor: '#fff',
        borderColor: '#e4e7ec',
        borderWidth: 1,
        textStyle: { color: '#1a1d24', fontSize: 12 },
        shadowBlur: 8,
        shadowColor: 'rgba(0,0,0,0.08)',
      }
    });
    return () => { chart.resize(); };
  }, [data, color, xLabel, yLabel, yMin, yMax]);

  useEffect(() => {
    const handle = () => chartRef.current && chartRef.current.resize();
    window.addEventListener('resize', handle);
    return () => window.removeEventListener('resize', handle);
  }, []);

  return <div ref={ref} style={{ width: '100%', height }} />;
}

// Experiment shell that wraps each experiment with standard panel
function ExperimentShell({ category, name, children, panelTabs, panelContent, catColor }) {
  const [activeTab, setActiveTab] = useState(panelTabs[0]?.id || 'controls');

  return (
    <div className="experiment">
      <div className="exp-main" style={{ ['--cat-color']: catColor }}>
        <div className="exp-header">
          <span className="exp-category-tag" style={{ background: catColor, color: '#fff' }}>{category}</span>
          <span className="exp-name">{name}</span>
        </div>
        <div className="sim-area">
          {children}
        </div>
      </div>
      <div className="exp-panel">
        {panelTabs.length > 1 && (
          <div className="panel-tabs">
            {panelTabs.map(t => (
              <button key={t.id}
                className={`panel-tab ${activeTab === t.id ? 'active' : ''}`}
                onClick={() => setActiveTab(t.id)}>
                {t.label}
              </button>
            ))}
          </div>
        )}
        <div className="panel-content">
          {panelContent(activeTab)}
        </div>
      </div>
    </div>
  );
}

// ========== Export to window ==========
Object.assign(window, {
  CATEGORIES,
  Icons,
  Icon,
  FormulaBackground,
  useState, useEffect, useRef, useCallback, useMemo,
  ControlSlider, ControlToggle, MeterCard, FormulaBox, ExplainBox, PanelTabBar,
  MiniChart, ExperimentShell,
});
