import { useEffect, useMemo, useState } from 'react';
import { X, Plus } from 'lucide-react';
import { ADIFFields } from '../../wailsjs/go/main/App';
import { Input } from '@/components/ui/input';
import { Combobox } from '@/components/ui/combobox';
import { Button } from '@/components/ui/button';

type FieldDef = {
  name: string; kind: string; category: string;
  promoted: boolean; deprecated: boolean; intl: boolean;
};

interface Props {
  // The QSO's extras map (uppercase ADIF tag → raw value).
  value: Record<string, string> | undefined;
  onChange: (next: Record<string, string> | undefined) => void;
}

// AdifExtrasEditor — a dictionary-driven editor for every ADIF field that is
// NOT promoted to a first-class column. Backed by the QSO's extras map, so any
// ADIF 3.1.7 field (plus custom/vendor tags) can be viewed and edited. This is
// what makes "100% of ADIF fields available" true without 160 DB columns.
export function AdifExtrasEditor({ value, onChange }: Props) {
  const [dict, setDict] = useState<FieldDef[]>([]);
  const [showDeprecated, setShowDeprecated] = useState(false);

  useEffect(() => {
    ADIFFields().then((f) => setDict((f ?? []) as any)).catch(() => {});
  }, []);

  // Entries currently set, sorted for stable display.
  const entries = useMemo(
    () => Object.entries(value ?? {}).sort((a, b) => a[0].localeCompare(b[0])),
    [value],
  );

  // Addable fields: standard non-promoted ADIF fields not already present.
  // Deprecated (import-only) fields are hidden unless the toggle is on.
  const addable = useMemo(() => {
    const have = new Set(Object.keys(value ?? {}));
    return dict
      .filter((f) => !f.promoted && !have.has(f.name) && (showDeprecated || !f.deprecated))
      .map((f) => f.name);
  }, [dict, value, showDeprecated]);

  const meta = useMemo(() => {
    const m: Record<string, FieldDef> = {};
    for (const f of dict) m[f.name] = f;
    return m;
  }, [dict]);

  function setKV(key: string, val: string) {
    const next = { ...(value ?? {}) };
    next[key] = val;
    onChange(next);
  }
  function remove(key: string) {
    const next = { ...(value ?? {}) };
    delete next[key];
    onChange(Object.keys(next).length ? next : undefined);
  }
  function addField(name: string) {
    const key = name.trim().toUpperCase();
    if (!key || (value && key in value)) return;
    setKV(key, '');
  }

  return (
    <div className="space-y-3">
      <p className="text-xs text-muted-foreground">
        Every ADIF 3.1.7 field not shown in the other tabs. Pick a field to add it,
        or type a custom/vendor tag (e.g. <code className="bg-muted px-1 rounded font-mono">APP_*</code>).
        Stored losslessly and exported in the <strong>full</strong> ADIF mode.
      </p>

      {/* Add a field */}
      <div className="flex items-center gap-2">
        <div className="flex-1 max-w-xs">
          <Combobox
            value=""
            options={addable}
            placeholder="Add ADIF field…"
            allowFreeText
            onChange={addField}
          />
        </div>
        <label className="flex items-center gap-1.5 text-[11px] text-muted-foreground cursor-pointer">
          <input type="checkbox" checked={showDeprecated} onChange={(e) => setShowDeprecated(e.target.checked)} />
          Show deprecated
        </label>
      </div>

      {/* Current entries */}
      {entries.length === 0 ? (
        <div className="text-[11px] text-muted-foreground italic border border-dashed border-border rounded-md px-3 py-4 text-center">
          No extra ADIF fields. Use the picker above to add one.
        </div>
      ) : (
        <div className="space-y-1.5">
          {entries.map(([k, v]) => {
            const def = meta[k];
            return (
              <div key={k} className="flex items-center gap-2">
                <div className="w-48 shrink-0">
                  <span className="font-mono text-xs font-semibold">{k}</span>
                  {def && (
                    <span className="block text-[10px] text-muted-foreground leading-tight">
                      {def.category}{def.deprecated ? ' · deprecated' : ''}{def.intl ? ' · intl' : ''}
                      {!def && ''}
                    </span>
                  )}
                  {!def && <span className="block text-[10px] text-amber-600 leading-tight">non-standard</span>}
                </div>
                <Input
                  className="flex-1 h-8 text-xs font-mono"
                  value={v}
                  onChange={(e) => setKV(k, e.target.value)}
                />
                <Button
                  type="button" variant="ghost" size="icon" className="h-7 w-7 shrink-0 text-muted-foreground hover:text-destructive"
                  onClick={() => remove(k)} title="Remove field"
                >
                  <X className="size-3.5" />
                </Button>
              </div>
            );
          })}
        </div>
      )}
    </div>
  );
}
