import { useRef, useState } from 'react';
import { Gauge, Radio, ChevronDown } from 'lucide-react';
import { cn } from '@/lib/utils';
import { MeterBar } from '@/components/MeterBar';
import type { TGStatus, TGChannel } from '@/components/TunerGeniusPanel';
import { TunerGeniusAutotune, TunerGeniusSetBypass, TunerGeniusSetOperate, TunerGeniusActivate } from '../../wailsjs/go/main/App';

// TunerCard renders the 4O3A Tuner Genius XL exactly like the amplifier card
// (AmpCard) so Station Control and the FlexRadio panel show the SAME card. It
// mirrors the native app's two channels (A / B) with their source, frequency and
// antenna, a live PWR / SWR pair, and the Tune / Bypass / Operate actions. It
// drives the backend directly (no local state) — the caller's ~1.5s poll
// reconciles the display, just like AmpCard. Meters come from the shared MeterBar
// so they're the exact same size as the Flex/amp meters.

function Card({ icon: Icon, title, accent, children, ckey }: { icon: any; title: string; accent?: string; children: React.ReactNode; ckey?: string }) {
  // Collapsible with persisted state — same behaviour as the FlexRadio panel's Card.
  const storeKey = 'opslog.cardOpen.' + (ckey || title);
  const [open, setOpen] = useState(() => localStorage.getItem(storeKey) !== '0');
  const toggle = () => setOpen((o) => { const n = !o; localStorage.setItem(storeKey, n ? '1' : '0'); return n; });
  return (
    <div className="rounded-xl border border-border bg-card shadow-sm overflow-hidden">
      <button type="button" onClick={toggle}
        className={cn('w-full flex items-center gap-2 px-3 py-2 bg-muted/30 hover:bg-muted/50 transition-colors text-left', open && 'border-b border-border/60')}>
        <Icon className="size-4" style={{ color: accent ?? 'var(--primary)' }} />
        <span className="text-xs font-bold uppercase tracking-wider text-foreground/80">{title}</span>
        <ChevronDown className={cn('ml-auto size-4 text-muted-foreground transition-transform', !open && '-rotate-90')} />
      </button>
      {open && <div className="p-3 space-y-3">{children}</div>}
    </div>
  );
}

// ChannelButton — one of the two RF channels (A / B). Clicking it makes that
// channel active. Shows the source (RF Sense / Flex / CAT…), frequency and
// antenna, matching the two rows of the native 4O3A app.
function ChannelButton({ letter, ch, active, ptt, threeWay, onSelect, t }: {
  letter: 'A' | 'B'; ch: TGChannel; active: boolean; ptt: boolean; threeWay: boolean;
  onSelect: () => void; t: (k: string, v?: any) => string;
}) {
  const cls = ptt
    ? 'bg-gradient-to-b from-red-500 to-rose-600 text-white border-red-400/50 shadow-[0_0_10px_rgba(244,63,94,0.5)]'
    : active
      ? 'bg-gradient-to-b from-emerald-500 to-emerald-600 text-white border-emerald-400/50 shadow-[0_0_9px_rgba(16,185,129,0.4)]'
      : 'bg-card text-foreground/80 border-border hover:bg-muted';
  const src = ch.mode_str || '—';
  const freq = ch.freq_mhz && ch.freq_mhz > 0 ? `${ch.freq_mhz.toFixed(3)} MHz` : '—';
  return (
    <button type="button" onClick={onSelect}
      title={active ? t('tgp.chActive', { letter }) : t('tgp.chSelect', { letter })}
      className={cn('flex-1 min-w-0 rounded-lg border px-2 py-1.5 text-left transition-all active:scale-[0.98]', cls)}>
      <div className="flex items-center gap-1.5">
        <span className="font-extrabold text-sm">{letter}</span>
        <span className="text-[11px] font-semibold truncate opacity-90">{src}</span>
        {ptt && <span className="ml-auto text-[9px] font-bold uppercase">TX</span>}
        {!ptt && active && <span className="ml-auto text-[9px] font-bold uppercase opacity-90">{t('tgp.chActiveTag')}</span>}
      </div>
      <div className="flex items-center gap-1.5 mt-0.5">
        <span className="font-mono text-[11px] tabular-nums truncate">{freq}</span>
        {ch.antenna != null && ch.antenna > 0 && (threeWay || ch.antenna > 0) && (
          <span className="ml-auto text-[10px] font-semibold whitespace-nowrap opacity-90">{t('tgp.ant')} {ch.antenna}</span>
        )}
      </div>
    </button>
  );
}

