import type { ControlOption, ZElement } from './types';
import { useDocumentStore } from '../stores/document';
import { getManifest } from './widgets';

/**
 * Option lists computed in the editor for `select` controls with `optionsFrom` (checked before
 * `window.ZADEX.data[optionsFrom]`). Built in: `loopWidgets` = the loop widgets of the current document
 * (target of the Taxonomy filter widget, T119).
 */
type Source = () => ControlOption[];
const sources = new Map<string, Source>();

export function registerOptionSource(name: string, source: Source): void {
  sources.set(name, source);
}

export function optionSource(name: string): ControlOption[] | undefined {
  const source = sources.get(name);
  if (!source) return undefined;
  try {
    return source();
  } catch {
    return undefined;
  }
}

export const LOOP_TYPES = ['loop-grid', 'loop-carousel', 'posts'];

/** Loop widgets of a tree, in document order (value = element id, label = title + id). */
export function loopWidgetOptions(elements: ZElement[]): ControlOption[] {
  const out: ControlOption[] = [];
  const walk = (list: ZElement[]): void => {
    for (const el of list) {
      if (LOOP_TYPES.includes(el.type)) {
        const title = el.label || getManifest(el.type)?.title || el.type;
        out.push({ value: el.id, label: `${title} (#${el.id})` });
      }
      if (el.children?.length) walk(el.children);
    }
  };
  walk(elements);
  return out;
}

registerOptionSource('loopWidgets', () => [{ value: '', label: '— Select —' }, ...loopWidgetOptions(useDocumentStore().doc.elements)]);
