import { useCallback, useEffect, useState } from 'react';
import { Container, Row, ScrollView, TouchableWithoutFeedback } from 'components/layout';
import { Text, TextField, BottomSheet, Fab, Visible, Card } from 'components';
import { metrics } from 'config';
import {
  smileysAndEmotion,
  animalsAndNature,
  foodAndDrink,
  travelAndPlaces,
  symbols,
  flags,
} from 'emojis';
import { SearchIcon, Smiles, Clock, Animal, Food, Symbol, Travel, Flag } from 'icons';
import { useResponsiveLayout } from 'hooks';
import { IconProps } from 'icons/types';
import { isEmojisOpenVar } from 'state-management/dialogs';

const { STYLES } = metrics;

const emojisObject: Record<EmojiTabsType, EmojiType[]> = {
  recent: smileysAndEmotion,
  smileys: smileysAndEmotion,
  animal: animalsAndNature,
  food: foodAndDrink,
  symbol: symbols,
  flag: flags,
  travel: travelAndPlaces,
};
const emojiTitles: Record<EmojiTabsType, string> = {
  recent: 'Recent Used',
  smileys: 'Smileys & Emotions',
  animal: 'Animals & Nature',
  food: 'Food & Drink',
  symbol: 'Symbols',
  flag: 'Flags',
  travel: 'Travel & Places',
};

