/* eslint-disable import/no-unresolved */
import YAML from 'js-yaml';
import uniqBy from 'lodash/uniqBy';
import { SnackbarProvider, enqueueSnackbar } from 'notistack';
import React, { FC, useMemo } from 'react';

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
import iconConfigYaml from '../../icons.config.yaml?raw';
import * as reactIcons from '../react';
import { IconProps } from '../types';
import './SearchComponent.css';

// eslint-disable-next-line prettier/prettier
const iconLib = reactIcons as unknown as { [key: string]: FC<IconProps> & { iconName: string } };

interface IconConfig {
  [Icon: string]: {
    name: string;
    tags: string[];
    aliases: string[];
  };
}
const iconConfig = YAML.load(iconConfigYaml) as IconConfig;

export const SearchComponent = () => {
  const [searchTerm, setSearchTerm] = React.useState('');

  const icons = useMemo(() => {
    const iconComponents = Object.keys(iconConfig)
      .filter((iconName) => {
        if (searchTerm) {
          return iconConfig[iconName].aliases?.some((alias) => alias.toLowerCase().includes(searchTerm.toLowerCase()));
        }

        return true;
      })
      .filter((iconName) => iconLib[iconName] !== undefined)
      .map((iconName) => ({ Component: iconLib[iconName], ...iconConfig[iconName] }));

    // exact match
    const exactMatch = iconComponents.find(({ name }) => name.toLowerCase() === searchTerm.toLowerCase());
    if (searchTerm && exactMatch) {
      iconComponents.unshift(exactMatch);
    }

    return uniqBy(iconComponents, 'name');
  }, [searchTerm]);

  const copyNameToClipboard = (name: string) => {
    navigator.clipboard.writeText(name);
    enqueueSnackbar(`Copied "${name}" to clipboard`, {
      variant: 'success',
      anchorOrigin: { vertical: 'top', horizontal: 'center' },
    });
  };

  return (
    <div className="search-component">
      <SnackbarProvider />

      <div className="search-component__input">
        <input
          type="text"
          placeholder="Search by name..."
          value={searchTerm}
          onChange={(e) => setSearchTerm(e.target.value)}
        />
        <span className="search-component__search_icon">
          <reactIcons.Search fill="#888" />
        </span>
      </div>

      <div className="search-component__count">{icons.length} icons</div>

      <div className="search-component__icons">
        {icons.map(({ Component: IconComponent, name }) => (
          <div className="search-component__icon" title={name} key={name} onClick={() => copyNameToClipboard(name)}>
            <div className="search-component__icon_icon">
              <IconComponent width={24} height={24} />
            </div>

            <div className="search-component__icon_title">{name}</div>
          </div>
        ))}
      </div>
    </div>
  );
};
