import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "@emotion/react/jsx-runtime";
import { Box, Button, Flex, Icon, Modal, ModalContent, ModalOverlay, Text, useMediaQuery, } from "@chakra-ui/react";
import { css, keyframes } from "@emotion/react";
import { ChevronCheck, Close } from "@feedloop/icon";
import React from "react";
import { useActionTrigger } from "./hooks/useActionTrigger";
import { usePageSource } from "./hooks/usePageSource";
import { RuntimeContext } from "@qorebase/app-component";
// This component breaks SSR
const QrReader = React.lazy(() => import("react-qr-reader"));
export const QRScannerActionContext = React.createContext({
    showQRScanner: false,
    code: {},
    activeQRScannerId: null,
    closeQRScanner: () => { },
    triggerQRScanner: () => { },
    setQRCode: () => { },
    removeQRCode: () => { },
});
export const QRScannerActionContextProvider = React.memo(function QRScannerActionContextProvider({ children, }) {
    const [state, setState] = React.useState({
        code: {},
        showQRScanner: false,
        activeQRScannerId: null,
    });
    const triggerQRScanner = React.useCallback((activeQRScannerId, metadata, onSuccessAction) => {
        setState((state) => (Object.assign(Object.assign({}, state), { showQRScanner: true, activeQRScannerId, message: (metadata === null || metadata === void 0 ? void 0 : metadata.message) || "", onSuccessAction })));
    }, []);
    const closeQRScanner = React.useCallback(() => {
        setState((state) => (Object.assign(Object.assign({}, state), { showQRScanner: false, activeQRScannerId: null, message: undefined, onSuccessAction: undefined })));
    }, []);
    const setQRCode = React.useCallback((key, code) => {
        setState((state) => (Object.assign(Object.assign({}, state), { code: Object.assign(Object.assign({}, state.code), { [key]: code }) })));
    }, []);
    const removeQRCode = React.useCallback((key) => {
        setState((state) => (Object.assign(Object.assign({}, state), { code: Object.assign(Object.assign({}, state.code), { [key]: null }) })));
    }, []);
    const contextValue = React.useMemo(() => ({
        showQRScanner: state.showQRScanner,
        code: state.code,
        activeQRScannerId: state.activeQRScannerId,
        message: state.message,
        onSuccessAction: state.onSuccessAction,
        setQRCode,
        removeQRCode,
        closeQRScanner,
        triggerQRScanner,
    }), [
        state.code,
        state.showQRScanner,
        state.activeQRScannerId,
        state.message,
        state.onSuccessAction,
        setQRCode,
        removeQRCode,
        closeQRScanner,
        triggerQRScanner,
    ]);
    return (_jsx(QRScannerActionContext.Provider, Object.assign({ value: contextValue }, { children: children })));
});
const qrActionPrefix = "action.QRScan.";
export const useQRScannerAction = () => React.useContext(QRScannerActionContext);
function generateScanKeyframes() {
    const key = Array.from(Array(100)).reduce((key, _, i) => key.concat(`
    ${i === 0 ? "from" : i === 100 ? "to" : `${i}%`} {
      transform: translate3d(0,${i}%,0);
    }
    `), "");
    return keyframes `${key}`;
}
const movingUpDownAnimation = generateScanKeyframes();
const bounceAnimation = keyframes `
  from, 20%, 53%, 80%, to {
    transform: translate3d(0,0,0);
  }

  40%, 43% {
    transform: translate3d(0, -20px, 0);
  }

  70% {
    transform: translate3d(0, -10px, 0);
  }

  90% {
    transform: translate3d(0,-4px,0);
  }
`;
const fadeInAnimation = keyframes `
  from {
    opacity: 0;
  }

  to {
    opacity: 1;
  }
`;
const QRScannerAction = () => {
    const { activeQRScannerId, showQRScanner, message, onSuccessAction, setQRCode, closeQRScanner, } = useQRScannerAction();
    const { source, row } = usePageSource();
    const actionTrigger = useActionTrigger(onSuccessAction, row, source);
    const [isMobileDevice, isTablet] = useMediaQuery([
        "(max-width: 48rem)",
        "(max-width: 85rem)",
    ]);
    const media = React.useMemo(() => ({
        small: isMobileDevice,
        medium: !isMobileDevice && isTablet,
        large: !isTablet,
    }), [isMobileDevice, isTablet]);
    const [scanStatus, setScanStatus] = React.useState("scan");
    const CornerBorderSVG = React.useCallback((svgProps) => {
        return (_jsx("svg", Object.assign({ width: "84", height: "84", viewBox: "0 0 84 84", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, { children: _jsx("path", { d: "M2 82V10C2 5.58172 5.58172 2 10 2H82", stroke: svgProps.stroke || "#4D93FF", strokeWidth: "4", strokeLinecap: "round" }) })));
    }, []);
    const scanColor = React.useMemo(() => {
        switch (scanStatus) {
            case "success":
                return "#70B864";
            case "error":
                return "#E96F74";
            case "scan":
            default:
                return "#4D93FF";
        }
    }, [scanStatus]);
    const ScanBox = React.useCallback(() => {
        return (_jsxs(_Fragment, { children: [_jsx(Box, Object.assign({ position: "absolute", left: "-1", top: "-1" }, { children: _jsx(CornerBorderSVG, { stroke: scanColor }) })), _jsx(Box, Object.assign({ position: "absolute", right: "-1", top: "-1", transform: "rotate(90deg)" }, { children: _jsx(CornerBorderSVG, { stroke: scanColor }) })), _jsx(Box, Object.assign({ position: "absolute", right: "-1", bottom: "-1", transform: "rotate(180deg)" }, { children: _jsx(CornerBorderSVG, { stroke: scanColor }) })), _jsx(Box, Object.assign({ position: "absolute", left: "-1", bottom: "-1", transform: "rotate(270deg)" }, { children: _jsx(CornerBorderSVG, { stroke: scanColor }) }))] }));
    }, [scanColor]);
    const handleClose = React.useCallback(() => {
        closeQRScanner();
        setScanStatus("scan");
    }, [closeQRScanner]);
    const handleOnSuccessScan = React.useCallback((code) => {
        if (code) {
            setQRCode(`${qrActionPrefix}${activeQRScannerId}`, code);
            setScanStatus("success");
            setTimeout(() => {
                actionTrigger.handleClick();
                handleClose();
            }, 1000);
        }
    }, [activeQRScannerId, actionTrigger.handleClick]);
    const qrRef = React.useRef(null);
    const handleRetry = React.useCallback(() => {
        if (qrRef.current) {
            qrRef.current.initiate();
            setScanStatus("scan");
        }
    }, []);
    React.useEffect(() => {
        if (scanStatus === "scan") {
            setTimeout(() => {
                setScanStatus("error");
            }, 300000);
        }
        else {
            if (qrRef.current) {
                qrRef.current.stopCamera();
            }
        }
    }, [scanStatus]);
    return (_jsxs(Modal, Object.assign({ isOpen: showQRScanner, onClose: handleClose }, { children: [_jsx(ModalOverlay, {}), _jsx(ModalContent, Object.assign({ margin: isTablet && "0", overflow: "hidden", maxW: isTablet ? "none" : "md" }, { children: _jsxs(Box, Object.assign({ position: "relative", width: "100%", height: "100%" }, { children: [_jsx(Box, Object.assign({ position: "absolute", top: "0", left: "0", zIndex: "1", padding: "16px", width: "100%", height: isTablet && "100", backgroundColor: "#171717A3" }, { children: _jsxs(Flex, Object.assign({ alignItems: "center" }, { children: [_jsx(Icon, { as: Close, fontSize: "4xl", color: "white", onClick: handleClose }), _jsx(Text, Object.assign({ color: "white", textAlign: "center", flex: "1" }, { children: "QR Scanner" }))] })) })), _jsxs(Box, Object.assign({ position: "absolute", top: isTablet ? "100" : "68px", left: "0", zIndex: "1", width: "100%", height: isTablet ? "100vw" : "80%" }, { children: [_jsx(Box, Object.assign({ margin: "0 auto", borderWidth: isTablet
                                        ? `calc((100vw - ${isMobileDevice ? "300px" : "400px"}) / 2)`
                                        : "50px", borderY: "50px", borderStyle: "solid", borderColor: "#171717A3", height: media.small ? "400px" : media.medium ? "500px" : "100%", width: isTablet ? "100vw" : "100%" }, { children: _jsxs(Box, Object.assign({ height: "100%", position: "relative" }, { children: [scanStatus === "scan" && (_jsx(Box, { width: "100%", height: "100%", borderTop: "2px solid #4D93FF", css: css `
                      animation: ${movingUpDownAnimation} 3s ease infinite;
                    ` })), scanStatus !== "scan" && (_jsx(Flex, Object.assign({ height: "100%", alignItems: "center", justifyContent: "center" }, { children: _jsx(Box, Object.assign({ paddingX: "8px", paddingY: "4px", borderRadius: "50%", backgroundColor: scanStatus === "success" ? "#EBF5E9" : "#FCEAEB", css: css `
                        animation: ${bounceAnimation} 1s ease,
                          ${fadeInAnimation} 0.5s ease;
                      ` }, { children: _jsx(Icon, { as: scanStatus === "success" ? ChevronCheck : Close, fontSize: "6xl", color: scanStatus === "success" ? "#329922" : "#E03138" }) })) }))), _jsx(ScanBox, {})] })) })), _jsxs(Box, Object.assign({ position: "relative", height: "100%", backgroundColor: "#171717A3" }, { children: [_jsx(Text, Object.assign({ textAlign: "center", whiteSpace: "pre", color: "white" }, { children: scanStatus === "scan"
                                                ? message
                                                : scanStatus === "success"
                                                    ? "Scan completed. Redirecting…"
                                                    : "No QR code detected" })), scanStatus === "error" && (_jsx(Box, Object.assign({ display: "flex", justifyContent: "center", mt: "16px" }, { children: _jsx(Button, Object.assign({ onClick: handleRetry }, { children: "Retry" })) })))] }))] })), _jsx(React.Suspense, { children: _jsx(QrReader, { ref: qrRef, facingMode: "environment", delay: scanStatus === "scan" ? 500 : Infinity, onScan: handleOnSuccessScan, onError: (err) => {
                                    console.error(err);
                                }, css: css `
                width: 100% !important;
                & div {
                  display: none;
                }
                & > section {
                  height: ${isTablet ? "100vh" : "100%"};
                }
              ` }) })] })) }))] })));
};
export const useQRActionsVariables = () => {
    const components = RuntimeContext.useSelectState((state) => state.maps.component);
    const actions = React.useMemo(() => Object.values(components)
        .filter((comp) => !!comp.properties.action)
        .map((comp) => comp.properties.action), [components]);
    const qrActionsSuggestions = React.useMemo(() => {
        const QRActions = actions
            .flat()
            .filter((act) => act.type === "scan_QR_code" && act.variableOutput);
        const onErrorQRActions = actions
            .flat()
            .filter((act) => act.onError)
            .map((act) => act.onError)
            .flat()
            .filter((item) => item.type === "scan_QR_code" && item.variableOutput);
        return QRActions.concat(onErrorQRActions).map((act) => ({
            id: qrActionPrefix + act.variableOutput,
            display: qrActionPrefix + act.variableOutput,
        }));
    }, [actions]);
    return qrActionsSuggestions;
};
export default QRScannerAction;
//# sourceMappingURL=QRScanner.action.js.map