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

interface Props {
  onClose: () => void;
  onCreated: () => void;
}

interface NodeParam {
  label: string;
  key: string;
  type: 'number' | 'text';
  default: string;
}

const NODE_TYPES: Array<{ type: string; label: string; params: NodeParam[] }> = [
  { type: 'gain',         label: 'Gain',            params: [{ label: 'Factor',     key: 'factor',  type: 'number', default: '1' }] },
  { type: 'offset',       label: 'Offset',          params: [{ label: 'Offset',     key: 'offset',  type: 'number', default: '0' }] },
  { type: 'moving_avg',   label: 'Moving Average',  params: [{ label: 'Window (n)', key: 'n',       type: 'number', default: '10' }] },
  { type: 'rms',          label: 'RMS',             params: [{ label: 'Window (n)', key: 'n',       type: 'number', default: '10' }] },
  { type: 'lowpass',      label: 'Lowpass Filter',  params: [{ label: 'Cutoff Hz',  key: 'cutoff',  type: 'number', default: '1' }, { label: 'Sample Hz', key: 'sample_rate', type: 'number', default: '10' }] },
  { type: 'highpass',     label: 'Highpass Filter', params: [{ label: 'Cutoff Hz',  key: 'cutoff',  type: 'number', default: '1' }, { label: 'Sample Hz', key: 'sample_rate', type: 'number', default: '10' }] },
  { type: 'derivative',   label: 'Derivative',      params: [] },
  { type: 'integral',     label: 'Integral',        params: [] },
  { type: 'clamp',        label: 'Clamp',           params: [{ label: 'Min', key: 'min', type: 'number', default: '0' }, { label: 'Max', key: 'max', type: 'number', default: '100' }] },
  { type: 'formula',      label: 'Formula',         params: [{ label: 'Expression (use "x")', key: 'expr', type: 'text', default: 'x * 1.0' }] },
];

export default function SyntheticWizard({ onClose, onCreated }: Props) {
  const [name, setName] = useState('');
  const [inputDs, setInputDs] = useState('stub');
  const [inputSig, setInputSig] = useState('sine_1hz');
  const [nodeType, setNodeType] = useState('gain');
  const [params, setParams] = useState<Record<string, string>>({});
  const [unit, setUnit] = useState('');
  const [desc, setDesc] = useState('');
  const [dispLow, setDispLow] = useState('0');
  const [dispHigh, setDispHigh] = useState('100');
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState('');

  const nodeDef = NODE_TYPES.find(n => n.type === nodeType)!;

  function getParam(key: string, def: string): string {
    return params[key] ?? def;
  }

  function setParam(key: string, val: string) {
    setParams(p => ({ ...p, [key]: val }));
  }

  async function handleCreate() {
    if (!name.trim()) { setError('Name is required'); return; }
    if (!inputSig.trim()) { setError('Input signal is required'); return; }

    const nodeParams: Record<string, any> = {};
    for (const p of nodeDef.params) {
      const raw = getParam(p.key, p.default);
      nodeParams[p.key] = p.type === 'number' ? parseFloat(raw) : raw;
    }

    const def = {
      name: name.trim(),
      ds: inputDs,
      signal: inputSig.trim(),
      pipeline: [{ type: nodeType, params: nodeParams }],
      meta: {
        unit: unit || undefined,
        description: desc || undefined,
        displayLow: parseFloat(dispLow) || 0,
        displayHigh: parseFloat(dispHigh) || 100,
      },
    };

    setSaving(true);
    setError('');
    try {
      const res = await fetch('/api/v1/synthetic', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(def),
      });
      if (!res.ok) {
        const j = await res.json().catch(() => ({ error: res.statusText }));
        throw new Error(j.error ?? res.statusText);
      }
      onCreated();
      onClose();
    } catch (err) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setSaving(false);
    }
  }

  return (
    <div class="wizard-backdrop" onClick={onClose}>
      <div class="wizard" onClick={(e) => e.stopPropagation()}>
        <div class="wizard-header">
          <span>New Synthetic Signal</span>
          <button class="icon-btn" onClick={onClose}>✕</button>
        </div>

        <div class="wizard-body">
          {error && <p class="wizard-error">{error}</p>}

          <div class="wizard-section-title">Signal identity</div>
          <div class="wizard-field">
            <label>Name</label>
            <input class="prop-input" value={name}
              placeholder="e.g. smoothed_pressure"
              onInput={(e) => setName((e.target as HTMLInputElement).value)} />
          </div>

          <div class="wizard-section-title">Input signal</div>
          <div class="wizard-field wizard-field-row">
            <div class="wizard-field">
              <label>Data source</label>
              <input class="prop-input" value={inputDs}
                placeholder="stub"
                onInput={(e) => setInputDs((e.target as HTMLInputElement).value)} />
            </div>
            <div class="wizard-field" style="flex:2;">
              <label>Signal name</label>
              <input class="prop-input" value={inputSig}
                placeholder="sine_1hz"
                onInput={(e) => setInputSig((e.target as HTMLInputElement).value)} />
            </div>
          </div>

          <div class="wizard-section-title">Processing</div>
          <div class="wizard-field">
            <label>Node type</label>
            <select class="prop-select" value={nodeType}
              onChange={(e) => { setNodeType((e.target as HTMLSelectElement).value); setParams({}); }}>
              {NODE_TYPES.map(n => <option key={n.type} value={n.type}>{n.label}</option>)}
            </select>
          </div>
          {nodeDef.params.map(p => (
            <div key={p.key} class="wizard-field">
              <label>{p.label}</label>
              <input class="prop-input" type={p.type === 'number' ? 'number' : 'text'}
                value={getParam(p.key, p.default)}
                onInput={(e) => setParam(p.key, (e.target as HTMLInputElement).value)} />
            </div>
          ))}

          <div class="wizard-section-title">Metadata (optional)</div>
          <div class="wizard-field wizard-field-row">
            <div class="wizard-field">
              <label>Unit</label>
              <input class="prop-input" value={unit} placeholder="m/s"
                onInput={(e) => setUnit((e.target as HTMLInputElement).value)} />
            </div>
            <div class="wizard-field">
              <label>Display low</label>
              <input class="prop-input" type="number" value={dispLow}
                onInput={(e) => setDispLow((e.target as HTMLInputElement).value)} />
            </div>
            <div class="wizard-field">
              <label>Display high</label>
              <input class="prop-input" type="number" value={dispHigh}
                onInput={(e) => setDispHigh((e.target as HTMLInputElement).value)} />
            </div>
          </div>
          <div class="wizard-field">
            <label>Description</label>
            <input class="prop-input" value={desc} placeholder="Optional description"
              onInput={(e) => setDesc((e.target as HTMLInputElement).value)} />
          </div>
        </div>

        <div class="wizard-footer">
          <button class="toolbar-btn" onClick={onClose}>Cancel</button>
          <button class="toolbar-btn toolbar-btn-primary" onClick={handleCreate} disabled={saving}>
            {saving ? 'Creating…' : 'Create Signal'}
          </button>
        </div>
      </div>
    </div>
  );
}
