import {Context} from "koa";
import axios from "axios";
import {parseString} from "xml2js";

import {ChannelHandler, LoginResult, PaymentResult} from "../interfaces/ChannelHandler";
import {ChannelConfig} from "../../config/channelConfig";
import {SignatureVerifier} from "../../utils/SignatureVerifier";
import QuickAsy from "../../utils/quickAsy";
import {PaymentHelper} from "../../utils/PaymentHelper";

const logger = require("../../utils/log");

/**
 * 0.1渠道（QuickSDK）渠道处理器
 * 负责登录验证与支付回调处理
 */
export class ZeroOneChannelHandler implements ChannelHandler {

    /**
     * QuickSDK 登录验证
     * @param ctx Koa上下文
     * @param config 渠道配置
     */
    async handleLogin(ctx: Context, config: ChannelConfig): Promise<LoginResult> {
        const data = ctx.request.body as any;
        const {token, uid, channel_code, product_code} = data || {};
        const finalProductCode = product_code || config.loginConfig?.productCode;
        const tag = `[渠道${config.channelId}]`;

        if (!token || !uid) {
            logger.warn(`${tag}登录验证失败: 缺少必要参数`, {token, uid});
            return {code: 0, msg: "缺少必要参数 token 或 uid"};
        }

        if (!finalProductCode) {
            logger.error(`${tag}登录验证失败: 未配置productCode`);
            return {code: 0, msg: "服务器未配置productCode"};
        }

        const requestUrl = "http://checkuser.quickapi.net/v2/checkUserInfo";
        const params: Record<string, string> = {
            token,
            uid,
            product_code: finalProductCode
        };
        if (channel_code) {
            params.channel_code = channel_code;
        }

        logger.info(`${tag}登录验证请求`, {url: requestUrl, params});

        try {
            const response = await axios.get(requestUrl, {params, timeout: 8000});
            logger.info(`${tag}登录验证响应`, {data: response.data});

            if (response.data == "1") {
                return {code: 1, msg: "success"};
            }

            logger.warn(`${tag}登录验证失败: 接口返回非1`, {data: response.data});
            return {code: 0, msg: "登录验证失败"};
        } catch (error) {
            logger.error(`${tag}登录验证异常`, error);
            return {code: 0, msg: "登录验证异常"};
        }
    }

    /**
     * QuickSDK 支付回调
     * @param ctx Koa上下文
     * @param config 渠道配置
     */
    async handlePayment(ctx: Context, config: ChannelConfig): Promise<PaymentResult> {
        const data = ctx.request.body as any;
        const tag = `[渠道${config.channelId}]`;
        logger.info(`${tag}支付回调参数`, {url: ctx.href, params: data});

        const {nt_data, sign, md5Sign} = data || {};
        if (!nt_data || !sign || !md5Sign) {
            logger.warn(`${tag}支付回调失败: 缺少必要参数`, {nt_data, sign, md5Sign});
            return {code: 0, msg: "缺少必要参数"};
        }

        const md5Key = config.paymentConfig?.signKey;
        const callbackKey = config.paymentConfig?.callbackKey;

        if (!md5Key || !callbackKey) {
            logger.error(`${tag}支付回调失败: 未配置QuickSDK密钥`);
            return {code: 0, msg: "服务器未配置渠道密钥"};
        }

        if (!SignatureVerifier.verifyQuickSign(data, md5Key)) {
            logger.warn(`${tag}支付回调失败: 签名验证失败`);
            return {code: 0, msg: "签名验证失败"};
        }

        try {
            const xmlData = QuickAsy.decode(nt_data, callbackKey);
            const parsed = await this.parseQuickXml(xmlData);

            const message = parsed.quicksdk_message.message[0];
            const orderId = message.game_order?.[0];
            const outTradeNo = message.order_no?.[0];
            const status = message.status?.[0];
            const amountStr = message.amount?.[0];

            if (!orderId || !outTradeNo || typeof status === "undefined" || !amountStr) {
                logger.error(`${tag}支付回调失败: XML缺少必要字段`, {message});
                return {code: 0, msg: "回调数据不完整"};
            }

            if (status !== "0") {
                logger.warn(`${tag}支付状态非成功`, {status});
                return {code: 0, msg: "支付状态失败"};
            }

            const amount = parseFloat(amountStr);

            const validation = await PaymentHelper.validateOrder(orderId);
            if (!validation.valid) {
                return {
                    code: validation.message?.includes("重复发货") ? 1 : 0,
                    msg: validation.message || "订单验证失败"
                };
            }

            const orderInfo = validation.orderInfo;
            if (Number(orderInfo.amount) !== amount) {
                logger.warn(`${tag}支付金额不匹配`, {
                    orderId,
                    requestAmount: amount,
                    orderAmount: orderInfo.amount
                });
                return {code: 0, msg: "订单金额不一致"};
            }

            logger.info(`${tag}支付订单${orderId}开始发货`);
            const result = await PaymentHelper.deliverOrder(
                orderInfo,
                ctx.request.ip,
                validation.url,
                outTradeNo
            );
            logger.info(`${tag}支付订单${orderId}发货完成`, {result});
            return result;
        } catch (error) {
            logger.error(`${tag}支付回调解析异常`, error);
            return {code: 0, msg: "回调解析异常"};
        }
    }

    private parseQuickXml(xml: string): Promise<any> {
        return new Promise((resolve, reject) => {
            parseString(xml, (err, result) => {
                if (err) {
                    return reject(err);
                }
                resolve(result);
            });
        });
    }
}
