import { h } from 'preact';
import { useState } from 'preact/hooks';
import type { Widget, Interface } from './lib/types';

interface Props {
  selected: Widget | null;
  multiCount: number;
  iface: Interface;
  onChange: (updated: Widget) => void;
  onIfaceChange: (updated: Interface) => void;
}

function Field({ label, children }: { label: string; children: any }) {
  return (
    <div class="prop-field">
      <label class="prop-label">{label}</label>
      {children}
    </div>
  );
}

function TextInput({ value, onCommit }: { value: string; onCommit: (v: string) => void }) {
  const [local, setLocal] = useState(value);
  // Sync when external value changes (e.g. different widget selected)
  if (local !== value && document.activeElement?.tagName !== 'INPUT') {
    setLocal(value);
  }
  return (
    <input
      class="prop-input"
      value={local}
      onInput={(e) => setLocal((e.target as HTMLInputElement).value)}
      onChange={(e) => onCommit((e.target as HTMLInputElement).value)}
    />
  );
}

// Widgets that show units from signal metadata (can be overridden)
const UNIT_WIDGETS = new Set(['textview', 'gauge', 'barh', 'barv', 'setvalue']);
// Widgets with a signal-based label (can be overridden)
const LABEL_WIDGETS = new Set(['textview', 'gauge', 'barh', 'barv', 'setvalue', 'led', 'multiled']);
// Widgets with multiple signals
const MULTI_SIGNAL_WIDGETS = new Set(['plot', 'multiled']);

