import { h } from 'preact';
import { useState } from 'preact/hooks';

interface Props {
  initialSection?: string;
  onClose: () => void;
}

// ── SVG Diagrams ─────────────────────────────────────────────────────────────

function DiagramViewMode() {
  return (
    <svg viewBox="0 0 580 230" class="help-diagram" role="img" aria-label="View mode layout diagram">
      {/* outer bg */}
      <rect width="580" height="230" rx="8" fill="#0f1117" />

      {/* toolbar */}
      <rect width="580" height="38" rx="0" fill="#1a1f2e" />
      <rect y="37" width="580" height="1" fill="#2d3748" />
      <text x="12" y="24" fill="#4a9eff" font-size="12" font-weight="bold">uopi</text>
      <text x="54" y="24" fill="#e2e8f0" font-size="11">Control Room</text>
      {/* live chip */}
      <rect x="488" y="10" width="80" height="18" rx="9" fill="#1e3a1e" />
      <circle cx="500" cy="19" r="4" fill="#22c55e" />
      <text x="509" y="23" fill="#22c55e" font-size="9">live</text>
      <rect x="454" y="10" width="30" height="18" rx="4" fill="#2d3748" />
      <text x="469" y="23" fill="#e2e8f0" font-size="9" text-anchor="middle">Edit</text>

      {/* interface list panel */}
      <rect x="0" y="38" width="148" height="192" fill="#151b2e" />
      <rect x="0" y="38" width="148" height="192" fill="none" stroke="#2d3748" />
      <text x="10" y="57" fill="#64748b" font-size="8">INTERFACES</text>
      <rect x="6" y="63" width="136" height="22" rx="4" fill="#2d3748" />
      <text x="14" y="79" fill="#4a9eff" font-size="10">Control Room</text>
      <rect x="6" y="89" width="136" height="22" rx="4" fill="none" />
      <text x="14" y="105" fill="#94a3b8" font-size="10">Vacuum System</text>
      <rect x="6" y="115" width="136" height="22" rx="4" fill="none" />
      <text x="14" y="131" fill="#94a3b8" font-size="10">RF Status</text>

      {/* canvas area */}
      <rect x="148" y="38" width="432" height="192" fill="#0f1117" />

      {/* gauge widget */}
      <rect x="162" y="52" width="108" height="88" rx="4" fill="#1a1f2e" stroke="#2d3748" />
      <text x="216" y="69" fill="#64748b" font-size="8" text-anchor="middle">Temperature</text>
      <circle cx="216" cy="108" r="26" fill="none" stroke="#2d3748" stroke-width="5" />
      <circle cx="216" cy="108" r="26" fill="none" stroke="#4a9eff" stroke-width="5"
        stroke-dasharray="55 108" stroke-dashoffset="27" stroke-linecap="round" />
      <text x="216" y="113" fill="#e2e8f0" font-size="10" text-anchor="middle" font-weight="bold">67°C</text>

      {/* LED */}
      <rect x="282" y="52" width="90" height="38" rx="4" fill="#1a1f2e" stroke="#2d3748" />
      <circle cx="300" cy="71" r="8" fill="#22c55e" />
      <text x="314" y="75" fill="#94a3b8" font-size="9">Beam ON</text>

      {/* text view */}
      <rect x="282" y="98" width="90" height="30" rx="4" fill="#1a1f2e" stroke="#2d3748" />
      <text x="327" y="118" fill="#e2e8f0" font-size="12" text-anchor="middle" font-weight="bold">1.23 mA</text>

      {/* bar */}
      <rect x="162" y="150" width="108" height="68" rx="4" fill="#1a1f2e" stroke="#2d3748" />
      <text x="216" y="167" fill="#64748b" font-size="8" text-anchor="middle">Pressure</text>
      <rect x="172" y="174" width="88" height="14" rx="3" fill="#2d3748" />
      <rect x="172" y="174" width="57" height="14" rx="3" fill="#4a9eff" />
      <text x="216" y="204" fill="#94a3b8" font-size="8" text-anchor="middle">65 %</text>

      {/* plot */}
      <rect x="386" y="52" width="182" height="166" rx="4" fill="#1a1f2e" stroke="#2d3748" />
      <text x="477" y="69" fill="#64748b" font-size="8" text-anchor="middle">Beam Current</text>
      <polyline points="398,195 418,180 438,170 458,175 478,160 498,155 518,158 548,145"
        fill="none" stroke="#4a9eff" stroke-width="1.5" />
      <line x1="398" y1="75" x2="398" y2="200" stroke="#2d3748" stroke-width="1" />
      <line x1="398" y1="200" x2="560" y2="200" stroke="#2d3748" stroke-width="1" />

      {/* Annotations */}
      {/* arrow to interface list */}
      <line x1="74" y1="218" x2="74" y2="170" stroke="#fbbf24" stroke-width="1.5" marker-end="url(#arr)" />
      <text x="74" y="228" fill="#fbbf24" font-size="9" text-anchor="middle">① Interface list</text>

      {/* arrow to canvas */}
      <line x1="360" y1="218" x2="360" y2="180" stroke="#fbbf24" stroke-width="1.5" marker-end="url(#arr)" />
      <text x="360" y="228" fill="#fbbf24" font-size="9" text-anchor="middle">② Live canvas</text>

      <defs>
        <marker id="arr" markerWidth="6" markerHeight="6" refX="3" refY="3" orient="auto">
          <path d="M0,0 L6,3 L0,6 Z" fill="#fbbf24" />
        </marker>
      </defs>
    </svg>
  );
}

