import { _objectSpread2 } from "../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
import { ClientEnum, ModeEnum } from "../const.js";
import { getBrowserVersion, getPayParams, getUuid } from "../helper.js";
import { updateComponent, updateCustom, updateState, useContextData, useDispatch } from "../store/index.js";
import { useStoreRef } from "../hooks.js";
import payLog from "../utils/payLog.js";
import step_default from "../component/step/step.js";
import { useTyro } from "./hooks.js";
import React, { useEffect, useRef, useState } from "react";
import { Button } from "antd";
import { locales } from "@pisell/utils";
import { Decimal as Decimal$1 } from "decimal.js";
//#region src/components/eftposPay/tyro/index.tsx
const Minute = 1e3 * 60;
var tyro_default = ({ api, onChange, children, url, version }) => {
	const { eftpos, custom, mode, status: payStatus, client } = useContextData();
	const dispatch = useDispatch();
	const [status, setStatus] = useState(-1);
	const [isManually, setManually] = useState(false);
	const isCancelRef = useRef(false);
	const { deviceRef, payRef, numRef, modeRef, orderIdRef, amountRef } = useStoreRef();
	const merchantReceiptRef = useRef({});
	const [TyroRef, load] = useTyro({
		url,
		version
	});
	const requestParams = useRef(custom === null || custom === void 0 ? void 0 : custom.requestParams);
	const listRef = useRef((custom === null || custom === void 0 ? void 0 : custom.list) || []);
	const iClientRef = useRef();
	const requestIdRef = useRef((custom === null || custom === void 0 ? void 0 : custom.requestId) || "");
	const unloadRef = useRef(false);
	const clearRef = useRef();
	const isPrint = (key) => {
		var _deviceRef$current, _deviceRef$current2;
		if ((_deviceRef$current = deviceRef.current) === null || _deviceRef$current === void 0 || (_deviceRef$current = _deviceRef$current.setting) === null || _deviceRef$current === void 0 ? void 0 : _deviceRef$current.receipts) return false;
		const receiptList = (_deviceRef$current2 = deviceRef.current) === null || _deviceRef$current2 === void 0 || (_deviceRef$current2 = _deviceRef$current2.setting) === null || _deviceRef$current2 === void 0 ? void 0 : _deviceRef$current2.receiptList;
		if (!Array.isArray(receiptList)) return true;
		if (Array.isArray(receiptList) && receiptList.some((item) => item === key)) return true;
		return false;
	};
	useEffect(() => {
		listRef.current = (custom === null || custom === void 0 ? void 0 : custom.list) || [];
	}, [custom === null || custom === void 0 ? void 0 : custom.list]);
	useEffect(() => {
		requestIdRef.current = (custom === null || custom === void 0 ? void 0 : custom.requestId) || "";
	}, [custom === null || custom === void 0 ? void 0 : custom.requestId]);
	useEffect(() => {
		requestParams.current = custom === null || custom === void 0 ? void 0 : custom.requestParams;
	}, [custom === null || custom === void 0 ? void 0 : custom.requestParams]);
	/**
	* @title: 获取设备信息
	* @description: 获取设备信息
	* @param {function} cb
	* @Author: hongbing.wang
	* @Date: 2024-08-19 11:32
	*/
	const getTerminalInfo = (cb) => {
		var _payLog$log;
		const iClient = iClientRef.current;
		if (!iClient) return;
		setStatus(0);
		const { connection } = deviceRef.current;
		const { integrationKey, tid, mid } = connection;
		console.log(integrationKey, tid, mid);
		payLog === null || payLog === void 0 || (_payLog$log = payLog.log) === null || _payLog$log === void 0 || _payLog$log.call(payLog, "Tyro：获取终端信息", {
			integrationKey,
			tid,
			mid,
			number: numRef.current
		});
		iClient.terminalInfo(({ status, message, terminalInfo }) => {
			payLog.log("Tyro：终端信息回调", {
				status,
				terminalInfo,
				message
			});
			if (status === "success" && (terminalInfo === null || terminalInfo === void 0 ? void 0 : terminalInfo.available)) cb();
		}, {
			mid,
			tid,
			integrationKey
		});
	};
	/**
	* @title: 退款
	* @description: 退款
	* @Author: hongbing.wang
	* @Date: 2024-08-19 11:32
	*/
	const refundOrder = () => {
		var _deviceRef$current3, _deviceRef$current4, _requestParams$curren;
		const iClient = iClientRef.current;
		if (!iClient) return;
		if (isCancelRef.current) return;
		const { connection } = deviceRef.current;
		const { integrationKey, tid, mid } = connection;
		numRef.current = getUuid();
		dispatch(updateState({ number: numRef.current }));
		requestParams.current = {
			amount: new Decimal$1(amountRef.current || 0).mul(100).toFixed(0, Decimal$1.ROUND_HALF_UP),
			integratedReceipt: !((_deviceRef$current3 = deviceRef.current) === null || _deviceRef$current3 === void 0 || (_deviceRef$current3 = _deviceRef$current3.setting) === null || _deviceRef$current3 === void 0 ? void 0 : _deviceRef$current3.receipts),
			integrationKey,
			transactionId: numRef.current,
			mid,
			tid,
			device: JSON.stringify(deviceRef.current),
			isPrintMerchant: isPrint("merchant"),
			isPrintCustomer: isPrint("customer"),
			browserVersion: getBrowserVersion()
		};
		dispatch(updateCustom({ requestParams: requestParams.current }));
		setStatus(Date.now());
		merchantReceiptRef.current = {};
		api.addTransaction({
			order_id: orderIdRef.current,
			number: numRef.current,
			card_reader_id: (_deviceRef$current4 = deviceRef.current) === null || _deviceRef$current4 === void 0 ? void 0 : _deviceRef$current4.id,
			card_reader_type: eftpos,
			amount: requestParams.current.amount,
			action: modeRef.current === ModeEnum.FullPay ? ModeEnum.Pay : modeRef.current,
			status: "pending",
			request: requestParams.current,
			response: {},
			metadata: { receipt: [] },
			_config: { retry: {
				count: 10,
				delay: 500
			} }
		}).then((res) => {
			requestIdRef.current = res.data.id;
			dispatch(updateCustom({ requestId: res.data.id }));
		});
		payLog.setContext({ transactionNumber: numRef.current });
		payLog.log("Tyro：发起退款", {
			number: numRef === null || numRef === void 0 ? void 0 : numRef.current,
			amount: (_requestParams$curren = requestParams.current) === null || _requestParams$curren === void 0 ? void 0 : _requestParams$curren.amount
		});
		iClient.initiateRefund(requestParams.current, {
			receiptCallback: receiptCallbackImpl,
			transactionCompleteCallback: transactionCompleteCallbackImpl,
			questionCallback: questionCallbackImpl,
			statusMessageCallback: statusMessageCallbackImpl
		});
	};
	/**
	* @title: 支付
	* @description:
	* @return {*}
	* @Author: hongbing.wang
	* @Date: 2024-08-19 11:33
	*/
	const payOrder = () => {
		var _deviceRef$current5, _payRef$current, _deviceRef$current6, _deviceRef$current7, _deviceRef$current8;
		const iClient = iClientRef.current;
		if (!iClient) return;
		if (isCancelRef.current) return;
		const { connection } = deviceRef.current;
		const { integrationKey, tid, mid } = connection;
		numRef.current = getUuid();
		dispatch(updateState({ number: numRef.current }));
		console.log("deviceRef.current?.settings?.useOriginSurcharge = ", (_deviceRef$current5 = deviceRef.current) === null || _deviceRef$current5 === void 0 || (_deviceRef$current5 = _deviceRef$current5.setting) === null || _deviceRef$current5 === void 0 ? void 0 : _deviceRef$current5.useOriginSurcharge);
		requestParams.current = {
			amount: new Decimal$1((_payRef$current = payRef.current) === null || _payRef$current === void 0 ? void 0 : _payRef$current.total).mul(100).toFixed(0, Decimal$1.ROUND_HALF_UP),
			enableSurcharge: ((_deviceRef$current6 = deviceRef.current) === null || _deviceRef$current6 === void 0 || (_deviceRef$current6 = _deviceRef$current6.setting) === null || _deviceRef$current6 === void 0 ? void 0 : _deviceRef$current6.useOriginSurcharge) || false,
			integratedReceipt: !((_deviceRef$current7 = deviceRef.current) === null || _deviceRef$current7 === void 0 || (_deviceRef$current7 = _deviceRef$current7.setting) === null || _deviceRef$current7 === void 0 ? void 0 : _deviceRef$current7.receipts),
			integrationKey,
			transactionId: numRef.current,
			mid,
			tid,
			device: JSON.stringify(deviceRef.current),
			isPrintMerchant: isPrint("merchant"),
			isPrintCustomer: isPrint("customer"),
			browserVersion: getBrowserVersion()
		};
		dispatch(updateCustom({ requestParams: requestParams.current }));
		setStatus(Date.now());
		merchantReceiptRef.current = {};
		api.addTransaction({
			order_id: orderIdRef.current,
			number: numRef.current,
			card_reader_id: (_deviceRef$current8 = deviceRef.current) === null || _deviceRef$current8 === void 0 ? void 0 : _deviceRef$current8.id,
			card_reader_type: eftpos,
			amount: requestParams.current.amount,
			action: modeRef.current === ModeEnum.FullPay ? ModeEnum.Pay : modeRef.current,
			status: "pending",
			request: requestParams.current,
			response: {},
			metadata: { receipt: [] },
			_config: { retry: {
				count: 10,
				delay: 500
			} }
		}).then((res) => {
			requestIdRef.current = res.data.id;
			dispatch(updateCustom({ requestId: res.data.id }));
		});
		payLog.setContext({ transactionNumber: numRef.current });
		payLog.log("Tyro：发起支付", {
			number: numRef.current,
			amount: requestParams.current.amount
		});
		iClient.initiatePurchase(requestParams.current, {
			receiptCallback: receiptCallbackImpl,
			transactionCompleteCallback: transactionCompleteCallbackImpl,
			questionCallback: questionCallbackImpl,
			statusMessageCallback: statusMessageCallbackImpl
		});
	};
	/**
	* @title: 恢复上一次支付
	* @Author: hongbing.wang
	* @Date: 2024-08-19 11:33
	*/
	const continueLastOrder = () => {
		const iClient = iClientRef.current;
		if (!iClient) return;
		if (isCancelRef.current) return;
		setStatus(Date.now());
		merchantReceiptRef.current = {};
		payLog.log("Tyro：恢复上次交易");
		iClient.continueLastTransaction({
			receiptCallback: receiptCallbackImpl,
			transactionCompleteCallback: transactionCompleteCallbackImpl,
			questionCallback: questionCallbackImpl,
			statusMessageCallback: statusMessageCallbackImpl
		});
	};
	/**
	* @title: 获取商家小票回调信息
	* @description: 获取小票回调信息
	* @param {{signatureRequired:boolean,merchantReceipt:string}} signatureRequired: 是否打印小票, merchantReceipt:小票内容
	* @Author: hongbing.wang
	* @Date: 2024-08-19 11:33
	*/
	const receiptCallbackImpl = ({ signatureRequired, merchantReceipt }) => {
		payLog.log("Tyro：小票回调", {
			signatureRequired,
			hasReceipt: !!merchantReceipt
		});
		const receipt = [merchantReceipt].filter((item) => typeof item === "string").filter(Boolean);
		merchantReceiptRef.current = {
			signatureRequired,
			merchantReceipt
		};
		if (signatureRequired) {
			onChange("print", receipt);
			return;
		}
		if (isPrint("merchant")) onChange("print", receipt);
	};
	/**
	* @title: 支付状态回调函数
	* @description:
	* @param {string} message
	* @return {*}
	* @Author: hongbing.wang
	* @Date: 2024-08-19 11:34
	*/
	const statusMessageCallbackImpl = (message) => {
		var _listRef$current;
		payLog.log("Tyro：状态消息", { message });
		const translateMsg = locales.getText("page.eftpos-pay.text.tyro")(message);
		const msg = Array.isArray(translateMsg) ? translateMsg.reduce((accumulator, currentValue) => accumulator + " " + currentValue, "") : translateMsg;
		const lastitem = listRef.current[listRef.current.length - 1];
		const key = locales.getText("page.eftpos-pay.text.tyro")("Connection lost. Attempting to recover");
		if (msg === key && lastitem && lastitem.pedding === key) return;
		console.log("message = ", message);
		console.log("msg = ", msg);
		dispatch(updateCustom({ list: [...listRef.current || [], {
			status: "pendding",
			pedding: msg,
			resolve: msg,
			reject: msg,
			index: ((_listRef$current = listRef.current) === null || _listRef$current === void 0 ? void 0 : _listRef$current.length) || 0
		}] }));
	};
	/**
	* @title: 支付提示下操作信息
	* @Author: hongbing.wang
	* @Date: 2024-08-19 11:34
	*/
	const questionCallbackImpl = (question, answerCallback) => {
		payLog.log("Tyro：交互问题回调", { question });
		setStatus(-1);
		setManually(false);
		const msg = locales.getText("page.eftpos-pay.text.tyro")(question.text);
		dispatch(updateCustom({ btnList: question.options.map((item) => {
			return /* @__PURE__ */ React.createElement(Button, {
				key: item,
				type: item === "YES" || item === "RETRY" ? "primary" : "default",
				className: "pisell-lowcode__eft-pay-step-item-btn",
				onClick: () => {
					dispatch(updateCustom({ btnList: [] }));
					setManually(false);
					dispatch(updateState({
						status: "loading",
						title: locales.getText("page.eftpos-pay.text.loading")(modeRef.current),
						subTitle: ""
					}));
					setStatus(Date.now());
					answerCallback(item);
				}
			}, locales.getText("page.eftpos-pay.text.tyro-btn")(item));
		}) }));
		const status = question.isError ? "fail" : "warn";
		dispatch(updateState(Array.isArray(msg) ? {
			status,
			title: msg[0],
			subTitle: msg[1]
		} : {
			status,
			title: msg
		}));
	};
	/**
	* @title: 支付完成-支付状态回调函数
	* @param {any} response
	* @Author: hongbing.wang
	* @Date: 2024-08-19 11:35
	*/
	const transactionCompleteCallbackImpl = (response) => {
		var _deviceRef$current9;
		setStatus(-1);
		setManually(false);
		payLog.log("Tyro：交易完成回调", { response });
		const receipt = [response === null || response === void 0 ? void 0 : response.customerReceipt].filter((item) => typeof item === "string").filter(Boolean);
		api.editTransaction(requestIdRef.current, {
			order_id: orderIdRef.current,
			number: numRef.current,
			card_reader_id: (_deviceRef$current9 = deviceRef.current) === null || _deviceRef$current9 === void 0 ? void 0 : _deviceRef$current9.id,
			card_reader_type: eftpos,
			amount: requestParams.current.amount,
			action: modeRef.current === ModeEnum.FullPay ? ModeEnum.Pay : modeRef.current,
			request: requestParams.current,
			status: response.result === "APPROVED" ? "succeed" : "failed",
			response: _objectSpread2(_objectSpread2({}, response), {}, { merchantReceipt: merchantReceiptRef.current }),
			metadata: { receipt }
		});
		dispatch(updateCustom({ btnList: [] }));
		if (response.result === "APPROVED") {
			dispatch(updateState({
				status: "success",
				title: locales.getText("page.eftpos-pay.text.successful")(mode),
				subTitle: ""
			}));
			dispatch(updateCustom({
				card_reader_surcharge: response.surchargeAmount || 0,
				receipt
			}));
			clearRef.current = setTimeout(() => {
				onChange("success", _objectSpread2(_objectSpread2({}, getPayParams({
					mode: modeRef.current,
					amount: amountRef.current,
					order_id: orderIdRef.current,
					number: numRef.current,
					device: deviceRef.current,
					pay: payRef.current,
					custom: {
						card_reader_surcharge: response.surchargeAmount || 0,
						receipt
					}
				}, "success")), {}, { receipt: isPrint("customer") ? receipt : [] }));
			}, 1e3);
			return;
		} else {
			var _deviceRef$current10;
			if ((((_deviceRef$current10 = deviceRef.current) === null || _deviceRef$current10 === void 0 ? void 0 : _deviceRef$current10.setting.receipts) ? [] : receipt).length > 0) {
				if (isPrint("customer")) onChange("print", receipt);
			}
		}
		if (response.result === "UNKNOWN") {
			dispatch(updateCustom({ errorStatus: "unknow" }));
			dispatch(updateComponent("UnknowFail"));
			return;
		}
		dispatch(updateState({ status: "fail" }));
		dispatch(updateCustom({ failCustom: {
			isPosNetworkError: false,
			status: "fail",
			fail: response.result,
			warn: null,
			title: locales.getText("page.eftpos-pay.text.failed")(modeRef.current)
		} }));
		dispatch(updateComponent("FailCustom"));
	};
	useEffect(() => {
		const { config } = deviceRef.current;
		const { apiKey, posProductData } = config;
		if (load && TyroRef.current) {
			const IClient = TyroRef.current.IClient;
			if (IClient) {
				iClientRef.current = new IClient(apiKey, posProductData);
				payLog.log("Tyro：SDK 初始化完成");
				if (isCancelRef.current) return;
				if (!numRef.current) {
					if (modeRef.current === ModeEnum.Pay || modeRef.current === ModeEnum.FullPay) {
						payLog.log("Tyro：支付交易，查询终端信息");
						getTerminalInfo(payOrder);
					} else if (modeRef.current === ModeEnum.Refund) {
						payLog.log("Tyro：退款交易，查询终端信息");
						getTerminalInfo(refundOrder);
					}
				} else {
					payLog.log("Tyro：恢复上次交易，查询终端信息");
					getTerminalInfo(continueLastOrder);
				}
			}
		}
	}, [load]);
	const onNotin = () => {
		onChange("print", [], "print_on_timeout");
	};
	useEffect(() => {
		let clear;
		if (status === -1) return () => {
			if (clear) clearTimeout(clear);
		};
		if (status === 0) {
			clear = setTimeout(() => {
				payLog.log("Tyro：连接超时");
				dispatch(updateState({ status: "fail" }));
				dispatch(updateCustom({ failCustom: {
					status: "fail",
					fail: locales.getText("page.eftpos-pay.text.transaction.pay.fail.timeout"),
					title: locales.getText("page.eftpos-pay.text.transaction.fail.timeout"),
					warn: null
				} }));
				dispatch(updateComponent("FailCustom"));
			}, Minute);
			return () => {
				if (clear) clearTimeout(clear);
			};
		}
		clear = setTimeout(() => {
			if (!iClientRef.current) return;
			payLog.log("Tyro：交易超时，显示手动标记");
			setManually(true);
		}, Minute);
		return () => {
			if (clear) clearTimeout(clear);
		};
	}, [status]);
	const onManually = () => {
		payLog.log("Tyro：点击手动标记");
		dispatch(updateState({ manual: {
			title: locales.getText("page.eftpos-pay.text.request.title")(mode),
			text: locales.getText("page.eftpos-pay.text.request.text")(mode)
		} }));
		dispatch(updateComponent("Manual", true));
	};
	/**
	* @title: 取消支付
	* @description:
	* @return {*}
	* @Author: hongbing.wang
	* @Date: 2024-09-13 13:42
	*/
	const onCancel = () => {
		const iClient = iClientRef.current;
		if (!iClient) return;
		if (status > 0) {
			payLog.log("Tyro：取消当前交易");
			iClient.cancelCurrentTransaction();
			return;
		}
		if (isCancelRef.current) return;
		payLog.log("Tyro：取消（交易未开始）");
		isCancelRef.current = true;
		dispatch(updateState({ status: "fail" }));
		dispatch(updateCustom({ failCustom: {
			status: "fail",
			fail: locales.getText("page.eftpos-pay.text.transaction.fail.cancel"),
			title: locales.getText("page.eftpos-pay.text.transaction.fail.cancel.title"),
			warn: null
		} }));
		dispatch(updateComponent("FailCustom"));
	};
	useEffect(() => () => {
		unloadRef.current = true;
		if (clearRef.current) clearTimeout(clearRef.current);
	}, []);
	return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("div", { className: "pisell-lowcode__eft-pay-body" }, ((custom === null || custom === void 0 ? void 0 : custom.list) || []).map((item) => /* @__PURE__ */ React.createElement(step_default, {
		key: item.index,
		pedding: item.pedding,
		resolve: item.resolve,
		reject: item.reject,
		status: item.status
	}))), isManually ? /* @__PURE__ */ React.createElement("div", { className: "pisell-lowcode__eft-pay-step-item-btns" }, client === ClientEnum.Merchant ? /* @__PURE__ */ React.createElement(Button, {
		block: true,
		className: "pisell-lowcode__eft-pay-step-item-btn",
		onClick: onManually
	}, locales.getText("page.eftpos-pay.text.manual.marking")) : /* @__PURE__ */ React.createElement(Button, {
		block: true,
		className: "pisell-lowcode__eft-pay-step-item-btn",
		onClick: onNotin
	}, locales.getText("page.eftpos-pay.text.manual.print_receipt"))) : null, /* @__PURE__ */ React.createElement("div", {
		className: "pisell-lowcode__eft-pay-step-item-btns",
		style: { flexWrap: "wrap" }
	}, Array.isArray(custom === null || custom === void 0 ? void 0 : custom.btnList) && (custom === null || custom === void 0 ? void 0 : custom.btnList).length > 0 ? /* @__PURE__ */ React.createElement("div", { style: {
		width: "100%",
		display: "flex",
		gap: "12px"
	} }, custom === null || custom === void 0 ? void 0 : custom.btnList) : null, !(payStatus === "success" || payStatus === "fail") ? /* @__PURE__ */ React.createElement(Button, {
		block: true,
		type: "text",
		disabled: Array.isArray(custom === null || custom === void 0 ? void 0 : custom.btnList) && (custom === null || custom === void 0 ? void 0 : custom.btnList).length > 0,
		className: "pisell-lowcode__eft-pay-step-item-btn",
		onClick: onCancel
	}, locales.getText("page.eftpos-pay.text.manual.cancel")) : null));
};
//#endregion
export { tyro_default as default };
