import { useEffect, useState } from 'react';
import { getSearchFields, type SearchField } from '../../api/search';
import type { FieldType } from './types';

// Clean, non-null field the builder UI consumes (SearchField from the generated client is all-nullable
// because ErsatzTV.Core compiles with <Nullable>disable</Nullable>).
export interface RuleField {
  name: string;
  label: string;
  type: FieldType;
  group: string;
  values: string[];
}

export interface FieldCatalog {
  fields: RuleField[];
  fieldTypes: Record<string, FieldType>;
  byGroup: Array<{ group: string; fields: RuleField[] }>;
  status: 'loading' | 'success' | 'error';
}

// Coerce a nullable generated SearchField into a clean RuleField; drop entries with no name.
function toRuleField(f: SearchField): RuleField | null {
  if (!f.name) return null;
  return {
    name: f.name,
    label: f.label ?? f.name,
    type: (f.type as FieldType | null) ?? 'text',
    group: f.group ?? 'Other',
    values: f.values ?? []
  };
}

// Field-catalog client for the rule builder (#176): fetches the server field list once and reshapes it
// into the two views the builder UI needs — a name -> FieldType lookup and a group -> fields listing.
export function useSearchFields(): FieldCatalog {
  const [raw, setRaw] = useState<SearchField[]>([]);
  const [status, setStatus] = useState<'loading' | 'success' | 'error'>('loading');

  useEffect(() => {
    let active = true;
    getSearchFields()
      .then((f) => { if (active) { setRaw(f); setStatus('success'); } })
      .catch(() => { if (active) setStatus('error'); });
    return () => { active = false; };
  }, []);

  const fields = raw.map(toRuleField).filter((f): f is RuleField => f !== null);

  const fieldTypes: Record<string, FieldType> = {};
  for (const f of fields) fieldTypes[f.name] = f.type;

  const groups = new Map<string, RuleField[]>();
  for (const f of fields) {
    const list = groups.get(f.group) ?? [];
    list.push(f);
    groups.set(f.group, list);
  }
  const byGroup = [...groups.entries()].map(([group, gf]) => ({ group, fields: gf }));

  return { fields, fieldTypes, byGroup, status };
}