function DiagramEditMode() {
  return (
    <svg viewBox="0 0 580 230" class="help-diagram" role="img" aria-label="Edit mode layout diagram">
      <rect width="580" height="230" rx="8" fill="#0f1117" />
      {/* toolbar */}
      <rect width="580" height="38" fill="#1a1f2e" />
      <rect y="37" width="580" height="1" fill="#2d3748" />
      <text x="12" y="24" fill="#4a9eff" font-size="12" font-weight="bold">uopi</text>
      <rect x="50" y="12" width="26" height="14" rx="3" fill="#1e40af" />
      <text x="63" y="23" fill="#93c5fd" font-size="8" text-anchor="middle">Edit</text>
      <text x="86" y="24" fill="#e2e8f0" font-size="11">My Panel</text>
      {/* toolbar buttons */}
      <rect x="350" y="11" width="28" height="16" rx="3" fill="#2d3748" />
      <text x="364" y="23" fill="#e2e8f0" font-size="9" text-anchor="middle">↩</text>
      <rect x="382" y="11" width="28" height="16" rx="3" fill="#2d3748" />
      <text x="396" y="23" fill="#e2e8f0" font-size="9" text-anchor="middle">↪</text>
      <rect x="480" y="11" width="36" height="16" rx="3" fill="#2563eb" />
      <text x="498" y="23" fill="#fff" font-size="9" text-anchor="middle">Save</text>
      <rect x="520" y="11" width="40" height="16" rx="3" fill="#2d3748" />
      <text x="540" y="23" fill="#e2e8f0" font-size="9" text-anchor="middle">✕ Close</text>

      {/* signal tree */}
      <rect x="0" y="38" width="140" height="192" fill="#151b2e" />
      <rect x="0" y="38" width="140" height="192" fill="none" stroke="#2d3748" />
      <text x="10" y="57" fill="#64748b" font-size="8">SIGNALS</text>
      <rect x="4" y="63" width="132" height="20" rx="3" fill="#1a2236" stroke="#2d3748" />
      <text x="10" y="78" fill="#64748b" font-size="9">Filter signals…</text>
      <text x="10" y="100" fill="#94a3b8" font-size="9">▾ epics</text>
      <text x="20" y="115" fill="#cbd5e1" font-size="9">  CURRENT</text>
      <text x="20" y="129" fill="#cbd5e1" font-size="9">  PRESSURE</text>
      <text x="10" y="148" fill="#94a3b8" font-size="9">▾ stub</text>
      <text x="20" y="163" fill="#cbd5e1" font-size="9">  sine_1hz</text>
      <text x="20" y="177" fill="#cbd5e1" font-size="9">  ramp_10s</text>

      {/* canvas */}
      <rect x="140" y="38" width="288" height="192" fill="#0f1117" />
      {/* grid dots */}
      {[0,1,2,3,4,5,6,7,8].map(col =>
        [0,1,2,3,4,5,6].map(row => (
          <circle key={`${col}-${row}`} cx={140 + 10 + col * 30} cy={38 + 10 + row * 26}
            r="0.8" fill="#2d3748" />
        ))
      )}
      {/* selected widget with handles */}
      <rect x="185" y="75" width="120" height="60" rx="4" fill="#1a1f2e" stroke="#4a9eff" stroke-width="1.5" />
      <text x="245" y="110" fill="#e2e8f0" font-size="11" text-anchor="middle" font-weight="bold">42.3°C</text>
      <text x="245" y="90" fill="#64748b" font-size="8" text-anchor="middle">Temperature</text>
      {/* resize handles */}
      <rect x="182" y="72" width="8" height="8" rx="1" fill="#4a9eff" />
      <rect x="301" y="72" width="8" height="8" rx="1" fill="#4a9eff" />
      <rect x="182" y="131" width="8" height="8" rx="1" fill="#4a9eff" />
      <rect x="301" y="131" width="8" height="8" rx="1" fill="#4a9eff" />
      {/* another widget */}
      <rect x="220" y="155" width="80" height="30" rx="4" fill="#1a1f2e" stroke="#2d3748" />
      <rect x="230" y="163" width="60" height="10" rx="2" fill="#2d3748" />
      <rect x="230" y="163" width="38" height="10" rx="2" fill="#22c55e" />

      {/* properties pane */}
      <rect x="428" y="38" width="152" height="192" fill="#1a1f2e" />
      <rect x="428" y="38" width="152" height="192" fill="none" stroke="#2d3748" />
      <text x="438" y="56" fill="#64748b" font-size="8">PROPERTIES</text>
      <line x1="428" y1="61" x2="580" y2="61" stroke="#2d3748" />
      <text x="438" y="78" fill="#94a3b8" font-size="8">Signal</text>
      <rect x="438" y="82" width="132" height="16" rx="3" fill="#1a2236" stroke="#2d3748" />
      <text x="444" y="94" fill="#e2e8f0" font-size="9">TEMPERATURE</text>
      <text x="438" y="112" fill="#94a3b8" font-size="8">X</text>
      <rect x="438" y="116" width="58" height="14" rx="3" fill="#1a2236" stroke="#2d3748" />
      <text x="444" y="127" fill="#e2e8f0" font-size="9">185</text>
      <text x="504" y="112" fill="#94a3b8" font-size="8">Y</text>
      <rect x="504" y="116" width="58" height="14" rx="3" fill="#1a2236" stroke="#2d3748" />
      <text x="510" y="127" fill="#e2e8f0" font-size="9">75</text>
      <text x="438" y="145" fill="#94a3b8" font-size="8">Width</text>
      <rect x="438" y="149" width="58" height="14" rx="3" fill="#1a2236" stroke="#2d3748" />
      <text x="444" y="160" fill="#e2e8f0" font-size="9">120</text>
      <text x="504" y="145" fill="#94a3b8" font-size="8">Height</text>
      <rect x="504" y="149" width="58" height="14" rx="3" fill="#1a2236" stroke="#2d3748" />
      <text x="510" y="160" fill="#e2e8f0" font-size="9">60</text>

      {/* Annotations */}
      <text x="70" y="218" fill="#fbbf24" font-size="9" text-anchor="middle">① Signal tree</text>
      <text x="284" y="218" fill="#fbbf24" font-size="9" text-anchor="middle">② Canvas</text>
      <text x="504" y="218" fill="#fbbf24" font-size="9" text-anchor="middle">③ Properties</text>
    </svg>
  );
}

