import { _asyncToGenerator } from "../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/asyncToGenerator.js";
import { _objectWithoutProperties } from "../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectWithoutProperties.js";
import { PayStatus } from "../const.js";
import payLog from "../utils/payLog.js";
import { useRef } from "react";
//#region src/components/eftposPay/payo/payment.ts
const _excluded = ["pay_param_base64"];
/**
* 实现支付和查询一体化的接口
* 核心点：
* 1.发起支付，在十秒钟后发起轮询操作，两个接口谁先返回成功用谁的结果，如果返回的失败是存在明确code信息的则全部失败
* 2.轮询操作总查询时间2分钟，超时直接失败，单次轮询超时时间5秒，超时直接abort本次请求，间隔两秒后发起新的请求
* 3.最终成功或者失败都需要把定时器给清理掉，并将未完成的接口abort掉
*/
const QUERY_START_DELAY = 1e3 * 10;
const GLOBAL_TIMEOUT = 1e3 * 60 * 2;
const REQUEST_TIMEOUT = 1e3 * 10;
const QUERY_INTERVAL = 1e3 * 2;
let ActionType = /* @__PURE__ */ function(ActionType) {
	ActionType["Pay"] = "pay";
	ActionType["Refund"] = "refund";
	ActionType["Query"] = "query";
	return ActionType;
}({});
/**
* 判断请求是否需要等待轮询结果
* 1. 有明确错误code且不是超时和支付超时，则直接失败
* @param code 错误码
*/
const isRequestFailed = (code) => {
	return code && `${code}` !== PayStatus.Timeout && `${code}` !== PayStatus.PayTimeout;
};
const usePayment = (options) => {
	const { payApi, refundApi, checkApi, shouldContinue = () => true } = options;
	const payControllerRef = useRef(null);
	const queryControllerRef = useRef(null);
	const queryStartTimerRef = useRef(null);
	const globalTimeoutTimerRef = useRef(null);
	const requestTimeoutTimerRef = useRef(null);
	const queryIntervalTimerRef = useRef(null);
	const isFinishedRef = useRef(false);
	const isQueryingRef = useRef(false);
	const callbacksRef = useRef(null);
	const isRequestTimeoutRef = useRef(false);
	const currentQueryIdRef = useRef(0);
	const currentRunIdRef = useRef(0);
	/**
	* 清理所有定时器和控制器
	* @param clearCallbacks 是否清空回调引用，默认为 true
	*/
	const clean = (params) => {
		const { clearCallbacks = true } = params || {};
		console.log("🧹 清理所有资源", { clearCallbacks });
		if (payControllerRef.current) {
			payControllerRef.current.abort();
			payControllerRef.current = null;
		}
		if (queryControllerRef.current) {
			queryControllerRef.current.abort();
			queryControllerRef.current = null;
		}
		if (queryStartTimerRef.current) {
			clearTimeout(queryStartTimerRef.current);
			queryStartTimerRef.current = null;
		}
		if (globalTimeoutTimerRef.current) {
			clearTimeout(globalTimeoutTimerRef.current);
			globalTimeoutTimerRef.current = null;
		}
		if (requestTimeoutTimerRef.current) {
			clearTimeout(requestTimeoutTimerRef.current);
			requestTimeoutTimerRef.current = null;
		}
		if (queryIntervalTimerRef.current) {
			clearTimeout(queryIntervalTimerRef.current);
			queryIntervalTimerRef.current = null;
		}
		isQueryingRef.current = false;
		isFinishedRef.current = false;
		isRequestTimeoutRef.current = false;
		if (clearCallbacks !== false) callbacksRef.current = null;
	};
	/**
	* 标记为完成状态并清理资源（包括回调）
	*/
	const finish = () => {
		if (!isFinishedRef.current) {
			clean();
			isFinishedRef.current = true;
		}
	};
	/**
	* 处理成功结果
	*/
	const handleFinalSuccess = (res, type) => {
		var _callbacksRef$current, _callbacksRef$current2;
		if (isFinishedRef.current || !shouldContinue()) {
			payLog.log(`handleFinalSuccess: 已完成或不应继续处理，忽略${type}操作成功结果`);
			return;
		}
		payLog.log("接口最终结果：支付成功", {
			type,
			res
		});
		(_callbacksRef$current = callbacksRef.current) === null || _callbacksRef$current === void 0 || (_callbacksRef$current2 = _callbacksRef$current.onSuccess) === null || _callbacksRef$current2 === void 0 || _callbacksRef$current2.call(_callbacksRef$current, res);
		finish();
	};
	/**
	* 处理错误（最终失败）
	* @param error 错误信息
	* @param source 错误来源
	*/
	const handleFinalError = (error, type) => {
		var _callbacksRef$current3, _callbacksRef$current4;
		if (isFinishedRef.current || !shouldContinue()) {
			payLog.log(`handleFinalError: 已完成或不应继续处理，忽略${type}操作错误`);
			return;
		}
		payLog.log("接口最终结果：支付失败", {
			type,
			error
		});
		(_callbacksRef$current3 = callbacksRef.current) === null || _callbacksRef$current3 === void 0 || (_callbacksRef$current4 = _callbacksRef$current3.onError) === null || _callbacksRef$current4 === void 0 || _callbacksRef$current4.call(_callbacksRef$current3, error);
		finish();
	};
	/**
	* 创建超时 Promise
	*/
	const createTimeoutPromise = (timeoutMs) => {
		return new Promise((_, reject) => {
			requestTimeoutTimerRef.current = setTimeout(() => {
				payLog.log(`⏱️ 单次查询超时（${timeoutMs / 1e3}秒），强制终止`);
				isRequestTimeoutRef.current = true;
				if (queryControllerRef.current) queryControllerRef.current.abort();
				reject(/* @__PURE__ */ new Error("REQUEST_TIMEOUT"));
			}, timeoutMs);
		});
	};
	/**
	* 单次查询请求
	*/
	const performQuery = function() {
		var _ref = _asyncToGenerator(function* (paymentNum) {
			if (isFinishedRef.current || !shouldContinue()) {
				payLog.log("支付轮询前置校验：已完成或不应继续，取消查询");
				return;
			}
			if (queryControllerRef.current) {
				queryControllerRef.current.abort();
				queryControllerRef.current = null;
			}
			if (requestTimeoutTimerRef.current) {
				clearTimeout(requestTimeoutTimerRef.current);
				requestTimeoutTimerRef.current = null;
			}
			const queryId = Date.now();
			currentQueryIdRef.current = queryId;
			isRequestTimeoutRef.current = false;
			queryControllerRef.current = new AbortController();
			const { signal } = queryControllerRef.current;
			try {
				payLog.log("支付轮询：开始单次查询");
				const res = yield Promise.race([checkApi({ number: paymentNum }, { signal }), createTimeoutPromise(REQUEST_TIMEOUT)]);
				if (requestTimeoutTimerRef.current) {
					clearTimeout(requestTimeoutTimerRef.current);
					requestTimeoutTimerRef.current = null;
				}
				if (queryId < currentQueryIdRef.current) {
					payLog.log("支付轮询结果：过期的查询响应，忽略");
					return;
				}
				if (isFinishedRef.current || !shouldContinue()) {
					payLog.log("支付轮询结果：已完成或不应继续处理");
					return;
				}
				if (res && `${res.code}` === "200") {
					payLog.log("支付轮询结果：支付成功");
					handleFinalSuccess(res, ActionType.Query);
					return;
				}
				if (isRequestFailed(res === null || res === void 0 ? void 0 : res.code)) {
					payLog.log("支付轮询结果：有明确错误code，停止轮询", { code: res === null || res === void 0 ? void 0 : res.code });
					handleFinalError(res, ActionType.Query);
				} else {
					payLog.log("支付轮询结果：无明确code，继续轮询", { code: res === null || res === void 0 ? void 0 : res.code });
					scheduleNextQuery(paymentNum);
				}
			} catch (error) {
				if (requestTimeoutTimerRef.current) {
					clearTimeout(requestTimeoutTimerRef.current);
					requestTimeoutTimerRef.current = null;
				}
				if (queryId < currentQueryIdRef.current) {
					payLog.log("支付轮询结果：error-过期的查询异常，忽略");
					return;
				}
				if (isFinishedRef.current || !shouldContinue()) return;
				if (isRequestTimeoutRef.current || (error === null || error === void 0 ? void 0 : error.name) === "AbortError" || (error === null || error === void 0 ? void 0 : error.message) === "REQUEST_TIMEOUT") {
					payLog.log("支付轮询结果：error-请求被取消或超时，继续轮询");
					scheduleNextQuery(paymentNum);
					return;
				}
				if (isRequestFailed(error === null || error === void 0 ? void 0 : error.code)) {
					payLog.log("支付轮询结果：error-有明确错误code，停止轮询", { code: error === null || error === void 0 ? void 0 : error.code });
					handleFinalError(error, ActionType.Query);
				} else {
					payLog.log("支付轮询结果：error-无明确code，继续轮询", { code: error === null || error === void 0 ? void 0 : error.code });
					scheduleNextQuery(paymentNum);
				}
			}
		});
		return function performQuery(_x) {
			return _ref.apply(this, arguments);
		};
	}();
	/**
	* 安排下一次查询
	*/
	const scheduleNextQuery = (paymentNum) => {
		if (isFinishedRef.current || !shouldContinue()) return;
		if (queryIntervalTimerRef.current) clearTimeout(queryIntervalTimerRef.current);
		queryIntervalTimerRef.current = setTimeout(() => {
			payLog.log("支付轮询：安排下一次查询");
			performQuery(paymentNum);
		}, QUERY_INTERVAL);
	};
	/**
	* 开始轮询
	*/
	const startQuery = (paymentNum) => {
		if (isFinishedRef.current || !shouldContinue() || isQueryingRef.current) return;
		isQueryingRef.current = true;
		globalTimeoutTimerRef.current = setTimeout(() => {
			if (isFinishedRef.current) return;
			console.log("⏱️ 轮询全局超时（2分钟），终止所有请求");
			payLog.log("轮询全局超时（2分钟），终止所有请求");
			handleFinalError({
				code: PayStatus.Timeout,
				message: "交易超时"
			}, ActionType.Query);
		}, GLOBAL_TIMEOUT);
		performQuery(paymentNum);
	};
	/**
	* 发起支付并在10秒后开始轮询
	*/
	const run = function() {
		var _ref3 = _asyncToGenerator(function* (options) {
			const { paymentType = ActionType.Pay, params, paymentNum, callbacks } = options;
			const runId = Date.now();
			currentRunIdRef.current = runId;
			const _ref2 = params || {}, { pay_param_base64 } = _ref2;
			_objectWithoutProperties(_ref2, _excluded);
			isFinishedRef.current = true;
			clean({ clearCallbacks: false });
			callbacksRef.current = callbacks;
			queryStartTimerRef.current = setTimeout(() => {
				payLog.log("支付后10秒开始轮询");
				startQuery(paymentNum);
			}, QUERY_START_DELAY);
			payControllerRef.current = new AbortController();
			const { signal } = payControllerRef.current;
			try {
				payLog.log("发起支付请求");
				const resultPromise = paymentType === ActionType.Pay ? payApi : refundApi;
				if (!resultPromise) throw new Error(`${paymentType === ActionType.Pay ? "支付" : "退款"}接口不存在`);
				const res = yield resultPromise === null || resultPromise === void 0 ? void 0 : resultPromise(params, { signal });
				if (runId < currentRunIdRef.current) {
					payLog.log("支付响应过期，忽略");
					return;
				}
				if (isFinishedRef.current || !shouldContinue()) {
					payLog.log("支付返回时已完成或不应继续处理");
					return;
				}
				if (res && `${res.code}` === "200") {
					payLog.log("支付接口成功");
					handleFinalSuccess(res, paymentType);
					return;
				}
				if (isRequestFailed(res === null || res === void 0 ? void 0 : res.code)) {
					payLog.log("支付接口返回失败", { code: res === null || res === void 0 ? void 0 : res.code });
					handleFinalError(res, ActionType.Pay);
				} else payLog.log("支付超时或无明确错误，等待轮询结果", { code: res === null || res === void 0 ? void 0 : res.code });
			} catch (error) {
				if (runId < currentRunIdRef.current) {
					payLog.log("支付异常响应过期，忽略");
					return;
				}
				if (isFinishedRef.current || !shouldContinue()) {
					payLog.log("支付异常时已完成或不应继续处理");
					return;
				}
				if (isRequestFailed(error === null || error === void 0 ? void 0 : error.code)) {
					payLog.log("支付接口异常", { code: error === null || error === void 0 ? void 0 : error.code });
					handleFinalError(error, paymentType);
				} else payLog.log("支付异常超时或无明确错误，等待轮询结果", { code: error === null || error === void 0 ? void 0 : error.code });
			}
		});
		return function run(_x2) {
			return _ref3.apply(this, arguments);
		};
	}();
	/**
	* 手动停止（完全清理，包括回调）
	*/
	const stop = () => {
		payLog.log("手动停止支付流程");
		clean();
		isFinishedRef.current = true;
	};
	return {
		run,
		stop,
		clean
	};
};
//#endregion
export { ActionType, usePayment };
