import { useEffect, useRef, useState } from 'react';
import { Radio, AudioLines, RefreshCw } from 'lucide-react';
import {
  GetIcomState, IcomRefresh,
  IcomSetAFGain, IcomSetRFGain, IcomSetNB, IcomSetNBLevel, IcomSetNR, IcomSetNRLevel,
  IcomSetANF, IcomSetAGC, IcomSetPreamp, IcomSetAtt, IcomSetFilter,
} from '../../wailsjs/go/main/App';
import { cn } from '@/lib/utils';

type IcomState = {
  available: boolean; model?: string; mode?: string;
  af_gain: number; rf_gain: number;
  nb: boolean; nb_level: number; nr: boolean; nr_level: number; anf: boolean;
  agc?: string; preamp: number; att: number; filter: number;
};

const ZERO: IcomState = {
  available: false, af_gain: 0, rf_gain: 0,
  nb: false, nb_level: 0, nr: false, nr_level: 0, anf: false,
  preamp: 0, att: 0, filter: 1,
};

function Slider({ value, onChange, disabled, accent = '#2563eb' }: {
  value: number; onChange: (v: number) => void; disabled?: boolean; accent?: string;
}) {
  const v = Math.max(0, Math.min(100, value));
  return (
    <input
      type="range" min={0} max={100} value={v} disabled={disabled}
      onChange={(e) => onChange(parseInt(e.target.value, 10))}
      className={cn('flex-1 h-1.5 rounded-full appearance-none cursor-pointer disabled:opacity-30 disabled:cursor-default',
        '[&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:size-3.5 [&::-webkit-slider-thumb]:rounded-full',
        '[&::-webkit-slider-thumb]:bg-white [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:shadow-sm')}
      style={{ background: `linear-gradient(to right, ${accent} ${v}%, #d8cfb8 ${v}%)`, borderColor: accent }}
    />
  );
}

function Segmented({ value, options, onChange }: {
  value: string; options: { v: string; l: string }[]; onChange: (v: string) => void;
}) {
  return (
    <div className="inline-flex rounded-md border border-border overflow-hidden shrink-0">
      {options.map((o) => (
        <button key={o.v} type="button" onClick={() => onChange(o.v)}
          className={cn('px-2 py-1 text-[11px] font-bold tracking-wide transition-colors border-l border-border first:border-l-0',
            value === o.v ? 'bg-primary text-primary-foreground' : 'bg-card text-muted-foreground hover:bg-muted')}>
          {o.l}
        </button>
      ))}
    </div>
  );
}

function Chip({ on, onClick, label }: { on: boolean; onClick: () => void; label: string }) {
  return (
    <button type="button" onClick={onClick}
      className={cn('w-14 shrink-0 px-2 py-1 rounded-md text-[11px] font-bold border transition-colors',
        on ? 'bg-emerald-600 border-emerald-600 text-white' : 'bg-card text-muted-foreground border-border hover:bg-muted')}>
      {label}
    </button>
  );
}

function LevelRow({ label, on, onToggle, value, onLevel }: {
  label: string; on: boolean; onToggle: () => void; value: number; onLevel: (v: number) => void;
}) {
  return (
    <div className="flex items-center gap-2">
      <Chip on={on} onClick={onToggle} label={label} />
      <Slider value={value} disabled={!on} onChange={onLevel} />
      <span className="w-8 text-right text-xs font-mono tabular-nums text-muted-foreground">{value}</span>
    </div>
  );
}

function Card({ icon: Icon, title, accent, children }: { icon: any; title: string; accent?: string; children: React.ReactNode }) {
  return (
    <div className="rounded-xl border border-border bg-card shadow-sm overflow-hidden">
      <div className="flex items-center gap-2 px-3 py-2 border-b border-border/60 bg-muted/30">
        <Icon className="size-4" style={{ color: accent ?? 'var(--primary)' }} />
        <span className="text-xs font-bold uppercase tracking-wider text-foreground/80">{title}</span>
      </div>
      <div className="p-3 space-y-3">{children}</div>
    </div>
  );
}

function Row({ label, children }: { label: string; children: React.ReactNode }) {
  return (
    <div className="flex items-center gap-2">
      <span className="w-16 shrink-0 text-[11px] font-bold uppercase tracking-wider text-muted-foreground">{label}</span>
      {children}
    </div>
  );
}

