require("../../../_virtual/_rolldown/runtime.js");
const require_objectSpread2 = require("../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
const require_asyncToGenerator = require("../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js");
const require_types = require("./types.js");
const require_serve = require("./serve.js");
let _pisell_utils = require("@pisell/utils");
//#region src/components/eftpos/SettlementModal/utils.ts
/**
* 解析MX51参数
* @param params 接口返回的原始参数
* @param status 支付状态
* @param data 接口返回的数据
* @returns 解析后的结果对象
*/
const parseMX51Params = (params, settlementStatus, data) => {
	if (!params) return null;
	const result = {
		transactionId: (params === null || params === void 0 ? void 0 : params.id) || "",
		status: (params === null || params === void 0 ? void 0 : params.status) || "",
		version: (params === null || params === void 0 ? void 0 : params.version) || 0,
		message: (params === null || params === void 0 ? void 0 : params.message) || "",
		merchantReceipt: params === null || params === void 0 ? void 0 : params.merchant_receipt,
		customerReceipt: params === null || params === void 0 ? void 0 : params.customer_receipt,
		resultAmounts: params === null || params === void 0 ? void 0 : params.result_amounts,
		resultFinancialStatus: params === null || params === void 0 ? void 0 : params.result_financial_status,
		layouts: [],
		details: {},
		detailsText: "",
		autoAction: []
	};
	if (!(params === null || params === void 0 ? void 0 : params.pos_instructions)) return result;
	const posInstructions = (params === null || params === void 0 ? void 0 : params.pos_instructions) || {};
	result.autoAction = (posInstructions === null || posInstructions === void 0 ? void 0 : posInstructions.auto_actions) || [];
	if (!(posInstructions === null || posInstructions === void 0 ? void 0 : posInstructions.action_form)) return result;
	const actionForm = (posInstructions === null || posInstructions === void 0 ? void 0 : posInstructions.action_form) || {};
	if (actionForm === null || actionForm === void 0 ? void 0 : actionForm.details) {
		result.details = require_objectSpread2._objectSpread2({}, (actionForm === null || actionForm === void 0 ? void 0 : actionForm.details) || {});
		const detailsTextArr = [];
		Object.keys((actionForm === null || actionForm === void 0 ? void 0 : actionForm.details) || {}).forEach((key) => {
			var _actionForm$details;
			detailsTextArr.push(`${key}: ${(actionForm === null || actionForm === void 0 || (_actionForm$details = actionForm.details) === null || _actionForm$details === void 0 ? void 0 : _actionForm$details[key]) || ""}`);
		});
		result.detailsText = (detailsTextArr === null || detailsTextArr === void 0 ? void 0 : detailsTextArr.join(", ")) || "";
	}
	if ((actionForm === null || actionForm === void 0 ? void 0 : actionForm.layout) && Array.isArray(actionForm === null || actionForm === void 0 ? void 0 : actionForm.layout)) {
		const layouts = [];
		actionForm.layout.forEach((layout) => {
			const elements = [];
			if ((layout === null || layout === void 0 ? void 0 : layout.elements) && Array.isArray(layout === null || layout === void 0 ? void 0 : layout.elements)) layout.elements.forEach((element) => {
				var _actionForm$propertie;
				const elementKey = (element === null || element === void 0 ? void 0 : element.key) || "";
				const elementLabel = (element === null || element === void 0 ? void 0 : element.label) || "";
				const property = (actionForm === null || actionForm === void 0 || (_actionForm$propertie = actionForm.properties) === null || _actionForm$propertie === void 0 ? void 0 : _actionForm$propertie[elementKey]) || {};
				if (property) {
					const element = {
						_extra: {
							merchantReceipt: params === null || params === void 0 ? void 0 : params.merchant_receipt,
							customerReceipt: params === null || params === void 0 ? void 0 : params.customer_receipt,
							settlementStatus,
							response: data
						},
						key: elementKey,
						name: (property === null || property === void 0 ? void 0 : property.name) || "",
						label: elementLabel,
						submitUrl: (property === null || property === void 0 ? void 0 : property.submit_url) || "",
						action: property === null || property === void 0 ? void 0 : property.action,
						type: (property === null || property === void 0 ? void 0 : property.type) || "button",
						text: property === null || property === void 0 ? void 0 : property.text,
						receipt: elementKey === require_types.EButtonKeyType.PrintMerchantReceipt ? result === null || result === void 0 ? void 0 : result.merchantReceipt : elementKey === require_types.EButtonKeyType.PrintCustomerReceipt ? result === null || result === void 0 ? void 0 : result.customerReceipt : null
					};
					if ((property === null || property === void 0 ? void 0 : property.type) === "image") element.image = {
						name: (property === null || property === void 0 ? void 0 : property.name) || "",
						data: (property === null || property === void 0 ? void 0 : property.data) || "",
						encoding: (property === null || property === void 0 ? void 0 : property.encoding) || ""
					};
					elements.push(element);
				}
			});
			if (elements.length > 0) layouts.push({
				layoutType: layout.type || "unknown",
				elements
			});
		});
		result.layouts = layouts;
	}
	return result;
};
/** 结算查询总超时时长：2 分钟 */
const SETTLEMENT_TOTAL_TIMEOUT = 120 * 1e3;
/** 单次结算查询接口超时：30 秒 */
const SETTLEMENT_QUERY_TIMEOUT = 30 * 1e3;
const createFailedResponse = (message) => {
	return {
		code: -1,
		data: {
			status: "FAILED",
			message: message || _pisell_utils.locales.getText("page.eftpos.text.settlement.failed"),
			pos_instructions: {
				auto_actions: null,
				action_form: {
					layout: [{
						type: "horizontal_layout",
						elements: [{
							label: _pisell_utils.locales.getText("page.eftpos.text.settlement.button.done"),
							key: "settlement_complete"
						}]
					}],
					properties: { settlement_complete: {
						type: "button",
						submit_url: null,
						action: "SETTLEMENT_COMPLETE"
					} },
					details: null
				}
			}
		}
	};
};
/**
* 轮询结算查询接口
* - 总超时 2min：由 mainController 控制，超时后取消当前在途请求并退出循环
* - 单次超时 30s：由 requestController 控制，超时后取消本次请求并发起下一次
* - 唯一停止条件：code === 200 && status === 'FINALISED'
* - 其他任何情况（失败/超时/异常）只要总超时未到，都继续轮询
*/
const pollSettlementQuery = function() {
	var _ref = require_asyncToGenerator._asyncToGenerator(function* (params, callback) {
		let min_version = ((params === null || params === void 0 ? void 0 : params.version) || 0) + 1;
		let isFinished = false;
		let currentRequestController = null;
		const totalTimer = setTimeout(() => {
			isFinished = true;
			if (currentRequestController) {
				currentRequestController.abort();
				currentRequestController = null;
			}
			callback(require_types.ESettlementStatus.Failed, createFailedResponse());
		}, SETTLEMENT_TOTAL_TIMEOUT);
		try {
			while (!isFinished) {
				if (currentRequestController) {
					currentRequestController.abort();
					currentRequestController = null;
				}
				currentRequestController = new AbortController();
				let requestTimeoutTimer = null;
				const requestPromise = () => {
					return new Promise((_, reject) => {
						requestTimeoutTimer = setTimeout(() => {
							if (currentRequestController) currentRequestController.abort();
							reject(createFailedResponse());
						}, SETTLEMENT_QUERY_TIMEOUT);
					});
				};
				try {
					var _queryRes$data, _queryRes$data2;
					const queryRes = yield Promise.race([requestPromise(), require_serve.settlementQueryApi(params === null || params === void 0 ? void 0 : params.id, {
						min_version,
						card_reader_id: params === null || params === void 0 ? void 0 : params.card_reader_id
					}, { signal: currentRequestController.signal })]);
					if (isFinished) break;
					if ((queryRes === null || queryRes === void 0 ? void 0 : queryRes.code) === 200 && (queryRes === null || queryRes === void 0 || (_queryRes$data = queryRes.data) === null || _queryRes$data === void 0 ? void 0 : _queryRes$data.status) === "FINALISED") {
						isFinished = true;
						clearTimeout(totalTimer);
						callback(require_types.ESettlementStatus.Success, queryRes);
						break;
					}
					console.log("settlementQuery_queryRes", queryRes);
					callback(require_types.ESettlementStatus.Processing, queryRes);
					min_version = ((queryRes === null || queryRes === void 0 || (_queryRes$data2 = queryRes.data) === null || _queryRes$data2 === void 0 ? void 0 : _queryRes$data2.version) || 0) + 1;
				} catch (error) {
					if (isFinished) break;
					console.log("settlementQuery_error", error);
				} finally {
					if (requestTimeoutTimer) clearTimeout(requestTimeoutTimer);
					requestTimeoutTimer = null;
				}
			}
		} finally {
			if (totalTimer) clearTimeout(totalTimer);
		}
	});
	return function pollSettlementQuery(_x, _x2) {
		return _ref.apply(this, arguments);
	};
}();
/**
* 结算查询
* @description 首先调用结算发起接口，然后调用结算查询接口
* 1. 首先调用结算发起接口，接口调用成功后调用结算查询接口，并设置 2min 的超时
* 2. 结算查询接口默认有 30s 超时，超时后取消本次请求并继续轮询
* 3. 如果结算查询接口返回 code === 200 && status === 'FINALISED'，则返回成功
* 4. 其他任何情况只要总超时未到，都继续轮询
*/
const settlementQuery = function() {
	var _ref2 = require_asyncToGenerator._asyncToGenerator(function* (params, callback) {
		try {
			var _initiateRes$data, _initiateRes$data2, _initiateRes$data3;
			const initiateRes = yield require_serve.settlementApi(params, {});
			if ((initiateRes === null || initiateRes === void 0 ? void 0 : initiateRes.code) == 200 && (initiateRes === null || initiateRes === void 0 || (_initiateRes$data = initiateRes.data) === null || _initiateRes$data === void 0 ? void 0 : _initiateRes$data.id)) callback(require_types.ESettlementStatus.Processing, initiateRes);
			else {
				callback(require_types.ESettlementStatus.Failed, createFailedResponse(initiateRes === null || initiateRes === void 0 ? void 0 : initiateRes.message));
				return;
			}
			pollSettlementQuery({
				id: initiateRes === null || initiateRes === void 0 || (_initiateRes$data2 = initiateRes.data) === null || _initiateRes$data2 === void 0 ? void 0 : _initiateRes$data2.id,
				version: (initiateRes === null || initiateRes === void 0 || (_initiateRes$data3 = initiateRes.data) === null || _initiateRes$data3 === void 0 ? void 0 : _initiateRes$data3.version) || 0,
				card_reader_id: params === null || params === void 0 ? void 0 : params.card_reader_id
			}, callback);
		} catch (error) {
			callback(require_types.ESettlementStatus.Failed, createFailedResponse(error === null || error === void 0 ? void 0 : error.message));
		}
	});
	return function settlementQuery(_x3, _x4) {
		return _ref2.apply(this, arguments);
	};
}();
//#endregion
exports.parseMX51Params = parseMX51Params;
exports.settlementQuery = settlementQuery;
