import React, { memo, useCallback, type LegacyRef } from 'react';
import { StyleSheet, View, type ViewStyle, type ViewProps } from 'react-native';

import LottieView, {
  type AnimationObject,
  type LottieViewProps,
} from 'lottie-react-native';

// @ts-ignore
import BarcodeScanner from '../BarcodeScanner';
import HeaderScreen, { type HeaderProps } from './HeaderScreen';

// styles
import styles from './styles';

type Props = {
  navigation?: any;
  goBack?: Function;
  style?: ViewStyle;
  contentStyle?: ViewStyle;
  cameraStyle?: ViewStyle;
  shouldScan: boolean;
  ComponentHeader?: React.ReactNode | React.Component | Function;
  headerProps?: HeaderProps;
  markProps?: Omit<LottieViewProps, 'source'> & {
    ref?: LegacyRef<LottieView> | undefined;
    source?: string | AnimationObject | { uri: string };
  } & { containerProps?: ViewProps };
  onScanBarcode: (result: any) => void;
  onPressLeftButton?: (() => void) | undefined;
};

const ScanCode = (props: Props) => {
  const {
    navigation,
    ComponentHeader,
    style,
    contentStyle,
    cameraStyle,
    headerProps,
    markProps = { source: undefined },
    onPressLeftButton,
  } = props;
  const { source, ...lottieProps } = markProps;

  const onScanBarcode = useCallback(
    (result: string | string[]) => {
      if (!props.shouldScan || (navigation && !navigation.isFocused())) {
        return null;
      }
      return props.onScanBarcode?.(result);
    },
    [props, navigation]
  );

  const renderHeader = useCallback(() => {
    if (!ComponentHeader) {
      return (
        <HeaderScreen
          {...(headerProps || {})}
          onPressLeftButton={onPressLeftButton}
        />
      );
    }
    if (typeof ComponentHeader === 'function') return ComponentHeader();
    if (React.isValidElement(ComponentHeader)) return ComponentHeader;

    return null;
  }, [ComponentHeader, headerProps, onPressLeftButton]);

  return (
    <View style={[styles.container, StyleSheet.flatten(style)]}>
      {renderHeader()}
      <View style={[styles.content, StyleSheet.flatten(contentStyle)]}>
        <BarcodeScanner
          style={[styles.cameraStyle, StyleSheet.flatten(cameraStyle)]}
          shouldScan={true}
          onBarcodesDetected={onScanBarcode}
        >
          <LottieView
            source={source || require('../assets/json/scan.json')}
            autoPlay
            loop
            {...lottieProps}
          />
        </BarcodeScanner>
      </View>
    </View>
  );
};

export default memo(ScanCode);
