import {Context} from "koa";
import axios from "axios";
import * as crypto from 'crypto';

import {ChannelHandler, LoginResult, PaymentResult} from "../interfaces/ChannelHandler";
import {ChannelConfig} from "../../config/channelConfig";
import {PaymentHelper} from "../../utils/PaymentHelper";
import {
    HKT_ANDROID_PRODUCT_CODE,
    HKT_ANDROID_CALLBACK_KEY,
    HKT_IOS_PRODUCT_CODE,
    HKT_IOS_CALLBACK_KEY,
    HKT_DOMAIN
} from "../../config/thirdParams";

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

/**
 * 港台渠道处理器（Quick海外SDK）
 * 负责登录验证与支付回调处理
 * 支持安卓和iOS平台
 */
export class HongKongTaiwanChannelHandler implements ChannelHandler {
    /**
     * 根据平台获取配置
     * @param platform 平台：android 或 ios
     * @param config 渠道配置
     * @returns 平台特定配置
     */
    private getPlatformConfig(platform: string, config: ChannelConfig) {
        const isIOS = platform === 'ios';
        
        return {
            productCode: isIOS ? HKT_IOS_PRODUCT_CODE : HKT_ANDROID_PRODUCT_CODE,
            callbackKey: isIOS ? HKT_IOS_CALLBACK_KEY : HKT_ANDROID_CALLBACK_KEY,
            domain: HKT_DOMAIN
        };
    }

