import React from 'react';

// @ts-ignore
const QrReader = React.lazy(() => import('@uides/react-qr-reader'));

export interface QrCodeScannerProps {
  style?: React.CSSProperties;
  dataType?: 'url' | 'text';
  legacyMode?: boolean;
  validate?: (...args) => boolean;
  onScan: (...args) => void;
  onError: (err: any, data: any) => void;
  onLoad?: (...args) => void;
  onImageLoad?: (...args) => void;
  delay?: number;
  facingMode?: 'user' | 'environment';
  showViewFinder?: boolean;
  className?: string;
  children?: React.ReactNode;
}

/**
 * QRCodeScanner assumes that the data provided inside the QR code image,
 * are a HTTP link, thus it uses the `encodeURI` function to escape
 * all scanned data that will be forwarded to the `onScan` function
 *
 * When a QR code is scanned, before we run the `onScan` callback function,
 * we do the following:
 *
 * 1. Run a validator function provided in the props of QrCodeScanner component
 *    that receives the *raw* scanned data and returns a boolean type. (eg. check
 *    if it's a gov.gr subdomain, or that it matches the current domain)
 * 2. If the validator returns `true`, then construct a URL object from the data provided
 *    and check if the protocol is `https` and the `origin` is the same as the origin of this page
 * 2. Automatically fallback to the `onError` callback function, if the validation or url check fail
 * 3. Finally, run `onScan` callback function with the scanned data encoded as a URI.
 *
 */

export const QrCodeScanner: React.FC<QrCodeScannerProps> = ({
  children,
  validate,
  onScan,
  onError,
  dataType = 'url',
  legacyMode = false,
  ...props
}) => {
  if (dataType === 'text') {
    console.warn(
      `Security Warning! The \`text\` dataType could be used to inject XSS code to your application database or user DOM.

In order to be safe, you can:
1. Use a sanitizer function inside the \`onScan\` callback function that makes sure the data is not posing a threat to your app
2. Contact @digigov-ui for any further details and feature requests.
3. Read more about xss https://owasp.org/www-community/attacks/xss/
`
    );
  }
  const handleOnScan = (data) => {
    if (data) {
      if (dataType === 'url') {
        try {
          new URL(data);
        } catch {
          return onError(
            new Error(
              '@digigov-ui XSS Validation failed: qr code payload should follow the pattern `https://dilosi.services.gov.gr/show/:reference_code`'
            ),
            data
          );
        }
      }
      // run a validator function provided by the application code
      if (validate && !validate(data)) {
        return onError(
          new Error('Custom QR Code payload validation failed'),
          data
        );
      }
      // proceed with application defined callback function
      onScan(data);
    }
  };
  return (
    <>
      <QrReader
        delay={100}
        onError={onError}
        onScan={handleOnScan}
        legacyMode={legacyMode}
        {...props}
      />
      {children}
    </>
  );
};

export default QrCodeScanner;