function DiagramDragDrop() {
  return (
    <svg viewBox="0 0 580 200" class="help-diagram" role="img" aria-label="Drag and drop workflow">
      <rect width="580" height="200" rx="8" fill="#0f1117" />

      {/* Step 1 */}
      <rect x="10" y="10" width="160" height="180" rx="6" fill="#151b2e" stroke="#2d3748" />
      <text x="90" y="30" fill="#64748b" font-size="9" text-anchor="middle">① SIGNAL TREE</text>
      <text x="20" y="55" fill="#94a3b8" font-size="9">▾ epics</text>
      <rect x="16" y="62" width="148" height="22" rx="4" fill="#1e3a5f" stroke="#4a9eff" />
      <text x="26" y="78" fill="#4a9eff" font-size="10">TEMPERATURE</text>
      <text x="26" y="78" fill="none" stroke="#4a9eff" stroke-width="0" />
      <text x="20" y="100" fill="#94a3b8" font-size="9">  PRESSURE</text>
      <text x="20" y="115" fill="#94a3b8" font-size="9">  CURRENT</text>
      {/* drag cursor hint */}
      <text x="90" y="175" fill="#64748b" font-size="8" text-anchor="middle">drag signal →</text>

      {/* Arrow 1→2 */}
      <line x1="178" y1="100" x2="218" y2="100" stroke="#fbbf24" stroke-width="2"
        marker-end="url(#arr2)" stroke-dasharray="4 2" />

      {/* Step 2 */}
      <rect x="220" y="10" width="160" height="180" rx="6" fill="#0f1117" stroke="#4a9eff" stroke-dasharray="4 3" />
      <text x="300" y="30" fill="#64748b" font-size="9" text-anchor="middle">② DROP ON CANVAS</text>
      {/* ghost drag indicator */}
      <rect x="235" y="75" width="130" height="50" rx="4" fill="#1e3a5f" stroke="#4a9eff" stroke-width="1.5" stroke-dasharray="4 2" />
      <text x="300" y="105" fill="#4a9eff" font-size="10" text-anchor="middle">TEMPERATURE</text>
      <text x="300" y="175" fill="#64748b" font-size="8" text-anchor="middle">drop here</text>

      {/* Arrow 2→3 */}
      <line x1="388" y1="100" x2="408" y2="100" stroke="#fbbf24" stroke-width="2"
        marker-end="url(#arr2)" stroke-dasharray="4 2" />

      {/* Step 3: widget picker */}
      <rect x="410" y="10" width="160" height="180" rx="6" fill="#1a1f2e" stroke="#2d3748" />
      <text x="490" y="30" fill="#64748b" font-size="9" text-anchor="middle">③ PICK WIDGET TYPE</text>
      <rect x="420" y="40" width="140" height="24" rx="4" fill="#2d3748" />
      <text x="490" y="57" fill="#e2e8f0" font-size="10" text-anchor="middle">Gauge</text>
      <rect x="420" y="68" width="140" height="24" rx="4" fill="#2d3748" />
      <text x="490" y="85" fill="#e2e8f0" font-size="10" text-anchor="middle">Bar (horizontal)</text>
      <rect x="420" y="96" width="140" height="24" rx="4" fill="#2d3748" />
      <text x="490" y="113" fill="#e2e8f0" font-size="10" text-anchor="middle">Text View</text>
      <rect x="420" y="124" width="140" height="24" rx="4" fill="#1e40af" />
      <text x="490" y="141" fill="#93c5fd" font-size="10" text-anchor="middle">Plot</text>
      <rect x="420" y="152" width="140" height="24" rx="4" fill="#2d3748" />
      <text x="490" y="169" fill="#e2e8f0" font-size="10" text-anchor="middle">LED</text>

      <defs>
        <marker id="arr2" markerWidth="6" markerHeight="6" refX="5" refY="3" orient="auto">
          <path d="M0,0 L6,3 L0,6 Z" fill="#fbbf24" />
        </marker>
      </defs>
    </svg>
  );
}