export default function PropertiesPane({ selected, multiCount, iface, onChange, onIfaceChange }: Props) {
  const [collapsed, setCollapsed] = useState(false);

  function setOpt(key: string, value: string) {
    if (!selected) return;
    onChange({ ...selected, options: { ...selected.options, [key]: value } });
  }

  function setProp(key: keyof Widget, value: any) {
    if (!selected) return;
    onChange({ ...selected, [key]: value } as Widget);
  }

  function removeSignal(idx: number) {
    if (!selected) return;
    const signals = selected.signals.filter((_, i) => i !== idx);
    onChange({ ...selected, signals });
  }

  const w = selected;

  return (
    <aside class={`panel props-panel${collapsed ? ' collapsed' : ''}`} style="border-left:1px solid #2d3748;border-right:none;">
      <div class="panel-header">
        {!collapsed && <span class="panel-title">Properties</span>}
        <button class="icon-btn" onClick={() => setCollapsed(c => !c)} title={collapsed ? 'Expand' : 'Collapse'}>
          {collapsed ? '◀' : '▶'}
        </button>
      </div>

      {!collapsed && (
        <div class="props-body">
          {/* Canvas-level properties */}
          <div class="props-section">
            <div class="props-section-title">Canvas</div>
            <Field label="Name">
              <TextInput
                value={iface.name}
                onCommit={(v) => onIfaceChange({ ...iface, name: v })}
              />
            </Field>
            <Field label="Width">
              <input
                class="prop-input prop-input-num"
                type="number"
                value={iface.w}
                min={100}
                onChange={(e) => onIfaceChange({ ...iface, w: parseInt((e.target as HTMLInputElement).value, 10) || iface.w })}
              />
            </Field>
            <Field label="Height">
              <input
                class="prop-input prop-input-num"
                type="number"
                value={iface.h}
                min={100}
                onChange={(e) => onIfaceChange({ ...iface, h: parseInt((e.target as HTMLInputElement).value, 10) || iface.h })}
              />
            </Field>
          </div>

          {w && (
            <div class="props-section">
              <div class="props-section-title">{w.type}</div>

              {/* Position / size */}
              <Field label="X">
                <input class="prop-input prop-input-num" type="number" value={w.x}
                  onChange={(e) => setProp('x', parseFloat((e.target as HTMLInputElement).value) || 0)} />
              </Field>
              <Field label="Y">
                <input class="prop-input prop-input-num" type="number" value={w.y}
                  onChange={(e) => setProp('y', parseFloat((e.target as HTMLInputElement).value) || 0)} />
              </Field>
              <Field label="Width">
                <input class="prop-input prop-input-num" type="number" value={w.w} min={10}
                  onChange={(e) => setProp('w', parseFloat((e.target as HTMLInputElement).value) || 10)} />
              </Field>
              <Field label="Height">
                <input class="prop-input prop-input-num" type="number" value={w.h} min={10}
                  onChange={(e) => setProp('h', parseFloat((e.target as HTMLInputElement).value) || 10)} />
              </Field>

              {/* Signals */}
              {MULTI_SIGNAL_WIDGETS.has(w.type) ? (
                <Field label="Signals">
                  <div class="prop-signals-list">
                    {w.signals.length === 0 && <span class="hint">No signals</span>}
                    {w.signals.map((s, i) => (
                      <div key={i} class="prop-signal-row">
                        <span class="prop-sig">{s.ds}:{s.name}</span>
                        <button
                          class="icon-btn prop-sig-remove"
                          title="Remove signal"
                          onClick={() => removeSignal(i)}
                        >✕</button>
                      </div>
                    ))}
                  </div>
                </Field>
              ) : w.signals.length > 0 ? (
                <Field label="Signal">
                  <span class="prop-sig">{w.signals[0].ds}:{w.signals[0].name}</span>
                </Field>
              ) : null}

              {/* ── Common label/unit overrides (issue #8) ──────────────────── */}

              {/* Label: button and textlabel use it as display text;
                  signal widgets use it as header label */}
              {w.type !== 'image' && w.type !== 'link' && (
                <Field label={LABEL_WIDGETS.has(w.type) ? 'Label override' : 'Label'}>
                  <TextInput
                    value={w.options['label'] ?? ''}
                    onCommit={(v) => setOpt('label', v)}
                  />
                  {LABEL_WIDGETS.has(w.type) && (
                    <span class="prop-hint">Empty = signal name</span>
                  )}
                </Field>
              )}

              {/* Unit override for signal widgets */}
              {UNIT_WIDGETS.has(w.type) && (
                <Field label="Unit override">
                  <TextInput
                    value={w.options['unit'] ?? ''}
                    onCommit={(v) => setOpt('unit', v)}
                  />
                  <span class="prop-hint">Empty = from metadata · "none" = hide</span>
                </Field>
              )}

              {/* ── Type-specific options ──────────────────────────────────── */}

              {(w.type === 'gauge' || w.type === 'barh' || w.type === 'barv') && (
                <div>
                  <Field label="Min">
                    <TextInput value={w.options['min'] ?? '0'} onCommit={(v) => setOpt('min', v)} />
                  </Field>
                  <Field label="Max">
                    <TextInput value={w.options['max'] ?? '100'} onCommit={(v) => setOpt('max', v)} />
                  </Field>
                </div>
              )}

              {w.type === 'led' && (
                <Field label="Condition">
                  <TextInput value={w.options['condition'] ?? '>0'} onCommit={(v) => setOpt('condition', v)} />
                </Field>
              )}

              {w.type === 'setvalue' && (
                <div>
                  <Field label="Min">
                    <TextInput value={w.options['min'] ?? ''} onCommit={(v) => setOpt('min', v)} />
                  </Field>
                  <Field label="Confirm dialog">
                    <select class="prop-select" value={w.options['confirm'] ?? 'false'}
                      onChange={(e) => setOpt('confirm', (e.target as HTMLSelectElement).value)}>
                      <option value="false">No</option>
                      <option value="true">Yes</option>
                    </select>
                  </Field>
                </div>
              )}

              {/* Button options (issue #2) */}
              {w.type === 'button' && (
                <div>
                  <Field label="Send value">
                    <TextInput value={w.options['value'] ?? '1'} onCommit={(v) => setOpt('value', v)} />
                  </Field>
                  <Field label="Mode">
                    <select class="prop-select" value={w.options['mode'] ?? 'oneshot'}
                      onChange={(e) => setOpt('mode', (e.target as HTMLSelectElement).value)}>
                      <option value="oneshot">One-shot (set once)</option>
                      <option value="setReset">Set-reset (auto-revert)</option>
                      <option value="persistent">Persistent (toggle / monitor)</option>
                    </select>
                  </Field>
                  {(w.options['mode'] === 'setReset' || w.options['mode'] === 'persistent') && (
                    <Field label="Reset value">
                      <TextInput value={w.options['resetValue'] ?? '0'} onCommit={(v) => setOpt('resetValue', v)} />
                    </Field>
                  )}
                  {w.options['mode'] === 'setReset' && (
                    <Field label="Reset after (s)">
                      <TextInput value={w.options['resetTime'] ?? '1'} onCommit={(v) => setOpt('resetTime', v)} />
                    </Field>
                  )}
                  <Field label="Confirm dialog">
                    <select class="prop-select" value={w.options['confirm'] ?? 'false'}
                      onChange={(e) => setOpt('confirm', (e.target as HTMLSelectElement).value)}>
                      <option value="false">No</option>
                      <option value="true">Yes</option>
                    </select>
                  </Field>
                </div>
              )}

              {/* Plot options */}
              {w.type === 'plot' && (
                <div>
                  <Field label="Plot type">
                    <select
                      class="prop-select"
                      value={w.options['plotType'] ?? 'timeseries'}
                      onChange={(e) => setOpt('plotType', (e.target as HTMLSelectElement).value)}
                    >
                      <option value="timeseries">Time-series</option>
                      <option value="histogram">Histogram</option>
                      <option value="bar">Bar chart</option>
                      <option value="fft">FFT</option>
                      <option value="waterfall">Waterfall</option>
                      <option value="logic">Logic analyser</option>
                    </select>
                  </Field>
                  {(w.options['plotType'] ?? 'timeseries') === 'timeseries' && (
                    <Field label="Time window (s)">
                      <TextInput value={w.options['timeWindow'] ?? '60'} onCommit={(v) => setOpt('timeWindow', v)} />
                    </Field>
                  )}
                  <Field label="Y min">
                    <TextInput value={w.options['yMin'] ?? 'auto'} onCommit={(v) => setOpt('yMin', v)} />
                  </Field>
                  <Field label="Y max">
                    <TextInput value={w.options['yMax'] ?? 'auto'} onCommit={(v) => setOpt('yMax', v)} />
                  </Field>
                  <Field label="Legend">
                    <select class="prop-select" value={w.options['legend'] ?? 'bottom'}
                      onChange={(e) => setOpt('legend', (e.target as HTMLSelectElement).value)}>
                      <option value="bottom">Bottom</option>
                      <option value="top">Top</option>
                      <option value="none">None</option>
                    </select>
                  </Field>
                </div>
              )}

              {w.type === 'textlabel' && (
                <div>
                  <Field label="Font size">
                    <TextInput value={w.options['fontSize'] ?? '14'} onCommit={(v) => setOpt('fontSize', v)} />
                  </Field>
                  <Field label="Color">
                    <TextInput value={w.options['color'] ?? '#e2e8f0'} onCommit={(v) => setOpt('color', v)} />
                  </Field>
                </div>
              )}

              {w.type === 'image' && (
                <Field label="URL">
                  <TextInput value={w.options['url'] ?? ''} onCommit={(v) => setOpt('url', v)} />
                </Field>
              )}

              {w.type === 'link' && (
                <div>
                  <Field label="Target">
                    <TextInput value={w.options['target'] ?? ''} onCommit={(v) => setOpt('target', v)} />
                  </Field>
                  <Field label="Label">
                    <TextInput value={w.options['label'] ?? ''} onCommit={(v) => setOpt('label', v)} />
                  </Field>
                </div>
              )}
            </div>
          )}

          {!w && multiCount > 1 && (
            <p class="hint" style="padding:0.75rem;">{multiCount} widgets selected.<br/>Use align/distribute tools in the toolbar.</p>
          )}

          {!w && multiCount === 0 && (
            <p class="hint" style="padding:0.75rem;">Select a widget to edit its properties.</p>
          )}
        </div>
      )}
    </aside>
  );
}
