import type { ReactElement } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { View } from 'react-native';
import { useTheme } from '../../theme';
import { emitter } from './EditorEvent';
import * as Events from './utils/events';

const isEmptyString = (s: string | null): boolean => !s || s.length === 0;

interface OnSelectOptionsType<TMetaData> {
  highlighted: boolean;
  meta?: TMetaData;
}

export interface MentionListProps<TMetaData = unknown> {
  /**
   * Unique name used to communicate with webview, should be the same with the RichTextEditor component it used with
   */
  name: string;
  /**
   * Function used to render mention options
   */
  render: (
    searchText: string,
    onSelect: (
      id: string,
      name: string,
      options?: OnSelectOptionsType<TMetaData>
    ) => void
  ) => ReactElement;
}

const MentionList = <TMetaData,>({
  name: eventPrefix,
  render,
}: MentionListProps<TMetaData>) => {
  const theme = useTheme();
  const [search, setSearch] = useState<string>('');
  const [target, setTarget] = useState<string | null>(null);
  const normalizeEventName = useCallback(
    (event: string) => `${eventPrefix}/${event}`,
    [eventPrefix]
  );

  useEffect(() => {
    const removeMentionSearchListener = Events.on(
      emitter,
      normalizeEventName('mention-search'),
      ({
        search: nextSearch,
        target: nextTarget,
      }: {
        search?: string;
        target?: string;
      }) => {
        setSearch(nextSearch || '');
        setTarget(nextTarget || null);
      }
    );

    return () => {
      removeMentionSearchListener();
    };
  }, []);

  if (isEmptyString(search)) {
    return null;
  }

  return (
    <View>
      {render(search, (id, name, options = { highlighted: false }) => {
        const { highlighted, meta } = options;

        const highlightStyle = {
          color: theme.colors.primary,
          borderRadius: theme.__hd__.richTextEditor.radii.mention,
          padding: highlighted ? theme.__hd__.richTextEditor.space.mention : 0,
          background: highlighted
            ? theme.colors.highlightedSurface
            : 'transparent',
          marginTop: theme.space.xxsmall,
          marginBottom: theme.space.xxsmall,
          display: 'inline-flex',
        };
        const data = {
          id,
          name,
          target,
          meta,
          style: highlightStyle,
        };

        Events.emit(emitter, normalizeEventName('mention-apply'), data);
      })}
    </View>
  );
};

export default MentionList;