function DiagramWidgets() {
  return (
    <svg viewBox="0 0 580 220" class="help-diagram" role="img" aria-label="Widget types overview">
      <rect width="580" height="220" rx="8" fill="#0f1117" />
      {/* Text View */}
      <g>
        <rect x="20" y="20" width="110" height="56" rx="4" fill="#1a1f2e" stroke="#2d3748" />
        <text x="75" y="50" fill="#e2e8f0" font-size="14" text-anchor="middle" font-weight="bold">42.7 °C</text>
        <text x="75" y="66" fill="#64748b" font-size="8" text-anchor="middle">Text View</text>
      </g>
      {/* Gauge */}
      <g>
        <rect x="150" y="20" width="110" height="90" rx="4" fill="#1a1f2e" stroke="#2d3748" />
        <circle cx="205" cy="82" r="26" fill="none" stroke="#2d3748" stroke-width="5" />
        <circle cx="205" cy="82" r="26" fill="none" stroke="#4a9eff" stroke-width="5"
          stroke-dasharray="52 108" stroke-dashoffset="27" stroke-linecap="round" />
        <text x="205" y="87" fill="#e2e8f0" font-size="10" text-anchor="middle">67%</text>
        <text x="205" y="34" fill="#64748b" font-size="8" text-anchor="middle">Gauge</text>
      </g>
      {/* Bar H */}
      <g>
        <rect x="280" y="20" width="130" height="56" rx="4" fill="#1a1f2e" stroke="#2d3748" />
        <text x="345" y="36" fill="#64748b" font-size="8" text-anchor="middle">Bar (horiz.)</text>
        <rect x="290" y="44" width="110" height="18" rx="3" fill="#2d3748" />
        <rect x="290" y="44" width="71" height="18" rx="3" fill="#4a9eff" />
        <text x="345" y="66" fill="#94a3b8" font-size="8" text-anchor="middle">65 %</text>
      </g>
      {/* LED */}
      <g>
        <rect x="430" y="20" width="130" height="56" rx="4" fill="#1a1f2e" stroke="#2d3748" />
        <circle cx="460" cy="48" r="12" fill="#22c55e" />
        <text x="477" y="46" fill="#94a3b8" font-size="9">Beam ON</text>
        <text x="477" y="59" fill="#64748b" font-size="8">LED</text>
      </g>
      {/* Plot */}
      <g>
        <rect x="20" y="130" width="260" height="80" rx="4" fill="#1a1f2e" stroke="#2d3748" />
        <text x="150" y="148" fill="#64748b" font-size="8" text-anchor="middle">Time-series Plot</text>
        <line x1="30" y1="152" x2="30" y2="200" stroke="#2d3748" />
        <line x1="30" y1="200" x2="270" y2="200" stroke="#2d3748" />
        <polyline points="32,195 55,182 78,175 101,180 124,165 147,160 170,163 193,150 216,155 239,142 262,138"
          fill="none" stroke="#4a9eff" stroke-width="1.5" />
        <polyline points="32,190 55,188 78,192 101,185 124,179 147,183 170,175 193,170 216,175 239,168 262,162"
          fill="none" stroke="#22c55e" stroke-width="1.5" />
      </g>
      {/* Set Value */}
      <g>
        <rect x="300" y="130" width="130" height="80" rx="4" fill="#1a1f2e" stroke="#2d3748" />
        <text x="365" y="150" fill="#64748b" font-size="8" text-anchor="middle">Set-point Control</text>
        <rect x="310" y="157" width="110" height="22" rx="4" fill="#1a2236" stroke="#2d3748" />
        <text x="365" y="173" fill="#e2e8f0" font-size="11" text-anchor="middle">100.0</text>
        <rect x="320" y="185" width="90" height="18" rx="4" fill="#2563eb" />
        <text x="365" y="198" fill="#fff" font-size="9" text-anchor="middle">Set</text>
      </g>
      {/* Button */}
      <g>
        <rect x="450" y="130" width="110" height="80" rx="4" fill="#1a1f2e" stroke="#2d3748" />
        <text x="505" y="150" fill="#64748b" font-size="8" text-anchor="middle">Button</text>
        <rect x="460" y="158" width="90" height="30" rx="6" fill="#2563eb" />
        <text x="505" y="178" fill="#fff" font-size="11" text-anchor="middle">RESET</text>
      </g>
    </svg>
  );
}

