import { useMemo } from 'react';
import { Star, Radio } from 'lucide-react';
import { Badge } from '@/components/ui/badge';
import { cn } from '@/lib/utils';
import type { WorkedBeforeView } from '@/types';

type WorkedBefore = WorkedBeforeView;

interface Props {
  wb: WorkedBefore | null;
  busy: boolean;
  currentBand: string;
  currentMode: string;
  bands?: string[]; // operator's configured bands; falls back to DEFAULT_BANDS
}

// Compact column label for a band tag: keep the classic V/U for 2m/70cm,
// strip the trailing "m" for meter bands (160m→160), and shorten cm bands
// (13cm→13c) so the column stays narrow.
function bandColLabel(tag: string): string {
  if (tag === '2m') return 'V';
  if (tag === '70cm') return 'U';
  if (tag.endsWith('cm')) return tag.replace('cm', 'c');
  return tag.replace(/m$/, '');
}

// Default 13-column band layout, used when the operator hasn't configured bands.
const DEFAULT_BANDS: { tag: string; label: string }[] = [
  { tag: '160m', label: '160' },
  { tag: '80m',  label: '80'  },
  { tag: '60m',  label: '60'  },
  { tag: '40m',  label: '40'  },
  { tag: '30m',  label: '30'  },
  { tag: '20m',  label: '20'  },
  { tag: '17m',  label: '17'  },
  { tag: '15m',  label: '15'  },
  { tag: '12m',  label: '12'  },
  { tag: '10m',  label: '10'  },
  { tag: '6m',   label: '6'   },
  { tag: '2m',   label: 'V'   },
  { tag: '70cm', label: 'U'   },
];
const CLASSES = ['PH', 'CW', 'DIG'] as const;

const PHONE_MODES = new Set(['SSB','USB','LSB','AM','FM','DIGITALVOICE','PHONE']);
function classMatchesMode(cls: string, mode: string): boolean {
  const u = (mode || '').toUpperCase();
  if (cls === 'PH') return PHONE_MODES.has(u);
  if (cls === 'CW') return u === 'CW';
  return u !== '' && u !== 'CW' && !PHONE_MODES.has(u);
}

const STATUS_CLASSES: Record<string, string> = {
  call_c: 'bg-emerald-700 hover:bg-emerald-600',
  call_w: 'bg-emerald-300 hover:bg-emerald-200',
  dxcc_c: 'bg-indigo-800 hover:bg-indigo-700',
  dxcc_w: 'bg-indigo-300 hover:bg-indigo-200',
};

// Legend entries, in the same colour order as the cells. swatch = the
// background class (or a special ring marker for the current-entry cell).
const LEGEND: { swatch: string; ring?: boolean; label: string }[] = [
  { swatch: 'bg-emerald-700', label: 'Call confirmed' },
  { swatch: 'bg-emerald-300', label: 'Call worked' },
  { swatch: 'bg-indigo-800', label: 'Entity confirmed' },
  { swatch: 'bg-indigo-300', label: 'Entity worked' },
  { swatch: 'bg-stone-200', label: 'Not worked' },
  { swatch: 'bg-stone-200', ring: true, label: 'Current entry' },
];

function cellTitle(band: string, cls: string, status: string, current: boolean): string {
  const desc =
    status === 'call_c' ? 'This callsign confirmed' :
    status === 'call_w' ? 'This callsign worked (not confirmed)' :
    status === 'dxcc_c' ? 'Entity confirmed (other callsign)' :
    status === 'dxcc_w' ? 'Entity worked (other callsign)' :
                          'Never worked';
  return `${band} ${cls}: ${desc}${current ? ' — current entry' : ''}`;
}

