import { IShape } from '@vev/utils';
import React, { useEffect, useState } from 'react';
import { SilkeBox } from '../silke-box';
import { SilkeButton } from '../silke-button';
import ButtonContext from '../silke-button/context';
import { SilkeSearchField } from '../silke-search-field';
import { SilkeToolbar } from '../silke-toolbar';
import { SilkeVirtualGrid } from '../silke-virtual';
import { TabProps } from './utils';

let iconsPromise: Promise<IShape[]>;

async function fetchIcons(): Promise<IShape[]> {
  if (!iconsPromise) {
    iconsPromise = fetch('https://cdn.vev.design/icons/fontawesome-v7.json')
      .then((r) => r.json() as Promise<IShape[]>)
      .then((res) => res.sort((i1, i2) => ((i1.name || '') < (i2.name || '') ? -1 : 1)));
  }
  return iconsPromise;
}

function isIconMatch(icon: IShape, reg: RegExp) {
  if (icon.name && reg.test(icon.name)) return true;

  if (icon.tags) {
    for (const tag of icon.tags) {
      if (reg.test(tag)) return true;
    }
  }

  return false;
}

export default function IconsTab({ onSelect }: TabProps) {
  const [icons, setIcons] = useState<IShape[] | null>(null);
  const [query, setQuery] = useState('');
  useEffect(() => {
    fetchIcons().then(setIcons);
  }, []);

  const filtered = React.useMemo(() => {
    if (!query || !icons) {
      return icons || [];
    }

    const terms = query
      .split(/\s+/)
      .map((term) => `(?=.*${term})`)
      .join('');

    const reg = new RegExp(terms, 'i');

    return icons.filter((icon) => isIconMatch(icon, reg));
  }, [query, icons]);

  return (
    <ButtonContext size="base" kind="ghost">
      <SilkeToolbar size="base">
        <SilkeSearchField
          placeholder="Search icons..."
          autoFocus
          flex
          size="base"
          search={query}
          onChange={setQuery}
          onReset={() => setQuery('')}
        />
        <SilkeButton
          label="Randomize"
          icon="random"
          onClick={() =>
            icons &&
            onSelect({ type: 1, value: icons[Math.round(Math.random() * (icons.length - 1))].path })
          }
        />
      </SilkeToolbar>
      <SilkeBox column gap="s" pad="m" flex scroll>
        {!icons && (
          <SilkeBox gap="xxs">
            <SilkeButton icon="history" loading />
            <SilkeButton icon="history" loading />
            <SilkeButton icon="history" loading />
          </SilkeBox>
        )}
        <SilkeVirtualGrid items={filtered} cell={[32, 32]}>
          {(shape) => (
            <SilkeButton
              icon={{ type: 1, value: shape.path }}
              onClick={() => onSelect({ type: 1, value: shape.path })}
            />
          )}
        </SilkeVirtualGrid>
      </SilkeBox>
    </ButtonContext>
  );
}
