import { h } from 'preact';
import { useState, useEffect } from 'preact/hooks';
import { getSignalStore, getMetaStore } from '../lib/stores';
import { wsClient } from '../lib/ws';
import type { Widget, SignalValue, SignalMeta } from '../lib/types';

const DEFAULT_VALUE: SignalValue = { value: null, quality: 'unknown', ts: null };

function qualityColor(q: string): string {
  switch (q) {
    case 'good': return '#4ade80';
    case 'uncertain': return '#fbbf24';
    case 'bad': return '#f87171';
    default: return '#6b7280';
  }
}

interface Props { widget: Widget; onContextMenu?: (e: MouseEvent) => void; }

export default function SetValue({ widget, onContextMenu }: Props) {
  const sigRef = widget.signals[0];
  const [sv, setSv] = useState<SignalValue>(DEFAULT_VALUE);
  const [meta, setMeta] = useState<SignalMeta | null>(null);
  const [inputValue, setInputValue] = useState('');

  useEffect(() => {
    if (!sigRef) return;
    const unsubV = getSignalStore(sigRef).subscribe(setSv);
    const unsubM = getMetaStore(sigRef).subscribe(setMeta);
    return () => { unsubV(); unsubM(); };
  }, [sigRef?.ds, sigRef?.name]);

  const label = widget.options['label'] || sigRef?.name || '';
  const rawUnit = widget.options['unit'];
  const unit = rawUnit === 'none' ? '' : (rawUnit || meta?.unit || '');
  const confirm = widget.options['confirm'] === 'true';
  const isNumeric = meta ? meta.type !== 'string' : true;
  const quality = sv.quality;

  function displayValue(): string {
    const v = sv.value;
    if (v === null || v === undefined) return '---';
    if (typeof v === 'number') {
      return Number.isFinite(v) ? v.toPrecision(4).replace(/\.?0+$/, '') : String(v);
    }
    return String(v);
  }

  function handleSet() {
    if (!sigRef) return;
    const raw = inputValue.trim();
    if (!raw) return;

    const doWrite = () => {
      const val = isNumeric ? parseFloat(raw) : raw;
      wsClient.write(sigRef, val);
      setInputValue('');
    };

    if (confirm) {
      if (window.confirm(`Set ${label} to ${raw}?`)) doWrite();
    } else {
      doWrite();
    }
  }

  function handleKeydown(e: KeyboardEvent) {
    if (e.key === 'Enter') handleSet();
  }

  return (
    <div
      class="setvalue"
      style={`left:${widget.x}px;top:${widget.y}px;width:${widget.w}px;height:${widget.h}px;`}
      onContextMenu={onContextMenu}
    >
      <span class="quality-dot" style={`background:${qualityColor(quality)};`} title={`Quality: ${quality}`} />
      <span class="sv-label">{label}:</span>
      <input
        class="sv-input"
        type={isNumeric ? 'number' : 'text'}
        value={inputValue}
        onInput={(e: Event) => setInputValue((e.target as HTMLInputElement).value)}
        onKeyDown={handleKeydown}
        placeholder="value"
      />
      <span class="sv-current">{displayValue()}</span>
      {unit && <span class="sv-unit">{unit}</span>}
      <button class="sv-btn" onClick={handleSet}>Set</button>
    </div>
  );
}
