import React, { useCallback, useMemo } from 'react';
import { Image, Keyboard, Platform, StyleSheet, Text, View } from 'react-native';
import Clipboard from '@react-native-clipboard/clipboard';
import ToolTipMenu from './TooltipMenu';
import loc from '../loc';
import { showFilePickerAndReadFile, showImagePickerAndReadImage } from '../blue_modules/fs';
import presentAlert from './Alert';
import { useTheme } from './themes';
import { detectQRCodeInImage } from 'react-native-camera-kit-no-google';
import { CommonToolTipActions } from '../typings/CommonToolTipActions';
import { useSettings } from '../hooks/context/useSettings';
import { scanQrHelper } from '../helpers/scan-qr.ts';

interface AddressInputScanButtonProps {
  isLoading?: boolean;
  onChangeText: (text: string) => void;
  type?: 'default' | 'link';
  testID?: string;
  beforePress?: () => Promise<void> | void;
}

export const AddressInputScanButton = ({
  isLoading,
  onChangeText,
  type = 'default',
  testID = 'BlueAddressInputScanQrButton',
  beforePress,
}: AddressInputScanButtonProps) => {
  const { colors } = useTheme();
  const { isClipboardGetContentEnabled } = useSettings();

  const stylesHook = StyleSheet.create({
    scan: {
      backgroundColor: colors.scanLabel,
    },
    scanText: {
      color: colors.inverseForegroundColor,
    },
  });

  const toolTipOnPress = useCallback(async () => {
    if (beforePress) {
      await beforePress();
    }
    Keyboard.dismiss();
    scanQrHelper().then(onChangeText);
  }, [beforePress, onChangeText]);

  const actions = useMemo(() => {
    const availableActions = [
      CommonToolTipActions.ChoosePhoto,
      CommonToolTipActions.ImportFile,
      {
        ...CommonToolTipActions.PasteFromClipboard,
        hidden: !isClipboardGetContentEnabled,
      },
    ];

    return availableActions;
  }, [isClipboardGetContentEnabled]);

  const onMenuItemPressed = useCallback(
    async (action: string) => {
      switch (action) {
        case CommonToolTipActions.PasteFromClipboard.id:
          try {
            let getImage: string | null = null;
            let hasImage = false;
            if (Platform.OS === 'android') {
              hasImage = true;
            } else {
              hasImage = await Clipboard.hasImage();
            }

            if (hasImage) {
              getImage = await Clipboard.getImage();
            }

            if (getImage) {
              try {
                const base64Data = getImage.replace(/^data:image\/(png|jpeg|jpg);base64,/, '');
                const result = await detectQRCodeInImage(base64Data);
                if (result) {
                  onChangeText(result);
                } else {
                  presentAlert({ message: loc.send.qr_error_no_qrcode });
                }
              } catch (error) {
                presentAlert({ message: (error as Error).message });
              }
            } else {
              const clipboardText = await Clipboard.getString();
              onChangeText(clipboardText);
            }
          } catch (error) {
            presentAlert({ message: (error as Error).message });
          }
          break;
        case CommonToolTipActions.ChoosePhoto.id:
          showImagePickerAndReadImage()
            .then(value => {
              if (value) {
                onChangeText(value);
              }
            })
            .catch(error => {
              presentAlert({ message: error.message });
            });
          break;
        case CommonToolTipActions.ImportFile.id:
          showFilePickerAndReadFile()
            .then(value => {
              if (value.data) {
                onChangeText(value.data);
              }
            })
            .catch(error => {
              presentAlert({ message: error.message });
            });
          break;
      }
      Keyboard.dismiss();
    },
    [onChangeText],
  );

  const menuButtonStyle = useMemo(() => (type === 'default' ? [styles.scan, stylesHook.scan] : undefined), [stylesHook.scan, type]);

  return (
    <ToolTipMenu
      actions={actions}
      isButton
      onPressMenuItem={onMenuItemPressed}
      shouldOpenOnLongPress
      disabled={isLoading}
      onPress={toolTipOnPress}
      testID={type === 'default' ? testID : undefined}
      buttonStyle={menuButtonStyle}
      accessibilityLabel={loc.send.details_scan}
      accessibilityHint={loc.send.details_scan_hint}
    >
      {type === 'default' ? (
        <View style={styles.scanContent}>
          <Image source={require('../img/scan-white.png')} accessible={false} />
          <Text numberOfLines={1} style={[styles.scanText, stylesHook.scanText]} accessible={false}>
            {loc.send.details_scan}
          </Text>
        </View>
      ) : (
        <View testID={testID} style={styles.contentRow}>
          <Text style={[styles.linkText, { color: colors.foregroundColor }]} numberOfLines={1} ellipsizeMode="tail">
            {loc.wallets.import_scan_qr}
          </Text>
        </View>
      )}
    </ToolTipMenu>
  );
};

AddressInputScanButton.displayName = 'AddressInputScanButton';

const styles = StyleSheet.create({
  scan: {
    height: 36,
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    gap: 6,
    minWidth: 82,
    flexShrink: 0,
    borderRadius: 4,
    paddingVertical: 4,
    paddingHorizontal: 8,
    marginHorizontal: 4,
    alignSelf: 'center',
  },
  scanText: {
    marginLeft: 4,
    flexShrink: 0,
    textAlignVertical: 'center',
  },
  scanContent: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    flexShrink: 0,
  },
  linkText: {
    textAlign: 'center',
    fontSize: 16,
    flexShrink: 1,
    textAlignVertical: 'center',
  },
  contentRow: {
    flexDirection: 'row',
    alignItems: 'center',
    justifyContent: 'center',
    width: '100%',
  },
});