function DiagramHistory() {
  return (
    <svg viewBox="0 0 580 130" class="help-diagram" role="img" aria-label="Historical data toolbar">
      <rect width="580" height="130" rx="8" fill="#0f1117" />

      {/* toolbar */}
      <rect width="580" height="44" fill="#1a1f2e" />
      <rect y="43" width="580" height="1" fill="#2d3748" />

      {/* Live button (inactive) */}
      <rect x="14" y="12" width="50" height="20" rx="10" fill="#2d3748" />
      <circle cx="26" cy="22" r="4" fill="#64748b" />
      <text x="42" y="27" fill="#94a3b8" font-size="9" text-anchor="middle">Live</text>

      {/* start input */}
      <rect x="72" y="12" width="148" height="20" rx="4" fill="#1a2236" stroke="#2d3748" />
      <text x="80" y="26" fill="#e2e8f0" font-size="9">2026-01-15  09:00</text>

      <text x="228" y="26" fill="#475569" font-size="11" text-anchor="middle">→</text>

      {/* end input */}
      <rect x="242" y="12" width="148" height="20" rx="4" fill="#1a2236" stroke="#63b3ed" />
      <text x="250" y="26" fill="#e2e8f0" font-size="9">2026-01-15  10:00</text>

      {/* Load button */}
      <rect x="398" y="12" width="44" height="20" rx="4" fill="#2d3748" />
      <text x="420" y="26" fill="#e2e8f0" font-size="9" text-anchor="middle">Load</text>

      {/* Plot showing historical data */}
      <rect x="10" y="54" width="560" height="66" rx="4" fill="#1a1f2e" stroke="#2d3748" />
      <text x="290" y="70" fill="#64748b" font-size="8" text-anchor="middle">Loaded 3 600 historical points · 09:00 → 10:00</text>
      <line x1="22" y1="75" x2="22" y2="112" stroke="#2d3748" />
      <line x1="22" y1="112" x2="560" y2="112" stroke="#2d3748" />
      <polyline
        points="24,108 70,100 116,92 162,96 208,85 254,80 300,84 346,75 392,78 438,70 484,73 530,65 558,62"
        fill="none" stroke="#4a9eff" stroke-width="1.5" />

      {/* annotations */}
      <line x1="39" y1="54" x2="39" y2="44" stroke="#fbbf24" stroke-width="1.5" />
      <text x="39" y="122" fill="#fbbf24" font-size="8" text-anchor="middle">① Live</text>
      <line x1="146" y1="54" x2="146" y2="44" stroke="#fbbf24" stroke-width="1.5" />
      <text x="146" y="122" fill="#fbbf24" font-size="8" text-anchor="middle">② Start time</text>
      <line x1="316" y1="54" x2="316" y2="44" stroke="#fbbf24" stroke-width="1.5" />
      <text x="316" y="122" fill="#fbbf24" font-size="8" text-anchor="middle">③ End time</text>
      <line x1="420" y1="54" x2="420" y2="44" stroke="#fbbf24" stroke-width="1.5" />
      <text x="420" y="122" fill="#fbbf24" font-size="8" text-anchor="middle">④ Load</text>
    </svg>
  );
}

function DiagramSignalTree() {
  return (
    <svg viewBox="0 0 280 280" class="help-diagram help-diagram-narrow" role="img" aria-label="Signal tree">
      <rect width="280" height="280" rx="8" fill="#151b2e" />

      {/* header */}
      <text x="14" y="22" fill="#e2e8f0" font-size="11" font-weight="bold">Signals</text>
      <rect x="240" y="8" width="28" height="20" rx="4" fill="#2d3748" />
      <text x="254" y="23" fill="#e2e8f0" font-size="10" text-anchor="middle">◀</text>
      <line x1="0" y1="32" x2="280" y2="32" stroke="#2d3748" />

      {/* search */}
      <rect x="8" y="38" width="194" height="20" rx="4" fill="#1a2236" stroke="#2d3748" />
      <text x="16" y="53" fill="#64748b" font-size="9">Filter signals…</text>
      <rect x="208" y="38" width="64" height="20" rx="4" fill="#2d3748" />
      <text x="240" y="53" fill="#e2e8f0" font-size="8" text-anchor="middle">🔍 CF</text>
      <line x1="0" y1="63" x2="280" y2="63" stroke="#2d3748" />

      {/* toolbar */}
      <rect x="8" y="68" width="80" height="18" rx="4" fill="#2d3748" />
      <text x="48" y="81" fill="#e2e8f0" font-size="8" text-anchor="middle">+ Synthetic</text>
      <rect x="94" y="68" width="38" height="18" rx="4" fill="#2d3748" />
      <text x="113" y="81" fill="#e2e8f0" font-size="8" text-anchor="middle">CSV</text>
      <rect x="138" y="68" width="28" height="18" rx="4" fill="#2d3748" />
      <text x="152" y="81" fill="#e2e8f0" font-size="9" text-anchor="middle">↺</text>
      <line x1="0" y1="90" x2="280" y2="90" stroke="#2d3748" />

      {/* epics group */}
      <text x="10" y="110" fill="#94a3b8" font-size="10">▾ epics</text>
      <rect x="250" y="100" width="22" height="16" rx="3" fill="none" />
      <text x="261" y="112" fill="#64748b" font-size="9" text-anchor="middle">+</text>
      <rect x="8" y="118" width="264" height="20" rx="3" fill="none" />
      <text x="22" y="133" fill="#cbd5e1" font-size="10" style="cursor:grab">TEMPERATURE</text>
      <text x="22" y="152" fill="#cbd5e1" font-size="10">PRESSURE</text>
      <text x="22" y="170" fill="#cbd5e1" font-size="10">BEAM_CURRENT</text>

      {/* stub group */}
      <line x1="0" y1="180" x2="280" y2="180" stroke="#2d3748" stroke-dasharray="2 2" />
      <text x="10" y="198" fill="#94a3b8" font-size="10">▾ stub</text>
      <text x="22" y="217" fill="#cbd5e1" font-size="10">sine_1hz</text>
      <text x="22" y="235" fill="#cbd5e1" font-size="10">ramp_10s</text>
      <text x="22" y="253" fill="#94a3b8" font-size="9" font-style="italic">my_custom_pv</text>
      <rect x="250" y="243" width="22" height="14" rx="3" fill="none" />
      <text x="261" y="254" fill="#ef4444" font-size="9" text-anchor="middle">✕</text>

      {/* label custom */}
      <rect x="100" y="246" width="52" height="12" rx="3" fill="#2d3748" />
      <text x="126" y="256" fill="#fbbf24" font-size="7" text-anchor="middle">custom</text>
    </svg>
  );
}

