import { Index } from 'flexsearch-ts';
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';

import data from './data';

import type { Emoji } from './index';

const index = new Index({
  tokenize: 'full',
  optimize: true,
  context: true,
});

for (const [key, emoji] of Object.entries(data.emojis)) {
  index.add('n' + key, emoji.name);
}

export interface searchOptions {
  maxResults?: number
  custom?: any
}

export const addCustomToPool = (customEmojis: any[]) => {
  // @ts-ignore
  for (const key in index.register) {
    if (key[0] === 'c') {
      index.remove(key); // remove old custom emojis
    }
  }

  let i = 0;

  for (const emoji of customEmojis) {
    index.add('c' + i++, emoji.id);
  }
};

// we can share an index by prefixing custom emojis with 'c' and native with 'n'
const search = (
  str: string, { maxResults = 5 }: searchOptions = {},
  custom_emojis?: ImmutableList<ImmutableMap<string, string>>,
): Emoji[] => {
  return index.search(str, maxResults)
    .flatMap((id) => {
      if (typeof id !== 'string') return;

      if (id[0] === 'c' && custom_emojis) {
        const index = Number(id.slice(1));
        const custom = custom_emojis.get(index);

        if (custom) {
          return {
            id: custom.get('shortcode', ''),
            colons: ':' + custom.get('shortcode', '') + ':',
            custom: true,
            imageUrl: custom.get('static_url', ''),
          };
        }
      }

      const skins = data.emojis[id.slice(1)]?.skins;

      if (skins) {
        return {
          id: id.slice(1),
          colons: ':' + id.slice(1) + ':',
          unified: skins[0].unified,
          native: skins[0].native,
        };
      }
    }).filter(Boolean) as Emoji[];
};

export default search;
