import { useCallback, useEffect, useState } from 'react';
import {
  Antenna as AntennaIcon, Radio, Plus, Trash2, Star,
  ChevronRight, ChevronDown, Edit2,
} from 'lucide-react';
import {
  ListOperatingTree, SaveOperatingStation, DeleteOperatingStation,
  SaveOperatingAntenna, DeleteOperatingAntenna,
} from '../../wailsjs/go/main/App';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Checkbox } from '@/components/ui/checkbox';
import { cn } from '@/lib/utils';
import { useI18n } from '@/lib/i18n';

type Band = { band: string; is_default: boolean };
type Antenna = {
  id: number;
  station_id: number;
  name: string;
  sort_order: number;
  bands: Band[];
};
type Station = {
  id: number;
  profile_id: number;
  name: string;
  tx_pwr?: number;
  sort_order: number;
  antennas?: Antenna[];
};

type Props = {
  /** ADIF bands available to toggle, in display order (from ListsSettings). */
  bands: string[];
  /** External error sink — parent shows it next to the Save button. */
  onError: (msg: string) => void;
};

export function OperatingPanel({ bands, onError }: Props) {
  const { t } = useI18n();
  const [tree, setTree] = useState<Station[]>([]);
  const [loading, setLoading] = useState(true);
  // expanded keeps which stations show their antennas; everything open by
  // default so the user sees the full setup at a glance.
  const [expanded, setExpanded] = useState<Set<number>>(new Set());
  // editingId tracks the row currently in edit mode. Use a string namespace
  // to keep station ids and antenna ids in the same Set.
  const [editing, setEditing] = useState<string | null>(null);

  const reload = useCallback(async () => {
    try {
      const t = await ListOperatingTree();
      const list = (t ?? []) as Station[];
      setTree(list);
      setExpanded((prev) => {
        if (prev.size > 0) return prev;
        return new Set(list.map((s) => s.id));
      });
    } catch (e: any) {
      onError(String(e?.message ?? e));
    } finally {
      setLoading(false);
    }
  }, [onError]);

  useEffect(() => { void reload(); }, [reload]);

  function toggleExpanded(id: number) {
    setExpanded((prev) => {
      const next = new Set(prev);
      if (next.has(id)) next.delete(id); else next.add(id);
      return next;
    });
  }

  async function addStation() {
    try {
      const created = await SaveOperatingStation({
        id: 0, profile_id: 0, name: 'New rig', sort_order: tree.length,
      } as any);
      const c = created as Station;
      setTree((prev) => [...prev, { ...c, antennas: [] }]);
      setExpanded((prev) => new Set(prev).add(c.id));
      setEditing(`station:${c.id}`);
    } catch (e: any) { onError(String(e?.message ?? e)); }
  }
  async function updateStation(s: Station) {
    try {
      const saved = await SaveOperatingStation(s as any) as Station;
      setTree((prev) => prev.map((x) => x.id === s.id ? { ...x, ...saved } : x));
    } catch (e: any) { onError(String(e?.message ?? e)); }
  }
  async function removeStation(id: number) {
    if (!confirm('Delete this rig and all its antennas?')) return;
    try {
      await DeleteOperatingStation(id);
      setTree((prev) => prev.filter((s) => s.id !== id));
    } catch (e: any) { onError(String(e?.message ?? e)); }
  }

  async function addAntenna(stationId: number) {
    try {
      const created = await SaveOperatingAntenna({
        id: 0, station_id: stationId, name: 'New antenna', sort_order: 0, bands: [],
      } as any) as Antenna;
      setTree((prev) => prev.map((s) =>
        s.id === stationId
          ? { ...s, antennas: [...(s.antennas ?? []), created] }
          : s
      ));
      setEditing(`antenna:${created.id}`);
    } catch (e: any) { onError(String(e?.message ?? e)); }
  }
  async function updateAntenna(a: Antenna) {
    try {
      const saved = await SaveOperatingAntenna(a as any) as Antenna;
      setTree((prev) => prev.map((s) => s.id === a.station_id
        ? {
            ...s,
            antennas: (s.antennas ?? []).map((x) => x.id === a.id ? saved : x),
          }
        : {
            // The save may have cleared is_default on antennas of OTHER
            // stations (one default per band per profile). Refresh those
            // by reloading the tree wholesale.
            ...s,
          }
      ));
      // Reload to pick up cross-station default flips.
      void reload();
    } catch (e: any) { onError(String(e?.message ?? e)); }
  }
  async function removeAntenna(stationId: number, antId: number) {
    if (!confirm(t('op.deleteAntConfirm'))) return;
    try {
      await DeleteOperatingAntenna(antId);
      setTree((prev) => prev.map((s) =>
        s.id === stationId
          ? { ...s, antennas: (s.antennas ?? []).filter((a) => a.id !== antId) }
          : s
      ));
    } catch (e: any) { onError(String(e?.message ?? e)); }
  }

  if (loading) {
    return <div className="text-xs text-muted-foreground italic">Loading…</div>;
  }

  return (
    <div className="space-y-3">
      <div className="text-[11px] text-muted-foreground max-w-2xl leading-relaxed">
        {t('op.intro1')}<Star className="inline size-3 text-warning fill-current align-text-bottom" />{t('op.intro2')}
      </div>

      <div className="flex gap-2">
        <Button size="sm" onClick={addStation}>
          <Plus className="size-3.5" /> {t('op.addRig')}
        </Button>
      </div>

      {tree.length === 0 ? (
        <div className="rounded-md border border-dashed border-border/70 px-4 py-8 text-center text-xs text-muted-foreground italic">
          {t('op.noRig')}
        </div>
      ) : (
        <div className="space-y-2">
          {tree.map((station) => (
            <StationRow
              key={station.id}
              station={station}
              bands={bands}
              expanded={expanded.has(station.id)}
              editing={editing}
              setEditing={setEditing}
              onToggleExpanded={() => toggleExpanded(station.id)}
              onUpdate={updateStation}
              onDelete={() => removeStation(station.id)}
              onAddAntenna={() => addAntenna(station.id)}
              onUpdateAntenna={updateAntenna}
              onDeleteAntenna={(antId) => removeAntenna(station.id, antId)}
            />
          ))}
        </div>
      )}
    </div>
  );
}