// ── Section content ───────────────────────────────────────────────────────────

const SECTIONS = [
  { id: 'start',     label: 'Getting Started' },
  { id: 'view',      label: 'View Mode' },
  { id: 'edit',      label: 'Edit Mode' },
  { id: 'widgets',   label: 'Widgets' },
  { id: 'signals',   label: 'Signals' },
  { id: 'history',   label: 'Historical Data' },
  { id: 'shortcuts', label: 'Keyboard Shortcuts' },
];

function SectionStart() {
  return (
    <div>
      <p class="help-lead">
        <strong>uopi</strong> is a web-based HMI for monitoring and controlling EPICS-based scientific and industrial systems.
        It runs as a single binary — open a browser, no installation required.
      </p>

      <h3 class="help-h3">How it works</h3>
      <ol class="help-list">
        <li>The server connects to your control system (EPICS, synthetic signals).</li>
        <li>Open <code>http://&lt;host&gt;:8080</code> in any browser.</li>
        <li>Pick an HMI panel from the left sidebar to view live data.</li>
        <li>Switch to <strong>Edit mode</strong> to build or modify panels.</li>
      </ol>

      <h3 class="help-h3">Two modes</h3>
      <div class="help-cards">
        <div class="help-card">
          <div class="help-card-title">👁 View Mode</div>
          <p>Monitor live signals in read-only HMI panels. Right-click any widget for signal info or to export data as CSV.</p>
        </div>
        <div class="help-card">
          <div class="help-card-title">✏ Edit Mode</div>
          <p>Drag signals from the tree onto the canvas, resize and configure widgets, then save your panel to the server.</p>
        </div>
      </div>

      <h3 class="help-h3">Quick navigation</h3>
      <ul class="help-list">
        <li>Click an interface in the left list to open it in view mode.</li>
        <li>Click <strong>Edit</strong> (top-right) to switch to the editor.</li>
        <li>Click <strong>✕ Close</strong> in Edit mode to return to View mode.</li>
        <li>Press <kbd>?</kbd> anywhere to open this help.</li>
      </ul>
    </div>
  );
}

function SectionView() {
  return (
    <div>
      <p class="help-lead">
        View mode displays a live HMI panel. Widget values update in real time via WebSocket.
      </p>

      <DiagramViewMode />
      <p class="help-caption">View mode layout: ① interface list · ② live canvas · WebSocket status top-right.</p>

      <h3 class="help-h3">Interface list</h3>
      <ul class="help-list">
        <li>Click any panel name to load it on the canvas.</li>
        <li>Use the action buttons (edit ✎, clone ⧉, delete ✕) that appear on hover.</li>
        <li>Collapse the list by clicking the <strong>◀</strong> button at the top.</li>
      </ul>

      <h3 class="help-h3">Context menu</h3>
      <p>Right-click any widget to:</p>
      <ul class="help-list">
        <li>View the signal name and current value.</li>
        <li>Copy the signal name to the clipboard.</li>
        <li>Export the last 1 000 samples as a CSV file.</li>
      </ul>

      <h3 class="help-h3">Connection status</h3>
      <p>
        The coloured chip in the top-right shows the WebSocket connection state.
        A red <em>"disconnected"</em> banner appears at the top while reconnecting — live values will resume automatically.
      </p>
    </div>
  );
}

function SectionEdit() {
  return (
    <div>
      <p class="help-lead">
        Edit mode gives you a drag-and-drop canvas, a signal tree on the left, and a properties pane on the right.
      </p>

      <DiagramEditMode />
      <p class="help-caption">Edit mode layout: ① signal tree · ② canvas with snap grid · ③ properties pane.</p>

      <h3 class="help-h3">Adding widgets</h3>
      <DiagramDragDrop />
      <p class="help-caption">Drag a signal from the tree → drop on canvas → choose a widget type.</p>

      <h3 class="help-h3">Selecting and moving</h3>
      <ul class="help-list">
        <li>Click a widget to select it — resize handles appear at the corners and edges.</li>
        <li>Drag the widget body to move it; drag a handle to resize.</li>
        <li><kbd>Ctrl</kbd>+click to add/remove widgets from the selection.</li>
        <li>Drag on empty canvas to rubber-band select multiple widgets.</li>
        <li>Arrow keys nudge the selection by 1 px (or grid size with <kbd>Shift</kbd>).</li>
      </ul>

      <h3 class="help-h3">Align &amp; distribute</h3>
      <p>When 2+ widgets are selected the alignment toolbar appears. Buttons align edges or centres; with 3+ selected you can distribute spacing evenly.</p>

      <h3 class="help-h3">Saving</h3>
      <ul class="help-list">
        <li><strong>Save</strong> — stores the panel on the server (XML). A <span style="color:#f59e0b">●</span> indicates unsaved changes.</li>
        <li><strong>Export</strong> — downloads the XML file locally.</li>
        <li><strong>Import</strong> — loads an XML file from disk (replaces the current canvas).</li>
      </ul>
    </div>
  );
}