export function TunerCard({ status, t }: { status: TGStatus; t: (k: string, v?: any) => string }) {
  // Peak-hold, exactly as AmpCard does it. Both cards read the same transmitter,
  // but the tuner is sampled by a 400 ms TCP poll: on SSB that lands in the gaps
  // between syllables as often as on a peak, so the raw reading collapses to zero
  // several times a second mid-transmission and reads as a dropped link. The
  // amplifier looked steady next to it only because it already smoothed this way.
  // Hold the highest value seen, decaying after 2 s so it follows a real drop.
  const peak = useRef<Record<string, { v: number; t: number }>>({});
  const peakHold = (key: string, val: number) => {
    const now = Date.now();
    const p = peak.current[key];
    if (!p || val >= p.v || now - p.t > 1000) { peak.current[key] = { v: val, t: now }; return val; }
    return p.v;
  };

  const connected = !!status.connected;
  const rawVswr = status.vswr && status.vswr > 0 ? status.vswr : undefined;
  // Prefer the device's own peak detector over the sampled reading; the JS hold
  // below still smooths what is left between polls.
  const rawPeak = Math.max(status.peak_w ?? 0, status.fwd_w ?? 0);
  const rawFwdW = rawPeak >= 1 ? rawPeak : 0;
  const fwdW = peakHold('fwd', rawFwdW);

  // SWR needs RF to mean anything: sampled on receive the device reports a
  // meaningless 1.00, which would wipe the figure the operator actually wants —
  // the one measured while transmitting. So show the live value during TX, keep it
  // briefly afterwards so it can be read, then let it go.
  //
  // That expiry is the point: the first version of this held the last TX value
  // with no timeout at all, so the meter sat frozen on the previous transmission
  // indefinitely — reading 1.39:1 with the radio plainly in RX and 0 W forward.
  // Same one-second window as the power peak above, so the two meters clear
  // together.
  const swrHold = useRef<{ v: number; t: number } | null>(null);
  if (rawFwdW >= 1 && rawVswr) swrHold.current = { v: rawVswr, t: Date.now() };
  const heldSwr = swrHold.current;
  const vswr = rawFwdW >= 1
    ? rawVswr
    : heldSwr && Date.now() - heldSwr.t < 1000
      ? heldSwr.v
      : undefined;
  const active = status.active ?? 1;
  const a: TGChannel = status.a ?? {};
  const b: TGChannel = status.b ?? {};

  const title = `${t('tgp.title')}${status.host ? ' · ' + status.host : ''}`;
  return (
    <Card icon={Gauge} title={title} accent="#f59e0b">
      <div className="flex items-center gap-3 flex-wrap">
        <button type="button" disabled={!connected}
          onClick={() => TunerGeniusSetOperate(!status.operate).catch(() => {})}
          className={cn('px-4 py-2 rounded-lg text-sm font-extrabold tracking-wide border-2 transition-all disabled:opacity-30',
            status.operate ? 'bg-warning text-warning-foreground border-warning shadow-[0_0_14px] shadow-warning/50' : 'bg-card text-warning border-warning hover:bg-warning-muted')}>
          {status.operate ? 'OPERATE' : 'STANDBY'}
        </button>
        <button type="button" disabled={!connected}
          onClick={() => TunerGeniusAutotune().catch(() => {})}
          className={cn('inline-flex items-center gap-1.5 px-4 py-2 rounded-lg text-sm font-extrabold tracking-wide border-2 transition-all disabled:opacity-30',
            status.tuning ? 'bg-amber-500 text-white border-amber-500 shadow-[0_0_14px] shadow-amber-500/50 animate-pulse' : 'bg-card text-amber-600 border-amber-500 hover:bg-amber-500/10')}>
          <Radio className="size-4" />{status.tuning ? t('tgp.tuning') : t('tgp.tune')}
        </button>
        <button type="button" disabled={!connected}
          onClick={() => TunerGeniusSetBypass(!status.bypass).catch(() => {})}
          className={cn('px-4 py-2 rounded-lg text-sm font-bold tracking-wide border-2 transition-all disabled:opacity-30',
            status.bypass ? 'bg-sky-500 text-white border-sky-500 shadow-[0_0_12px] shadow-sky-500/40' : 'bg-card text-sky-600 border-sky-500/70 hover:bg-sky-500/10')}>
          {t('tgp.bypass')}
        </button>
        <span className={cn('inline-flex items-center gap-1.5 text-sm', connected ? 'text-muted-foreground' : 'text-danger')}>
          <span className={cn('size-2 rounded-full', connected ? 'bg-success' : 'bg-danger')} />
          {connected ? (status.bypass ? t('tgp.bypassed') : t('tgp.inLine')) : t('tgp.offline')}
        </span>
        <div className="flex-1" />
        {status.message && (
          <span className="px-2 py-1 rounded bg-warning-muted text-warning-muted-foreground text-xs font-bold">⚠ {status.message}</span>
        )}
      </div>

      {connected && (
        <>
          {/* Channel A / B selector — click to make active (activate ch=1/2). */}
          <div className="flex items-stretch gap-2">
            <ChannelButton letter="A" ch={a} active={active === 1} ptt={!!a.ptt} threeWay={!!status.three_way}
              onSelect={() => TunerGeniusActivate(1).catch(() => {})} t={t} />
            <ChannelButton letter="B" ch={b} active={active === 2} ptt={!!b.ptt} threeWay={!!status.three_way}
              onSelect={() => TunerGeniusActivate(2).catch(() => {})} t={t} />
          </div>

          {/* PWR + SWR meters, each taking half the card. The amp card's grid is
              3-wide because it shows three meters; copying it here left the tuner's
              two meters in the first two of three columns, with a third of the card
              empty to the right of SWR. */}
          <div className="grid grid-cols-2 gap-2">
            <MeterBar label={t('tgp.power')} value={fwdW} unit="W" lo={0} hi={2000}
              display={fwdW >= 1 ? `${Math.round(fwdW)} W` : '—'}
              segColor={(f) => (f > 0.9 ? '#dc2626' : f > 0.75 ? '#f59e0b' : '#ea580c')} />
            <MeterBar label={t('tgp.swr')} value={vswr ?? 1} lo={1} hi={3}
              display={vswr ? `${vswr.toFixed(2)}:1` : '—'}
              segColor={(f) => (f > 0.5 ? '#dc2626' : f > 0.25 ? '#f59e0b' : '#16a34a')} />
          </div>
        </>
      )}
    </Card>
  );
}