    /**
     * QuickSDK 登录验证
     * @param ctx Koa上下文
     * @param config 渠道配置
     */
    async handleLogin(ctx: Context, config: ChannelConfig): Promise<LoginResult> {
        const data = ctx.request.body as any;
        const {token, uid, platform} = data || {};
        
        // 默认使用android，如果没有指定platform
        const platformType = platform || 'android';
        const platformConfig = this.getPlatformConfig(platformType, config);
        const finalProductCode = data.product_code || platformConfig.productCode;

        if (!token || !uid) {
            logger.warn("港台渠道登录验证失败: 缺少必要参数", {token, uid, platform: platformType});
            return {code: 0, msg: "缺少必要参数 token 或 uid"};
        }

        if (!finalProductCode) {
            logger.error("港台渠道登录验证失败: 未配置productCode", {platform: platformType});
            return {code: 0, msg: "服务器未配置productCode"};
        }

        // 使用海外QuickSDK的域名
        // 安卓和iOS都使用相同的登录验证接口
        const requestUrl = `${platformConfig.domain}/webapi/checkUserInfo`;
        const params: Record<string, string> = {
            token,
            uid,
            product_code: finalProductCode
        };

        logger.info("港台渠道登录验证请求", {
            platform: platformType,
            url: requestUrl,
            params: {...params, token: token.substring(0, 20) + '...'}
        });

        try {
            const response = await axios.get(requestUrl, {params, timeout: 8000});
            logger.info("港台渠道登录验证响应", {
                platform: platformType,
                data: response.data
            });

            // 根据响应格式判断成功
            // 海外QuickSDK可能返回JSON格式：{"status":true,"message":""}
            // 或者返回字符串 "1" 表示成功
            if (typeof response.data === 'string' && response.data === "1") {
                return {code: 1, msg: "success"};
            } else if (typeof response.data === 'object' && response.data.status === true) {
                return {code: 1, msg: "success"};
            }

            logger.warn("港台渠道登录验证失败: 接口返回非成功", {
                platform: platformType,
                data: response.data
            });
            return {code: 0, msg: "登录验证失败"};
        } catch (error: any) {
            logger.error("港台渠道登录验证异常", {
                platform: platformType,
                error: error.message
            });
            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;
        logger.info("港台渠道支付回调参数", {url: ctx.href, params: data});

        // 海外版本直接使用明文字段，不需要nt_data和XML解密
        const {
            uid,
            username,
            cpOrderNo,
            orderNo,
            payTime,
            payType,
            payAmount,
            payCurrency,
            usdAmount,
            payStatus,
            actRate,
            extrasParams,
            subscriptionStatus,
            subReason,
            sign,
            platform
        } = data || {};

        // 验证必要参数
        if (!uid || !username || !orderNo || !payTime || !payType || !payAmount || 
            !payCurrency || !usdAmount || typeof payStatus === "undefined" || 
            !actRate || !sign) {
            logger.warn("港台渠道支付回调失败: 缺少必要参数", {
                uid: !!uid,
                username: !!username,
                orderNo: !!orderNo,
                payTime: !!payTime,
                payType: !!payType,
                payAmount: !!payAmount,
                payCurrency: !!payCurrency,
                usdAmount: !!usdAmount,
                payStatus: typeof payStatus !== "undefined",
                actRate: !!actRate,
                sign: !!sign
            });
            return {code: 0, msg: "缺少必要参数"};
        }

        // 从请求中获取platform，如果没有则尝试从数据中推断
        // 默认使用android
        const platformType = extrasParams == "" ? "ios" : 'android';
        const platformConfig = this.getPlatformConfig(platformType, config);

        const callbackKey = platformConfig.callbackKey;

        if (!callbackKey) {
            logger.error("港台渠道支付回调失败: 未配置回调密钥", {platform: platformType});
            return {code: 0, msg: "服务器未配置回调密钥"};
        }

        // 验证sign签名（使用callbackKey）
        // 根据文档：移除sign字段 -> 按首字母升序排序 -> 拼接成key=val&格式 -> 拼接callbackKey -> MD5
        if (!this.verifyCallbackSign(data, callbackKey)) {
            logger.warn("港台渠道支付回调失败: sign签名验证失败", {platform: platformType});
            return {code: 0, msg: "签名验证失败"};
        }

        try {
            // 检查订阅状态（如果有subscriptionStatus字段，且值为2，表示订阅取消，不需要发货）
            if (subscriptionStatus !== undefined && subscriptionStatus === "2") {
                logger.info("港台渠道支付回调: 订阅取消，不需要发货", {
                    platform: platformType,
                    orderNo,
                    subscriptionStatus,
                    subReason
                });
                return {code: 1, msg: "订阅取消，不需要发货"};
            }

            // 验证支付状态（0表示成功，1表示失败）
            if (payStatus !== "0") {
                logger.warn("港台渠道支付状态非成功", {
                    platform: platformType,
                    orderNo,
                    payStatus
                });
                return {code: 0, msg: `支付状态失败: ${payStatus}`};
            }

            // 使用cpOrderNo作为订单ID（如果为空则使用orderNo）
            const orderId = cpOrderNo || orderNo;
            
            if (!orderId) {
                logger.error("港台渠道支付回调失败: 缺少订单号", {
                    platform: platformType,
                    cpOrderNo,
                    orderNo
                });
                return {code: 0, msg: "缺少订单号"};
            }

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

            const orderInfo = validation.orderInfo;
            
            // 验证金额（payAmount单位是元）
            const paymentAmount = parseFloat(payAmount);
            if (Math.abs(Number(orderInfo.amount) - paymentAmount) > 0.01) {
                logger.warn("港台渠道支付金额不匹配", {
                    platform: platformType,
                    orderId,
                    requestAmount: paymentAmount,
                    orderAmount: orderInfo.amount
                });
                return {code: 0, msg: `订单金额不一致: 订单金额${orderInfo.amount}元，支付金额${paymentAmount}元`};
            }

            logger.info(`港台渠道支付订单${orderId}开始发货`, {
                platform: platformType,
                orderNo,
                uid,
                username,
                payAmount: paymentAmount,
                payCurrency,
                actRate
            });
            
            const result = await PaymentHelper.deliverOrder(
                orderInfo,
                ctx.request.ip,
                validation.url,
                orderNo // 使用SDK订单号作为out_trade_no
            );
            
            logger.info(`港台渠道支付订单${orderId}发货完成`, {
                platform: platformType,
                result
            });
            
            return result;
        } catch (error: any) {
            logger.error("港台渠道支付回调处理异常", {
                platform: platformType,
                error: error.message,
                stack: error.stack
            });
            return {code: 0, msg: "回调处理异常"};
        }
    }

    /**
     * 验证回调签名（使用callbackKey）
     * 根据文档签名算法：
     * 1. 移除sign字段
     * 2. 按首字母升序排序
     * 3. 拼接成 key1=val1&key2=val2&key3=val3& 格式
     * 4. 拼接callbackKey
     * 5. MD5编码
     * 6. 与收到的sign对比
     * @param data 回调数据
     * @param callbackKey 回调密钥
     * @returns 验证结果
     */
    private verifyCallbackSign(data: any, callbackKey: string): boolean {
        try {
            const receivedSign = data.sign;
            if (!receivedSign) {
                logger.error("港台渠道支付回调: 缺少sign字段");
                return false;
            }

            // 1. 移除sign字段
            const params = {...data};
            delete params.sign;

            // 2. 按首字母升序排序
            const sortedKeys = Object.keys(params).sort();

            // 3. 拼接成 key1=val1&key2=val2&key3=val3& 格式
            const signStr = sortedKeys.map(key => {
                const value = params[key];
                // 处理null和undefined
                if (value === null || value === undefined) {
                    return '';
                }
                return `${key}=${value}&`;
            }).join('');

            // 4. 拼接callbackKey
            const stringToSign = signStr + callbackKey;

            // 5. MD5编码（32位小写）
            const calculatedSign = crypto.createHash('md5').update(stringToSign).digest('hex').toLowerCase();

            logger.info("港台渠道支付回调签名验证详情:", {
                sortedKeys,
                signStr: signStr.substring(0, 200) + '...', // 只显示前200个字符
                stringToSign: stringToSign.substring(0, 200) + '...',
                calculatedSign,
                receivedSign,
                isValid: calculatedSign === receivedSign.toLowerCase()
            });

            // 6. 与收到的sign对比（不区分大小写）
            return calculatedSign === receivedSign.toLowerCase();
        } catch (error: any) {
            logger.error("港台渠道支付回调签名验证出错:", error);
            return false;
        }
    }
}