function SectionWidgets() {
  return (
    <div>
      <p class="help-lead">
        Each widget is configured in the Properties pane on the right.
        The available options depend on the widget type.
      </p>

      <DiagramWidgets />
      <p class="help-caption">Widget type overview — drag a signal from the tree to place one.</p>

      <div class="help-widget-table">
        {[
          { type: 'Text View',    desc: 'Shows the current numeric or string value. Supports alarm colouring.' },
          { type: 'Gauge',        desc: 'Circular arc gauge with configurable range and colour zones.' },
          { type: 'Bar (H / V)',  desc: 'Horizontal or vertical filled bar, great for percentages or levels.' },
          { type: 'LED',          desc: 'Coloured indicator. Turns green/red based on a threshold or enum value.' },
          { type: 'Multi-LED',    desc: 'Bitset indicator — shows individual bits of an integer signal as LEDs.' },
          { type: 'Set Value',    desc: 'Text input that writes a value back to a writable signal on Enter or click.' },
          { type: 'Button',       desc: 'Sends a fixed value to a signal when clicked.' },
          { type: 'Plot',         desc: 'Multi-signal chart. Supports time-series (uPlot), FFT, waterfall, histogram, bar chart, logic analyser.' },
          { type: 'Text Label',   desc: 'Static annotation text — no signal required.' },
          { type: 'Image',        desc: 'Static image loaded from a URL.' },
          { type: 'Link',         desc: 'Navigates to another interface when clicked.' },
        ].map(w => (
          <div key={w.type} class="help-widget-row">
            <span class="help-widget-name">{w.type}</span>
            <span class="help-widget-desc">{w.desc}</span>
          </div>
        ))}
      </div>

      <h3 class="help-h3">Plot widget details</h3>
      <ul class="help-list">
        <li>Add multiple signals via the <em>Signals</em> section in the Properties pane.</li>
        <li>Choose plot type: <em>timeseries</em>, <em>FFT</em>, <em>waterfall</em>, <em>histogram</em>, <em>bar</em>, or <em>logic</em>.</li>
        <li>Set <em>Time window</em> to control how many seconds of live data are shown.</li>
        <li>In Historical mode the entire requested range is loaded at once.</li>
      </ul>
    </div>
  );
}

function SectionSignals() {
  return (
    <div>
      <p class="help-lead">
        The signal tree (left pane in Edit mode) lets you browse, search, and manage the signals available from each data source.
      </p>

      <div class="help-two-col">
        <div>
          <h3 class="help-h3">Finding signals</h3>
          <ul class="help-list">
            <li>Type in the <em>Filter signals…</em> box to search by name or description.</li>
            <li>Click a group header to collapse or expand that data source.</li>
            <li>Drag any signal onto the canvas to create a widget.</li>
          </ul>

          <h3 class="help-h3">Adding custom signals</h3>
          <ul class="help-list">
            <li>Click <strong>+</strong> next to a group name to type a PV name manually.</li>
            <li>Custom signals are saved in your browser (localStorage) and persist across reloads.</li>
            <li>Click <strong>✕</strong> on a custom signal to remove it.</li>
          </ul>

          <h3 class="help-h3">CSV import</h3>
          <p>Click <strong>CSV</strong> to import a list of signals from a file. Each line should be either:</p>
          <ul class="help-list">
            <li><code>PV_NAME</code> — added to the <em>epics</em> data source.</li>
            <li><code>ds,PV_NAME</code> — added to the specified data source.</li>
          </ul>
          <p>Lines starting with <code>#</code> are treated as comments.</p>

          <h3 class="help-h3">Channel Finder</h3>
          <p>
            If your server is configured with an EPICS Channel Finder URL,
            a <strong>🔍</strong> button appears when you type in the filter box.
            Click it to search Channel Finder and import matching PV names.
          </p>

          <h3 class="help-h3">Synthetic signals</h3>
          <p>Click <strong>+ Synthetic</strong> to open the wizard. Choose an input signal, a processing node (gain, moving average, lowpass filter, …), and optional metadata. The new signal appears in the tree immediately.</p>
        </div>
        <DiagramSignalTree />
      </div>
    </div>
  );
}