export const EmojisAction: React.FC<EmojisSheetProps> = ({ isSheetOpen, setIsSheetOpen }) => {
  const [activeTab, setActiveTab] = useState<EmojiTabsType>('recent');
  const [searchString, setSearchString] = useState('');
  const [searchedEmojis, setSearchedEmojis] = useState<EmojiType[]>();
  const { top, isMobile } = useResponsiveLayout();
  const sheetHeight = 400 + top;

  const closeSheet = useCallback(() => {
    setIsSheetOpen(false);
  }, [setIsSheetOpen]);

  useEffect(() => {
    if (searchString && searchString.length > 0) {
      const smileySearch: EmojiType[] = smileysAndEmotion.filter((emoji) =>
        emoji.description.includes(searchString)
      );
      const animalSearch: EmojiType[] = animalsAndNature.filter((emoji) =>
        emoji.description.includes(searchString)
      );

      const foodSearch: EmojiType[] = foodAndDrink.filter((emoji) =>
        emoji.description.includes(searchString)
      );
      const symbolSearch: EmojiType[] = symbols.filter((emoji) =>
        emoji.description.includes(searchString)
      );
      const flagsSearch: EmojiType[] = flags.filter((emoji) =>
        emoji.description.includes(searchString)
      );
      const travelSearch: EmojiType[] = travelAndPlaces.filter((emoji) =>
        emoji.description.includes(searchString)
      );

      setSearchedEmojis([
        ...smileySearch,
        ...animalSearch,
        ...foodSearch,
        ...symbolSearch,
        ...flagsSearch,
        ...travelSearch,
      ]);
    }
  }, [searchString]);

  const getIconColor = useCallback(
    (tab: EmojiTabsType) => {
      return activeTab === tab ? 'primary' : 'body';
    },
    [activeTab]
  );

  const ClockIcon = (props: IconProps) => {
    return <Clock colorVariant={getIconColor('recent')} width={20} height={20} {...props} />;
  };
  const SmileysIcon = (props: IconProps) => {
    return <Smiles colorVariant={getIconColor('smileys')} width={20} height={20} {...props} />;
  };

  const AnimalIcon = (props: IconProps) => {
    return <Animal colorVariant={getIconColor('animal')} width={20} height={20} {...props} />;
  };

  const FoodIcon = (props: IconProps) => {
    return <Food colorVariant={getIconColor('food')} width={20} height={20} {...props} />;
  };

  const TravelIcon = (props: IconProps) => {
    return <Travel colorVariant={getIconColor('travel')} width={20} height={20} {...props} />;
  };

  const SymbolIcon = (props: IconProps) => {
    return <Symbol colorVariant={getIconColor('symbol')} width={20} height={20} {...props} />;
  };

  const FlagIcon = (props: IconProps) => {
    return <Flag colorVariant={getIconColor('flag')} width={20} height={20} {...props} />;
  };

  const emojiTabs: EmojiTabsProps[] = [
    {
      value: 'recent',
      Icon: ClockIcon,
    },
    {
      value: 'smileys',
      Icon: SmileysIcon,
    },
    {
      value: 'animal',
      Icon: AnimalIcon,
    },
    {
      value: 'food',
      Icon: FoodIcon,
    },
    {
      value: 'travel',
      Icon: TravelIcon,
    },
    {
      value: 'symbol',
      Icon: SymbolIcon,
    },
    {
      value: 'flag',
      Icon: FlagIcon,
    },
  ];

  const emojis = emojisObject[activeTab];
  const emojiTitle = emojiTitles[activeTab];

  const selectEmoji = useCallback(() => {
    isEmojisOpenVar(false);
  }, []);

  const isSearchEmojisValid = searchedEmojis && searchedEmojis?.length > 0;

  const InnerEmojisAction = () => {
    return (
      <>
        <Container p="m">
          <TextField
            sizeVariant="small"
            leftElement={<SearchIcon colorVariant="body" />}
            shapeVariant="round"
            placeholder="Search Emoji"
            variant="plain"
            onChangeText={setSearchString}
            value={searchString}
            backgroundVariant="base-02"
            colorVariant="primary"
          />
        </Container>

        <ScrollView overflow="scroll" px="xs" height={300}>
          <>
            <Visible if={isSearchEmojisValid}>
              <>
                <Text px="2xs" mb="xs" variant="title">
                  Search Results
                </Text>
                <Container>
                  <Row flexWrap="wrap">
                    {searchedEmojis?.map(({ emoji }) => (
                      <Container key={emoji} flexGrow={1}>
                        <Fab
                          sizeVariant="medium"
                          variant="plain"
                          m="3xs"
                          shapeVariant="round"
                          colorVariant="transparent"
                          centerElement={
                            <Text variant="heading" fontSize={25}>
                              {emoji}
                            </Text>
                          }
                          onPress={() => selectEmoji()}
                        />
                      </Container>
                    ))}
                  </Row>
                </Container>
              </>
            </Visible>
            <Text px="2xs" mb="xs" variant="title">
              {emojiTitle}
            </Text>
            <Container>
              <Row flexWrap="wrap">
                {emojis.map(({ emoji }) => (
                  <Container key={emoji} flexGrow={1}>
                    <Fab
                      sizeVariant="medium"
                      variant="plain"
                      m="3xs"
                      shapeVariant="round"
                      colorVariant="transparent"
                      hoverColorVariant="base-02-hover"
                      centerElement={
                        <Text variant="heading" fontSize={25}>
                          {emoji}
                        </Text>
                      }
                      onPress={() => selectEmoji()}
                    />
                  </Container>
                ))}
              </Row>
            </Container>
          </>
        </ScrollView>
        <Row py="3xs" px="m" justifyContent="space-between">
          {emojiTabs.map(({ Icon, value }) => (
            <Fab
              onPress={() => setActiveTab(value)}
              variant="plain"
              colorVariant="base"
              shapeVariant="round"
              sizeVariant="medium"
              hoverColorVariant="base-02-hover"
              centerElement={Icon({})}
            />
          ))}
        </Row>
      </>
    );
  };

  const isOpenOnMobile = isMobile && isSheetOpen;
  return (
    <>
      <Visible if={isOpenOnMobile}>
        <BottomSheet isSheetOpen={isSheetOpen} height={sheetHeight} closeSheet={closeSheet}>
          <Container paddingBottom={top} borderRadius={STYLES.radius.card} flexGrow={1}>
            <InnerEmojisAction />
          </Container>
        </BottomSheet>
      </Visible>
      <Visible if={!isMobile}>
        <TouchableWithoutFeedback onPress={() => {}}>
          <Card variant="outline" colorVariant="base" zIndex={2} width={500} height={400}>
            <InnerEmojisAction />
          </Card>
        </TouchableWithoutFeedback>
      </Visible>
    </>
  );
};

export interface EmojisSheetProps {
  isSheetOpen: boolean;
  setIsSheetOpen: (value: boolean) => void;
}
type EmojiType = {
  emoji: string;
  description: string;
  category: string;
};
type EmojiTabsType = 'recent' | 'smileys' | 'animal' | 'food' | 'travel' | 'symbol' | 'flag';

interface EmojiTabsProps {
  Icon: (props: IconProps) => JSX.Element;
  value: EmojiTabsType;
}