// IcomPanel — receive-DSP control surface for an Icom on the CI-V backend.
// Unlike the Flex (which pushes state), the Icom is polled: the cache reflects
// the last refresh plus optimistic updates. Front-panel knob changes show after
// the next ↻ Refresh.
export function IcomPanel() {
  const [st, setSt] = useState<IcomState>(ZERO);
  const [busy, setBusy] = useState(false);

  const load = () => GetIcomState().then((s) => setSt((s ?? ZERO) as IcomState)).catch(() => {});
  const refresh = async () => {
    setBusy(true);
    try { await IcomRefresh(); } catch {}
    await load();
    setBusy(false);
  };

  useEffect(() => {
    refresh();
    const id = window.setInterval(load, 1500); // cheap cache poll (mode + optimistic state)
    return () => window.clearInterval(id);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  // Optimistic local update + fire the command; the cache poll reconciles.
  const set = (patch: Partial<IcomState>, fn: () => Promise<void>) => {
    setSt((s) => ({ ...s, ...patch }));
    fn().catch(() => {});
  };

  if (!st.available) {
    return (
      <div className="h-full flex items-center justify-center text-sm text-muted-foreground p-6 text-center">
        Icom not connected. Enable the Icom CI-V backend in Settings → CAT and connect the radio's USB port.
      </div>
    );
  }

  return (
    <div className="h-full overflow-y-auto p-3 space-y-3">
      <div className="flex items-center justify-between">
        <div className="text-sm font-bold">{st.model || 'Icom'}{st.mode ? <span className="ml-2 text-xs font-mono text-muted-foreground">{st.mode}</span> : null}</div>
        <button type="button" onClick={refresh} disabled={busy}
          className="inline-flex items-center gap-1.5 rounded-md border border-border bg-card px-2 py-1 text-xs hover:bg-muted disabled:opacity-40">
          <RefreshCw className={cn('size-3.5', busy && 'animate-spin')} /> Refresh
        </button>
      </div>

      <Card icon={Radio} title="Receive" accent="#2563eb">
        <Row label="AF">
          <Slider value={st.af_gain} onChange={(v) => set({ af_gain: v }, () => IcomSetAFGain(v))} />
          <span className="w-8 text-right text-xs font-mono tabular-nums text-muted-foreground">{st.af_gain}</span>
        </Row>
        <Row label="RF">
          <Slider value={st.rf_gain} onChange={(v) => set({ rf_gain: v }, () => IcomSetRFGain(v))} />
          <span className="w-8 text-right text-xs font-mono tabular-nums text-muted-foreground">{st.rf_gain}</span>
        </Row>
        <Row label="AGC">
          <Segmented value={st.agc || ''} options={[{ v: 'FAST', l: 'FAST' }, { v: 'MID', l: 'MID' }, { v: 'SLOW', l: 'SLOW' }]}
            onChange={(v) => set({ agc: v }, () => IcomSetAGC(v))} />
        </Row>
        <Row label="Preamp">
          <Segmented value={String(st.preamp)} options={[{ v: '0', l: 'OFF' }, { v: '1', l: 'P1' }, { v: '2', l: 'P2' }]}
            onChange={(v) => set({ preamp: parseInt(v) }, () => IcomSetPreamp(parseInt(v)))} />
        </Row>
        <Row label="Att">
          <Segmented value={String(st.att)} options={[{ v: '0', l: 'OFF' }, { v: '6', l: '6dB' }, { v: '12', l: '12dB' }, { v: '18', l: '18dB' }]}
            onChange={(v) => set({ att: parseInt(v) }, () => IcomSetAtt(parseInt(v)))} />
        </Row>
        <Row label="Filter">
          <Segmented value={String(st.filter)} options={[{ v: '1', l: 'FIL1' }, { v: '2', l: 'FIL2' }, { v: '3', l: 'FIL3' }]}
            onChange={(v) => set({ filter: parseInt(v) }, () => IcomSetFilter(parseInt(v)))} />
        </Row>
      </Card>

      <Card icon={AudioLines} title="Noise / Notch" accent="#16a34a">
        <LevelRow label="NB" on={st.nb} value={st.nb_level}
          onToggle={() => set({ nb: !st.nb }, () => IcomSetNB(!st.nb))}
          onLevel={(v) => set({ nb_level: v }, () => IcomSetNBLevel(v))} />
        <LevelRow label="NR" on={st.nr} value={st.nr_level}
          onToggle={() => set({ nr: !st.nr }, () => IcomSetNR(!st.nr))}
          onLevel={(v) => set({ nr_level: v }, () => IcomSetNRLevel(v))} />
        <div className="flex items-center gap-2">
          <Chip label="ANF" on={st.anf} onClick={() => set({ anf: !st.anf }, () => IcomSetANF(!st.anf))} />
          <span className="text-xs text-muted-foreground">Auto notch filter</span>
        </div>
      </Card>
    </div>
  );
}