function SectionHistory() {
  return (
    <div>
      <p class="help-lead">
        Historical data is retrieved from EPICS Archive Appliance when the server is configured with an <code>archive_url</code>.
        Only the <strong>Plot</strong> widget in <em>time-series</em> mode supports historical ranges.
      </p>

      <DiagramHistory />
      <p class="help-caption">Time navigation toolbar: ① Live button · ② start · ③ end datetime · ④ Load.</p>

      <h3 class="help-h3">How to load historical data</h3>
      <ol class="help-list">
        <li>Set the <strong>start</strong> and <strong>end</strong> date/time fields in the toolbar.</li>
        <li>Click <strong>Load</strong> — all plot widgets on the current panel will fetch the requested range.</li>
        <li>While loading, a <em>"Loading history…"</em> overlay appears on each plot.</li>
        <li>If no data is available, the overlay shows <em>"No archive data for this range"</em>.</li>
        <li>Click <strong>● Live</strong> (highlighted when active) to return to streaming mode.</li>
      </ol>

      <h3 class="help-h3">Notes</h3>
      <ul class="help-list">
        <li>Historical data is requested over the WebSocket connection (not REST).</li>
        <li>Requests time out after 15 seconds if the archive does not respond.</li>
        <li>Non-timeseries plot types (FFT, waterfall, etc.) remain in live mode regardless of the time range.</li>
        <li>Point-value widgets (gauge, bar, LED, …) are unaffected by the time range selection.</li>
      </ul>
    </div>
  );
}

function SectionShortcuts() {
  const shortcuts: Array<[string, string]> = [
    ['Ctrl+C',              'Copy selected widgets (Edit mode)'],
    ['Ctrl+V',              'Paste widgets from clipboard (Edit mode)'],
    ['Ctrl+Z',              'Undo last change (Edit mode)'],
    ['Ctrl+Y / Ctrl+Shift+Z', 'Redo (Edit mode)'],
    ['Ctrl+A',              'Select all widgets (Edit mode)'],
    ['Delete / Backspace',  'Delete selected widgets (Edit mode)'],
    ['Arrow keys',          'Nudge selection by 1 px (Edit mode)'],
    ['Shift+Arrow',         'Nudge by grid size (Edit mode)'],
    ['Ctrl+click',          'Add/remove widget from multi-selection'],
    ['Escape',              'Close dialogs / cancel input'],
    ['?',                   'Open this help'],
  ];

  return (
    <div>
      <p class="help-lead">All shortcuts that work while the canvas or modal has focus.</p>

      <table class="help-shortcut-table">
        <thead>
          <tr><th>Shortcut</th><th>Action</th></tr>
        </thead>
        <tbody>
          {shortcuts.map(([key, action]) => (
            <tr key={key}>
              <td><kbd class="help-kbd">{key}</kbd></td>
              <td>{action}</td>
            </tr>
          ))}
        </tbody>
      </table>

      <h3 class="help-h3">API &amp; Metrics</h3>
      <ul class="help-list">
        <li>REST API: <code>/api/v1/datasources</code>, <code>/api/v1/signals</code>, <code>/api/v1/interfaces</code>, …</li>
        <li>Prometheus metrics: <code>/metrics</code></li>
        <li>Health check: <code>/healthz</code></li>
        <li>WebSocket: <code>ws://&lt;host&gt;/ws</code></li>
      </ul>

      <h3 class="help-h3">Configuration file</h3>
      <pre class="help-pre">[server]{'\n'}listen      = ":8080"{'\n'}storage_dir = "./data"{'\n\n'}[datasource.epics]{'\n'}enabled     = true{'\n'}archive_url = "http://archiver:17665"{'\n\n'}[datasource.synthetic]{'\n'}enabled = true</pre>
    </div>
  );
}

const SECTION_COMPONENTS: Record<string, () => JSX.Element> = {
  start:     SectionStart,
  view:      SectionView,
  edit:      SectionEdit,
  widgets:   SectionWidgets,
  signals:   SectionSignals,
  history:   SectionHistory,
  shortcuts: SectionShortcuts,
};

// ── Main modal ────────────────────────────────────────────────────────────────

export default function HelpModal({ initialSection = 'start', onClose }: Props) {
  const [active, setActive] = useState(initialSection);

  const Content = SECTION_COMPONENTS[active] ?? SectionStart;

  // Close on backdrop click
  function handleBackdrop(e: MouseEvent) {
    if ((e.target as Element).classList.contains('help-backdrop')) onClose();
  }

  // Close on Escape
  function handleKey(e: KeyboardEvent) {
    if (e.key === 'Escape') onClose();
  }

  return (
    <div class="help-backdrop" onClick={handleBackdrop} onKeyDown={handleKey} tabIndex={-1}>
      <div class="help-modal" role="dialog" aria-modal="true" aria-label="uopi Help Manual">
        {/* Header */}
        <div class="help-header">
          <span class="help-title">uopi — User Manual</span>
          <button class="icon-btn help-close" onClick={onClose} title="Close help">✕</button>
        </div>

        <div class="help-body">
          {/* Sidebar nav */}
          <nav class="help-sidebar">
            {SECTIONS.map(s => (
              <button
                key={s.id}
                class={`help-nav-item${active === s.id ? ' active' : ''}`}
                onClick={() => setActive(s.id)}
              >
                {s.label}
              </button>
            ))}
          </nav>

          {/* Content area */}
          <div class="help-content">
            <h2 class="help-h2">{SECTIONS.find(s => s.id === active)?.label}</h2>
            <Content />
          </div>
        </div>
      </div>
    </div>
  );
}
