import { Pipe, type PipeTransform } from '@angular/core';
import { type Option } from '../components/types';

/**
 * Adapts a `T[]` into the `Option[]` shape consumed by the search-select family
 * (`<au-search-select>`, `<au-multiple-search-select>`,
 * `<au-async-search-select>`, `<au-async-multiple-search-select>`).
 *
 * The label is built from a template string with `{<identifier>}` placeholders,
 * mirroring the `front.displayField` semantics on the Aurora schema. Identifier
 * shape (`'name'`) is treated equivalently to `'{name}'`. Anything else in the
 * template is emitted verbatim, so separators like `' - '`, `':'`, or `' / '`
 * are preserved.
 *
 * @example
 * ```html
 * [options]="customerOptions() | toOptions:'name'"
 * [options]="permissionOptions() | toOptions:'{code} - {name}'"
 * ```
 */
@Pipe({ name: 'toOptions', pure: true })
export class ToOptionsPipe implements PipeTransform {
  transform<T extends { id?: string | null }>(
    items: ReadonlyArray<T | null | undefined> | null | undefined,
    template: string = '{name}',
  ): Option[] {
    if (!items) return [];
    const expr = /\{/.test(template) ? template : `{${template}}`;
    return items.flatMap((item) => {
      if (!item?.id) return [];
      const label = expr.replace(/\{(\w+)\}/g, (_, key) => {
        const value = (item as Record<string, unknown>)[key];
        return value == null ? '' : String(value);
      });
      return [{ value: item.id, label }];
    });
  }
}
