import React, { useCallback, useEffect, useMemo } from 'react';
import {
  Image,
  StyleSheet,
  TouchableOpacity,
  View,
  ViewStyle,
  ImageStyle,
  ScrollView,
} from 'react-native';
import { IStickerEmoji } from '@livelike/javascript';
import {
  BasePickerData,
  LLBasePicker,
  LLBasePickerProps,
} from '../LLBasePicker';
import { ComponentStyleProp, LLComponentStyleFn } from '../../types';
import {
  useStickerPacks,
  useStickerPicker,
  useStyles,
  useTheme,
} from '../../hooks';

export type LLStickerPickerStyles = {
  stickerPacksContainer: ViewStyle;
  stickerPackIcon: ImageStyle;
  stickerImage: ImageStyle;
  stickerImageContainer: ViewStyle;
  stickerHeaderContainer: ViewStyle;
  pickerCloseIcon: ImageStyle;
};

export type LLStickerPickerProps = ComponentStyleProp<LLStickerPickerStyles> & {
  visible?: boolean;
  onPanelOpen?: () => void;
  onPanelClose?: () => void;
  closeStickerPicker?: () => void;
  onSelectSticker: (stickerShortcode: string) => void;
  PickerComponentStyles?: LLBasePickerProps<BasePickerData>['styles'];
};

const EMPTY_STICKERS: IStickerEmoji[] = [];
/**
 * @description Provides stock UI for the Sticker picker component.
 * @param {Function} onPanelOpen - A callback function to be called when the panel opens. It is used for tracking analytics events when the component becomes visible.
 * @param {Function} onPanelClose - A callback function to be called when the panel closes. It is used for tracking analytics events when the component is unmounted as it becomes invisible.
 * @returns {JSX.Element} - Stock UI for the Sticker picker.
 */
export function LLStickerPicker({
  visible,
  onPanelOpen,
  onPanelClose,
  closeStickerPicker,
  onSelectSticker,
  styles: stylesProp,
  PickerComponentStyles,
}: LLStickerPickerProps) {
  const { stickerPacks } = useStickerPacks();
  const { selectedStickerPackId, setSelectedStickerPackId } =
    useStickerPicker();
  const _selectedStickerPackId = selectedStickerPackId || stickerPacks?.[0]?.id;
  const { theme, themeAssets } = useTheme();

  const stickerPickerStyles = useStyles({
    componentStylesFn: getStickerPickerStyles,
    stylesProp,
  });
  useEffect(() => {
    onPanelOpen?.();
    return () => {
      onPanelClose?.();
    };
  }, []);
  const stickers = useMemo(() => {
    if (!stickerPacks.length) {
      return EMPTY_STICKERS;
    }
    const stickerPack = stickerPacks.find(
      (pack) => pack.id === _selectedStickerPackId
    );
    return stickerPack.stickers || [];
  }, [_selectedStickerPackId]);

  const renderStickerHeaderComponent = useCallback(() => {
    if (stickerPacks && stickerPacks.length <= 1) {
      return null;
    }
    return (
      <View style={stickerPickerStyles.stickerHeaderContainer}>
        <ScrollView horizontal={true} keyboardShouldPersistTaps={'always'}>
          {stickerPacks.map((pack) => (
            <TouchableOpacity
              key={pack.id}
              onPress={() => setSelectedStickerPackId(pack.id)}
            >
              <View
                style={[
                  { backgroundColor: theme.secondaryBackground },
                  _selectedStickerPackId === pack.id && {
                    backgroundColor: theme.primaryButtonBackground,
                  },
                  stickerPickerStyles.stickerPacksContainer,
                ]}
              >
                <Image
                  style={stickerPickerStyles.stickerPackIcon}
                  source={{
                    uri: pack.file,
                  }}
                />
              </View>
            </TouchableOpacity>
          ))}
        </ScrollView>
        <TouchableOpacity
          onPress={closeStickerPicker}
          accessibilityLabel="Close Sticker picker"
        >
          <Image
            style={stickerPickerStyles.pickerCloseIcon}
            source={themeAssets.close}
          />
        </TouchableOpacity>
      </View>
    );
  }, [
    themeAssets,
    theme,
    closeStickerPicker,
    stickerPickerStyles,
    selectedStickerPackId,
    stickerPacks,
  ]);

  const renderPickerItem = useCallback(
    ({ item }) => {
      return (
        <TouchableOpacity
          style={stickerPickerStyles.stickerImageContainer}
          onPress={() => onSelectSticker(item.shortcode)}
        >
          <Image
            resizeMode="contain"
            style={stickerPickerStyles.stickerImage}
            source={{
              uri: item.file,
            }}
          />
        </TouchableOpacity>
      );
    },
    [stickerPickerStyles, onSelectSticker]
  );

  return (
    <LLBasePicker
      packItems={stickers}
      visible={visible}
      PickerItemComponent={renderPickerItem}
      PickerHeaderComponent={renderStickerHeaderComponent}
      styles={PickerComponentStyles}
    />
  );
}

const getStickerPickerStyles: LLComponentStyleFn<LLStickerPickerStyles> = ({
  theme,
}) =>
  StyleSheet.create({
    stickerPacksContainer: {
      paddingVertical: 5,
      paddingHorizontal: 15,
      marginTop: 10,
      marginBottom: 15,
      marginHorizontal: 5,
      borderRadius: 20,
    },
    stickerPackIcon: {
      height: 25,
      width: 25,
    },
    stickerImage: {
      width: 80,
      height: 80,
    },
    stickerImageContainer: {
      margin: 5,
    },
    stickerHeaderContainer: {
      flexDirection: 'row',
      justifyContent: 'center',
      alignItems: 'center',
      paddingHorizontal: 10,
    },
    pickerCloseIcon: {
      width: 30,
      height: 30,
      marginLeft: 10,
    },
  });
