hybridAPP = {};

const getUA = () => {
    return navigator.userAgent || "";
};

const isAndroid = () => {
    return /Android/i.test(getUA());
};

const isIOS = () => {
    return /iPhone/i.test(getUA()) || /iPad/i.test(getUA());
};

const isFlutter = () => {
    return /Flutter/i.test(getUA());
};

const setupWebViewJavascriptBridge = (callback) => {
    if (window.WebViewJavascriptBridge) {
        return callback(window.WebViewJavascriptBridge);
    }
    if (!isFlutter() && isIOS()) {
        // Not used in Zii's Apps, but just to backup.
        if (window.WVJBCallbacks) {
            return window.WVJBCallbacks.push(callback);
        }
        window.WVJBCallbacks = [callback];
        const WVJBIframe = document.createElement("iframe");
        WVJBIframe.style.display = "none";
        WVJBIframe.src = "wvjbscheme://__BRIDGE_LOADED__";
        document.documentElement.appendChild(WVJBIframe);
        setTimeout(() => {
            document.documentElement.removeChild(WVJBIframe);
        }, 0);
    } else {
        document.addEventListener(
            "WebViewJavascriptBridgeReady",
            () => {
                callback(window.WebViewJavascriptBridge);
            },
            false
        );
    }
    return true;
};

const initBridge = () => {
    return new Promise((resolve) => {
        setupWebViewJavascriptBridge((bridge) => {
            console.debug("Setup Bridge");
            if (!isFlutter() && isAndroid()) {
                // Not used in Zii's Apps, but just to backup.
                bridge.init((message, responseCallback) => {
                    console.debug("JS got a message", message);
                    const data = {
                        "Javascript Responds": "测试中文!",
                    };
                    if (responseCallback) {
                        console.debug("JS responding with", data);
                        responseCallback(data);
                    }
                });
            }

            bridge.registerHandler("postMsg", (data, callback) => {
                callback("Got your data: " + JSON.stringify(data));
            });

            bridge.registerHandler("clearStorage", (data, callback) => {
                localStorage.clear();
                sessionStorage.clear();
                if (callback) {
                    callback(true);
                }
            });


            bridge.registerHandler("prepare", (payload, callback) => {
                ecr.actionInitConnection();
                if (callback) {
                    callback(true);
                }
            });

            bridge.registerHandler("config", (payload, callback) => {
                init("config");
                if (callback) {
                    callback(true);
                }
            });

            bridge.registerHandler("purchase", (payload, callback) => {
                init("purchase", payload);
                // Get last transaction and check whether the lost one.
                // ecr.actionTransactionInfoRequest();

                const doPurchase = () => {
                    if (ecr.requestInProgress == timapi.constants.RequestType.activate ||
                        ecr.requestInProgress == timapi.constants.RequestType.login ||
                        ecr.requestInProgress == timapi.constants.RequestType.connect ||
                        ecr.requestInProgress == timapi.constants.RequestType.transactionInfoRequest
                    ) {
                        loading.show();
                        setTimeout(doPurchase, 1000);
                        return;
                    }

                    try {
                        const ref = payload.OrderNo.toString() + payload.IDNo.toString().padStart(3, 0);
                        ecr.actionTransaction("purchase", payload.Amount + (payload.Specialcharge ? payload.Specialcharge : 0), payload.Tips, 0, ref);
                        //ecr.actionGetTransactionData();
                    } catch (e) {
                        console.error('Start transaction fail: ', e);
                    }
                    loading.hide();
                }
                doPurchase();

                if (callback) {
                    callback(true);
                }
            });

            bridge.registerHandler("refund", async (payload, callback) => {
                var req = {};

                req.Amount = payload.RefundAmount;
                req.MachineID = machineID;
                req.OpName = payload.OpName;
                req.OrderNo = payload.OrderNo;
                req.RefundIDNo = payload.IDNo;
                req.RefundGst = payload.RefundGst;

                console.info("refund request.params :", req);
                try {
                    loading.show();
                    const result = await $.ajax({
                        type: "POST",
                        url: "/api/eft/tryRefund",
                        dataType: "json",
                        contentType: "application/json;charset=UTF-8",
                        headers: {
                            Accept: "application/json; charset=utf-8",
                            ContentType: "application/json; charset=utf-8",
                            MerchantId: merchantId,
                            BranchId: branchId
                        },
                        data: JSON.stringify(req),
                    });
                    loading.hide();
                    console.debug("refund response.result:", result);
                    if (result.Code == 1000) {
                        const data = result.Data;
                        const finalData = { ...payload, ...data, Amount: data.AmountCent / 100, Tips: 0 };
                        init("credit", finalData);
                        const doCredit = () => {
                            if (ecr.requestInProgress == timapi.constants.RequestType.activate ||
                                ecr.requestInProgress == timapi.constants.RequestType.login ||
                                ecr.requestInProgress == timapi.constants.RequestType.connect ||
                                ecr.requestInProgress == timapi.constants.RequestType.transactionInfoRequest) {
                                loading.show();
                                setTimeout(doCredit, 1000);
                                return;
                            }
                            ecr.actionTransaction("credit", finalData.Amount, finalData.Tips, 0);
                            loading.hide();
                        }
                        doCredit();
                    }
                    else {
                        console.info(result.Message);
                    }
                } catch (error) {
                    console.error("refund response.error:", error);
                }
                if (callback) {
                    callback(true);
                }
            });

            bridge.registerHandler("cancel", (payload, callback) => {
                ecr.actionCancel();
                if (callback) {
                    callback(true);
                }
            });

            bridge.registerHandler("dispose", (payload, callback) => {
                ecr.actionDisposeConnection();
                if (callback) {
                    callback(true);
                }
            });

            bridge.registerHandler("maintenance", (payload, callback) => {
                init("maintenance");
                if (callback) {
                    callback(true);
                }
            });

            window.hybridAPP = {
                close: (needCheck) => {
                    loading.hide();
                    init("");
                    bridge.callHandler("closePage", { needCheck });
                },
                canClose: (flag) => {
                    bridge.callHandler("canClose", { flag });
                },
                openBrowser: (url) => {
                    bridge.callHandler("openBrowser", { url });
                },
            };
            resolve();
        });
    });
};
