import entitiesProps, { TEntityProps } from '../common/entities-props';
import { TOptionizedEntity } from '../types/common';
import { CoreEntity } from '../types/entities';

function convertEntityToOption<R extends any>(
  targetName: string,
  entity: R,
): TOptionizedEntity<R> {
  const entityName = (entity as CoreEntity).__typename;
  const entityProps: TEntityProps = entitiesProps[entityName];
  if (!entityProps) {
    throw new Error(`${entityName} was not found in propsMap!`);
  }

  const {
    name: nameProp,
    getName,
    value: valueProp,
  } = entitiesProps[entityName];

  let name: string = entity[nameProp];
  if (getName) name = getName(entity, targetName);
  const value = entity[valueProp];

  return Object.assign({}, entity, { name, value });
}

export function optionizeEntities<K extends string, R>(
  entities: Partial<Record<K, R | R[]>>,
): Partial<Record<K, TOptionizedEntity<R>[]>> {
  return Object.keys(entities).reduce((acc, targetName) => {
    let target: R[] = entities[targetName];
    if (!Array.isArray(entities[targetName])) target = [entities[targetName]];

    const optionizedEntities = target.map(entity =>
      convertEntityToOption(targetName, entity),
    );
    acc[targetName] = optionizedEntities;
    return acc;
  }, {} as Partial<Record<K, TOptionizedEntity<R>[]>>);
}