// ── Station row ────────────────────────────────────────────────────────

type StationRowProps = {
  station: Station;
  bands: string[];
  expanded: boolean;
  editing: string | null;
  setEditing: (id: string | null) => void;
  onToggleExpanded: () => void;
  onUpdate: (s: Station) => void;
  onDelete: () => void;
  onAddAntenna: () => void;
  onUpdateAntenna: (a: Antenna) => void;
  onDeleteAntenna: (antId: number) => void;
};

function StationRow({
  station, bands, expanded, editing, setEditing,
  onToggleExpanded, onUpdate, onDelete, onAddAntenna,
  onUpdateAntenna, onDeleteAntenna,
}: StationRowProps) {
  const { t } = useI18n();
  const editKey = `station:${station.id}`;
  const isEditing = editing === editKey;
  const [draft, setDraft] = useState({
    name: station.name,
    tx_pwr: station.tx_pwr != null ? String(station.tx_pwr) : '',
  });
  useEffect(() => {
    if (!isEditing) setDraft({
      name: station.name,
      tx_pwr: station.tx_pwr != null ? String(station.tx_pwr) : '',
    });
  }, [isEditing, station.name, station.tx_pwr]);

  function commit() {
    const pwrNum = draft.tx_pwr.trim() === '' ? undefined : parseFloat(draft.tx_pwr);
    onUpdate({
      ...station,
      name: draft.name.trim() || station.name,
      tx_pwr: Number.isFinite(pwrNum as number) ? (pwrNum as number) : undefined,
    });
    setEditing(null);
  }

  return (
    <div className="rounded-md border border-border bg-card">
      <div className="flex items-center gap-2 px-2 py-1.5 border-b border-border/60 bg-muted/30">
        <button
          type="button"
          onClick={onToggleExpanded}
          className="p-0.5 hover:bg-accent/40 rounded"
          title={expanded ? t('op.collapse') : t('op.expand')}
        >
          {expanded ? <ChevronDown className="size-3.5" /> : <ChevronRight className="size-3.5" />}
        </button>
        <Radio className="size-4 text-muted-foreground" />

        {isEditing ? (
          <div className="flex items-center gap-2 flex-1">
            <Input
              autoFocus
              className="h-7 text-sm flex-1"
              placeholder={t('op.rigNamePh')}
              value={draft.name}
              onChange={(e) => setDraft((d) => ({ ...d, name: e.target.value }))}
              onKeyDown={(e) => { if (e.key === 'Enter') commit(); if (e.key === 'Escape') setEditing(null); }}
            />
            <Label className="text-[11px] text-muted-foreground">{t('op.powerW')}</Label>
            <Input
              type="number"
              min={0}
              step={1}
              className="h-7 text-sm w-20 font-mono"
              placeholder="100"
              value={draft.tx_pwr}
              onChange={(e) => setDraft((d) => ({ ...d, tx_pwr: e.target.value }))}
              onKeyDown={(e) => { if (e.key === 'Enter') commit(); if (e.key === 'Escape') setEditing(null); }}
            />
            <Button size="sm" onClick={commit}>{t('btn.save')}</Button>
            <Button size="sm" variant="ghost" onClick={() => setEditing(null)}>{t('btn.cancel')}</Button>
          </div>
        ) : (
          <>
            <span className="font-semibold text-sm">{station.name}</span>
            {station.tx_pwr != null && (
              <span className="text-[11px] text-muted-foreground font-mono">{station.tx_pwr} W</span>
            )}
            <div className="flex-1" />
            <Button size="icon" variant="ghost" className="size-6" onClick={() => setEditing(editKey)} title={t('op.edit')}>
              <Edit2 className="size-3" />
            </Button>
            <Button size="sm" variant="outline" className="h-6 text-xs" onClick={onAddAntenna}>
              <Plus className="size-3" /> {t('op.antenna')}
            </Button>
            <Button size="icon" variant="ghost" className="size-6 text-destructive hover:bg-destructive/10" onClick={onDelete} title={t('op.deleteRig')}>
              <Trash2 className="size-3" />
            </Button>
          </>
        )}
      </div>

      {expanded && (
        <div className="p-2 space-y-2">
          {(station.antennas ?? []).length === 0 ? (
            <div className="text-[11px] text-muted-foreground italic pl-6">
              {t('op.noAntenna')}
            </div>
          ) : (
            (station.antennas ?? []).map((a) => (
              <AntennaRow
                key={a.id}
                antenna={a}
                bands={bands}
                editing={editing}
                setEditing={setEditing}
                onUpdate={onUpdateAntenna}
                onDelete={() => onDeleteAntenna(a.id)}
              />
            ))
          )}
        </div>
      )}
    </div>
  );
}