export function BandSlotGrid({ wb, busy, currentBand, currentMode, bands }: Props) {
  // Columns from the operator's configured bands (so the matrix shows only the
  // bands they actually use), falling back to the built-in default set.
  const cols = useMemo(
    () => (bands && bands.length ? bands.map((tag) => ({ tag, label: bandColLabel(tag) })) : DEFAULT_BANDS),
    [bands],
  );
  const dxcc = wb?.dxcc ?? 0;
  const dxccName = wb?.dxcc_name ?? '';
  const dxccCount = wb?.dxcc_count ?? 0;
  const callCount = wb?.count ?? 0; // QSOs with this exact callsign
  const hasDxcc = dxcc > 0;
  const newOne = hasDxcc && dxccCount === 0;

  const statusMap = useMemo(() => {
    const m = new Map<string, string>();
    for (const s of wb?.band_status ?? []) {
      m.set(`${s.band}|${s.class}`, s.status);
    }
    return m;
  }, [wb]);

  return (
    <section
      className={cn(
        'flex items-center gap-4 px-3 py-2 flex-wrap shrink-0',
        newOne && 'bg-gradient-to-br from-amber-100 to-amber-200 rounded-lg',
      )}
    >
      <div className="flex items-center gap-2 min-w-[220px]">
        {newOne ? (
          <>
            <Badge className="bg-amber-800 text-amber-50 gap-1 px-3 py-1 text-[11px]">
              <Star className="size-3 fill-current" />
              NEW ONE
            </Badge>
            <span className="text-xs text-amber-900">
              <strong className="text-amber-950 font-semibold">{dxccName || `DXCC #${dxcc}`}</strong>
              {' '}· never worked this entity
            </span>
          </>
        ) : hasDxcc ? (
          <>
            <Badge className="bg-primary text-primary-foreground px-3 py-1 text-xs normal-case font-semibold tracking-normal">
              {dxccName || `DXCC #${dxcc}`}
            </Badge>
            <span className="text-xs text-muted-foreground">
              <strong className="text-foreground font-semibold">{dxccCount}</strong>{' '}
              QSO{dxccCount > 1 ? 's' : ''} with this entity
              {callCount > 0 && (
                <>
                  {' · '}
                  <strong className="text-foreground font-semibold">{callCount}</strong>{' '}
                  with this call
                </>
              )}
            </span>
          </>
        ) : busy ? (
          <span className="flex items-center gap-2 text-xs text-muted-foreground italic">
            <Radio className="size-3.5 animate-pulse" />
            looking up…
          </span>
        ) : (
          <span className="text-xs text-muted-foreground italic">
            Type a callsign to see entity stats
          </span>
        )}
      </div>

      <div className="flex flex-col gap-2">
      <table className="border-separate" style={{ borderSpacing: 3 }}>
        <thead>
          <tr>
            <th className="w-[26px]" />
            {cols.map((b) => (
              <th
                key={b.tag}
                className={cn(
                  'font-mono text-[11px] font-semibold px-1 text-center',
                  b.tag === currentBand ? 'text-primary font-extrabold' : 'text-muted-foreground',
                )}
              >
                {b.label}
              </th>
            ))}
          </tr>
        </thead>
        <tbody>
          {CLASSES.map((cls) => {
            const classCurrent = classMatchesMode(cls, currentMode);
            return (
              <tr key={cls}>
                <th
                  className={cn(
                    'font-mono text-[11px] font-semibold pr-1.5 text-right w-[26px]',
                    classCurrent ? 'text-primary font-extrabold' : 'text-muted-foreground',
                  )}
                >
                  {cls}
                </th>
                {cols.map((b) => {
                  const st = statusMap.get(`${b.tag}|${cls}`) ?? '';
                  const isCurrent = b.tag === currentBand && classCurrent;
                  return (
                    <td
                      key={b.tag}
                      title={cellTitle(b.tag, cls, st, isCurrent)}
                      className={cn(
                        'w-[28px] h-[24px] rounded transition-colors p-0',
                        st ? STATUS_CLASSES[st] : 'bg-stone-200 hover:bg-stone-300',
                        isCurrent && 'ring-2 ring-amber-500 ring-inset',
                      )}
                    />
                  );
                })}
              </tr>
            );
          })}
        </tbody>
      </table>

      {/* Colour legend — sits in the spare room under the matrix. */}
      <div className="flex items-center gap-x-3 gap-y-1 flex-wrap pl-[26px]">
        {LEGEND.map((l) => (
          <span key={l.label} className="flex items-center gap-1.5 text-[10px] text-muted-foreground">
            <span
              className={cn(
                'inline-block size-3 rounded shrink-0',
                l.swatch,
                l.ring && 'ring-2 ring-amber-500 ring-inset',
              )}
            />
            {l.label}
          </span>
        ))}
      </div>
      </div>
    </section>
  );
}
