import React, { useEffect, useRef } from "react";
import { Platform, ViewStyle } from "react-native";
import WebView from "react-native-webview";
import {
  BackgroundOptionsProps,
  CornerDotOptionsProps,
  CornerSquareOptionsProps,
  DotOptionsProps,
  ImageOptionsProps,
  QRGeneratorProps,
  QRGeneratorType,
  QROptionsProps,
} from "..";

const defaultValues = {
  width: 200,
  height: 200,
  borderRadius: 0,
  image: "",
};

const SOURCE_PATH = "./source.html";

const defaultDotOptions: DotOptionsProps = {
  type: "square",
  color: "#000",
};

const defaultCornerSquareOptions: CornerSquareOptionsProps = {
  type: "square",
  color: "#000",
};

const defaultCornerDotOptions: CornerDotOptionsProps = {
  type: "square",
  color: "#000",
};

const defaultBackgroundOptions: BackgroundOptionsProps = {
  color: "#FFF",
};

const defaultImageOptions: ImageOptionsProps = {
  hideBackgroundDots: true,
  imageSize: 0.4,
  margin: 0,
  crossOrigin: "anonymous",
};

const defaultQROptions: QROptionsProps = {
  typeNumber: 0,
  errorCorrectionLevel: "Q",
  mode: "Byte",
};

const defaultType: QRGeneratorType = "canvas";

const initLibrary = ({
  value,
  width,
  height,
  type,
  image,
  dotOptions,
  cornerSquareOptions,
  cornerDotOptions,
  backgroundOptions,
  imageOptions,
  qrOptions,
}: QRGeneratorProps) => {
  const configQR = {
    width: width,
    height: height,
    type: type,
    data: value,
    image: image,
    dotsOptions: {
        color: dotOptions?.color,
        type: dotOptions?.type,
        gradient:dotOptions?.gradient
    },
    cornersSquareOptions: {
        type:cornerSquareOptions?.type,
        color:cornerSquareOptions?.color,
        gradient:cornerSquareOptions?.gradient
    },
    cornersDotOptions: {
        type:cornerDotOptions?.type,
        color:cornerDotOptions?.color,
        gradient:cornerDotOptions?.gradient
    },
    backgroundOptions: {
        color: backgroundOptions?.color,
        gradient: backgroundOptions?.gradient
    },
    imageOptions: {
        margin: imageOptions?.margin,
        imageSize: imageOptions?.imageSize,
        hideBackgroundDots: imageOptions?.hideBackgroundDots,
    },
    qrOptions: {
      typeNumber: qrOptions?.typeNumber,
      mode: qrOptions?.mode,
      errorCorrectionLevel: qrOptions?.errorCorrectionLevel,
    }
  }
  if(imageOptions?.crossOrigin) {
    configQR.imageOptions['crossOrigin'] =imageOptions?.crossOrigin

  }
  const finalScriptQR = `
  const rnQRCodeStyling = new QRCodeStyling(${JSON.stringify(configQR)});
  rnQRCodeStyling.append(document.getElementById("canvas"));
  var elm = document.getElementById("canvas").firstChild
  if('${type}' === 'canvas') {
    var base64CanvasData = elm.toDataURL();
    ReactNativeWebView.postMessage(JSON.stringify({base64:base64CanvasData}));
  } else {
    var svgString = new XMLSerializer().serializeToString(elm);
    var decoded = unescape(encodeURIComponent(svgString));
    var base64 = btoa(decoded);
    var base64Data = 'data:image/svg+xml;base64,'+base64
    ReactNativeWebView.postMessage(JSON.stringify({base64:base64Data}));
  }
`;
  return finalScriptQR
};

const QRGenerator = ({
  value,
  type = defaultType,
  width = defaultValues.width,
  height = defaultValues.height,
  image = defaultValues.image,
  borderRadius = defaultValues.borderRadius,
  dotOptions = defaultDotOptions,
  cornerSquareOptions = defaultCornerSquareOptions,
  cornerDotOptions = defaultCornerDotOptions,
  backgroundOptions = defaultBackgroundOptions,
  imageOptions = defaultImageOptions,
  qrOptions = defaultQROptions,
  getBase64DataImage,
}: QRGeneratorProps) => {
  const webViewRef: any = useRef(null);

  const src = initLibrary({
    value,
    type,
    width,
    height,
    image,
    dotOptions,
    cornerSquareOptions,
    cornerDotOptions,
    backgroundOptions,
    imageOptions,
    qrOptions,
  });

  const loadContent = () => {
    webViewRef?.current?.injectJavaScript(src);
  };

  useEffect(() => {
    webViewRef?.current?.reload();
  });

  const webViewStyle: ViewStyle = {
    width: width,
    height: height,
    borderRadius: borderRadius,
  };

  const handleMessage = (event: any) => {
    const { data } = event?.nativeEvent;
    try {
      const jsonData = JSON.parse(data);
      getBase64DataImage?.(jsonData?.base64);
    } catch (err) {
      console.log("Something wrong when parse data");
    }
  };
  const isIOS = Platform.OS === "ios";
  return (
    <WebView
      ref={webViewRef}
      source={
        isIOS ? require(SOURCE_PATH) : { html: require("./source").template() }
      }
      onLoad={loadContent}
      style={webViewStyle}
      scrollEnabled={false}
      showsHorizontalScrollIndicator={false}
      showsVerticalScrollIndicator={false}
      onMessage={handleMessage}
      originWhitelist={isIOS ? ["*"] : []}
    />
  );
};

export default QRGenerator;