// ── Antenna row ────────────────────────────────────────────────────────

type AntennaRowProps = {
  antenna: Antenna;
  bands: string[];
  editing: string | null;
  setEditing: (id: string | null) => void;
  onUpdate: (a: Antenna) => void;
  onDelete: () => void;
};

function AntennaRow({ antenna, bands, editing, setEditing, onUpdate, onDelete }: AntennaRowProps) {
  const { t } = useI18n();
  const editKey = `antenna:${antenna.id}`;
  const isEditing = editing === editKey;
  const [draft, setDraft] = useState({ name: antenna.name });
  useEffect(() => {
    if (!isEditing) setDraft({ name: antenna.name });
  }, [isEditing, antenna.name]);

  const enabledBands = new Map<string, Band>(
    (antenna.bands ?? []).map((b) => [b.band, b])
  );

  function commitNames() {
    onUpdate({
      ...antenna,
      name: draft.name.trim() || antenna.name,
      bands: antenna.bands ?? [],
    });
    setEditing(null);
  }

  function toggleBand(band: string, on: boolean) {
    let next = [...(antenna.bands ?? [])];
    if (on) {
      if (!next.find((b) => b.band === band)) {
        next.push({ band, is_default: false });
      }
    } else {
      next = next.filter((b) => b.band !== band);
    }
    onUpdate({ ...antenna, bands: next });
  }

  function setDefault(band: string, isDefault: boolean) {
    const next = (antenna.bands ?? []).map((b) =>
      b.band === band ? { ...b, is_default: isDefault } : b
    );
    onUpdate({ ...antenna, bands: next });
  }

  return (
    <div className="rounded border border-border/70 bg-muted/10">
      <div className="flex items-center gap-2 px-2 py-1.5">
        <AntennaIcon className="size-3.5 text-muted-foreground ml-3" />
        {isEditing ? (
          <div className="flex items-center gap-2 flex-1">
            <Input
              autoFocus
              className="h-7 text-sm flex-1"
              placeholder={t('op.antNamePh')}
              value={draft.name}
              onChange={(e) => setDraft((d) => ({ ...d, name: e.target.value }))}
              onKeyDown={(e) => { if (e.key === 'Enter') commitNames(); if (e.key === 'Escape') setEditing(null); }}
            />
            <Button size="sm" onClick={commitNames}>{t('btn.save')}</Button>
            <Button size="sm" variant="ghost" onClick={() => setEditing(null)}>{t('btn.cancel')}</Button>
          </div>
        ) : (
          <>
            <span className="text-sm font-medium">{antenna.name}</span>
            <div className="flex-1" />
            <Button size="icon" variant="ghost" className="size-6" onClick={() => setEditing(editKey)}>
              <Edit2 className="size-3" />
            </Button>
            <Button size="icon" variant="ghost" className="size-6 text-destructive hover:bg-destructive/10" onClick={onDelete}>
              <Trash2 className="size-3" />
            </Button>
          </>
        )}
      </div>

      <div className="px-3 pb-2 pl-8 flex flex-wrap gap-1.5">
        {bands.length === 0 ? (
          <span className="text-[10px] text-muted-foreground italic">No band configured in Settings → Bands.</span>
        ) : bands.map((band) => {
          const entry = enabledBands.get(band);
          const enabled = !!entry;
          const isDefault = !!entry?.is_default;
          return (
            <div
              key={band}
              className={cn(
                'flex items-center gap-1.5 px-2 py-1 rounded text-[11px] font-mono border transition-colors',
                isDefault
                  ? 'border-warning-border bg-warning-muted shadow-sm'
                  : enabled
                    ? 'border-primary/30 bg-primary/5'
                    : 'border-border/50 bg-muted/30 text-muted-foreground'
              )}
            >
              <Checkbox
                checked={enabled}
                onCheckedChange={(c) => toggleBand(band, !!c)}
                className="size-3"
              />
              <span className={isDefault ? 'font-semibold' : undefined}>{band}</span>
              {enabled && (
                <button
                  type="button"
                  onClick={() => setDefault(band, !isDefault)}
                  className={cn(
                    'flex items-center gap-0.5 ml-1 px-1.5 py-0.5 rounded transition-colors',
                    isDefault
                      ? 'bg-warning text-warning-foreground'
                      : 'border border-dashed border-muted-foreground/40 text-muted-foreground hover:border-warning hover:text-warning',
                  )}
                  title={isDefault ? t('op.defaultOn') : t('op.defaultOff')}
                >
                  <Star className={cn('size-3', isDefault && 'fill-current')} />
                  <span className="text-[9px] font-bold uppercase tracking-wider">
                    {isDefault ? t('op.default') : t('op.set')}
                  </span>
                </button>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}
