import { Application, BackendSession, HandlerService, } from 'pinus';
import { genCode, resResult } from '../../../pubUtils/util';
import { ACTIVITY_TYPE, DEBUG_MAGIC_WORD, ORDER_STATE, PAY_TYPE, STATUS, TASK_TYPE } from '../../../consts';
import { dicRMB } from '../../../pubUtils/dictionary/DicRMB';
import { UserOrderModel } from '../../../db/UserOrder';
import _ = require('underscore');
import { applyOrderWX, checkOrderWX } from '../../../services/pay/weixinPay';
import { applyOrderALI, checkOrderALI } from '../../../services/pay/aliPay';
import { makeOrder } from '../../../services/orderService';
import { addRechargeMoney } from '../../../services/activity/rechargeMoneyService';
import { ActivityModel, ActivityModelType } from '../../../db/Activity';
import { ServerlistModel } from '../../../db/Serverlist';
import { addVipRechargeMoney } from '../../../services/activity/vipRechargeMoneyService';
import { checkActivityTask } from '../../../services/taskService';
import { getActivityById } from '../../../services/activity/activityService';

export default function (app: Application) {
    new HandlerService(app, {});
    return new orderHandler(app);
}

export class orderHandler {
    constructor(private app: Application) {
    }

    /************************订单****************************/

    /**
    * @description 获取订单号
    * @param {{productID:string, payType:number ,activityId: number, paramStr: string  }} msg
    * @param {BackendSession} session
    * @memberof orderHandler
    */
    async applyOrder(msg: { productID: string, payType: number, activityId: number, paramStr: string }, session: BackendSession) {
        const { productID, payType, activityId, paramStr } = msg;
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');

        //如果有特殊情况，activityId可为0
        if (!productID || !_.isString(productID) || !payType || !_.isNumber(payType)) {
            return resResult(STATUS.WRONG_PARMS);
        }

        //商品价格信息
        let productInfo = dicRMB.get(productID)
        if (!productInfo) {
            console.log('productID', productID)
            return resResult(STATUS.NO_PRODUCT_ID);
        }

        let price = productInfo.price;//价格
        let productType = productInfo.type;//类型
        let message = productInfo.message;//商品信息
        let localOrderID = genCode(32);//本地订单号
        let orderID = '';//平台订单号
        let sdkOrderInfo = null;//客户端需要的平台订单信息
        switch (payType) {
            case PAY_TYPE.WX:
                {
                    let weixinOrder = await applyOrderWX(localOrderID, price * 100, message);
                    if (weixinOrder.code == 0) {
                        console.log('微信下单失败')
                        return resResult(STATUS.APPLY_ORDER_ERROR);
                    }
                    sdkOrderInfo = weixinOrder.data;
                    orderID = weixinOrder.data.prepayid;//微信订单号
                    break;
                }
            case PAY_TYPE.ALI:
                {
                    let aliOrder = await applyOrderALI(localOrderID, price, message);
                    if (aliOrder.code == 0) {
                        console.log('支付宝下单失败')
                        return resResult(STATUS.APPLY_ORDER_ERROR);
                    }
                    sdkOrderInfo = aliOrder.data;
                    orderID = aliOrder.data;//支付宝订单

                    break;
                }

            case PAY_TYPE.APPLE:
                {
                    break;
                }
            default:
                console.log('未知支付类型');
                return resResult(STATUS.NO_PAY_TYPE);
        }
        await UserOrderModel.applyOrder(serverId, roleId, productID, localOrderID, orderID, price, payType, activityId, paramStr, message);
        return resResult(STATUS.SUCCESS, { orderInfo: sdkOrderInfo, productInfo, localOrderID });
    }

    /**
        * @description 查询订单，结算奖励                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
        * @param {{ localOrderID: string}} msg
        * @param {BackendSession} session
        * @memberof firstGiftHandler
        */
    async checkOrder(msg: { localOrderID: string }, session: BackendSession) {
        const { localOrderID } = msg;
        // const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const sid = session.get('sid');
        const roleName = session.get('roleName');
        
        if (!localOrderID || !_.isString(localOrderID)) {
            return resResult(STATUS.WRONG_PARMS);
        }
        let orderInfo = await UserOrderModel.findOrder(localOrderID);
        if (!orderInfo) {
            return resResult(STATUS.NO_ORDER);
        }
        if (orderInfo.state == ORDER_STATE.RESULT_SUCCESS) {
            return resResult(STATUS.DUPLICATE_ORDER);
        }

        //商品价格信息
        let productInfo = dicRMB.get(orderInfo.productID)
        if (!productInfo) {
            console.log(orderInfo.productID)
            return resResult(STATUS.NO_PRODUCT_ID);
        }

        let productType = productInfo.type;//类型
        let price = orderInfo.price;//下单时的价格
        let payType = orderInfo.payType;//支付类型
        let roleId = orderInfo.roleId;//角色

        orderInfo = await UserOrderModel.check(roleId, localOrderID);
        if (!orderInfo) {
            return resResult(STATUS.DUPLICATE_ORDER);
        }
        switch (payType) {
            case PAY_TYPE.WX:
                {
                    let weixinResult = await checkOrderWX(localOrderID);
                    if (weixinResult.code == 0) {
                        console.log('微信订单查询失败')
                        return resResult(STATUS.ORDER_ERROR);
                    }
                    if (parseInt(weixinResult.data.total_fee) / 100 != price) {
                        console.log('订单价格错误')
                        return resResult(STATUS.PRICE_ERROR);
                    }
                    if (weixinResult.data.trade_state != "SUCCESS" ||
                        weixinResult.data.result_code != "SUCCESS" ||
                        weixinResult.data.return_code != "SUCCESS") {
                        return resResult(STATUS.NO_PAY);
                    }
                    break;
                }
            case PAY_TYPE.ALI:
                {
                    let aliResult = await checkOrderALI(localOrderID);
                    if (aliResult.code == 0) {
                        console.log('支付宝订单查询失败')
                        return resResult(STATUS.ORDER_ERROR);
                    }
                    if (parseInt(aliResult.data.total_amount) != price) {
                        console.log('订单价格错误')
                        return resResult(STATUS.PRICE_ERROR);
                    }
                    if (aliResult.data.trade_status != "TRADE_SUCCESS") {
                        return resResult(STATUS.NO_PAY);
                    }
                    let aliOrderID = aliResult.data.trade_no;
                    await UserOrderModel.saveOrderID(roleId, localOrderID, aliOrderID);
                    break;
                }

            case PAY_TYPE.APPLE:
                {
                    break;
                }
            default:
                console.log('未知支付类型');
                return resResult(STATUS.NO_PAY_TYPE);
        }

        //订单成功
        orderInfo = await UserOrderModel.success(roleId, localOrderID);
        if (orderInfo) {

            //结算奖励
            let result = await makeOrder(localOrderID, sid, orderInfo);
            if (result.code !== 0) {//结算失败
                console.log(`测试支付失败..... ${JSON.stringify(result)}`)
                return resResult(result);
            }
            //推送
            this.app.channelService.pushMessageByUids('onOrder', resResult(STATUS.SUCCESS, {
                data: result.data,
                price: price,
            }), [{ uid: roleId, sid: sid }]);
            //活动统计
            await addRechargeMoney(roleId, serverId, price);
            await addVipRechargeMoney(roleId, serverId, price);
            //成长任务
            await checkActivityTask(serverId, sid, roleId, TASK_TYPE.ACTIVITY_RMB, price, { activityId: orderInfo.activityId })


            console.log('结算完成', localOrderID)
            return resResult(STATUS.SUCCESS, result.data);
        }

        return resResult(STATUS.DUPLICATE_ORDER);
    }


    /**
   * @description 支付测试
   * @param {{productID:string, magicWord:string,  paramStr: string }} msg
   * @param {BackendSession} session
   * @memberof orderHandler
   */
    async debugOrder(msg: { productID: string, magicWord: string, paramStr: string, activityId: number }, session: BackendSession) {
        const { magicWord, productID, paramStr, activityId } = msg;
        if (magicWord !== DEBUG_MAGIC_WORD || !activityId) {
            return resResult(STATUS.WRONG_PARMS);
        }

        const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const sid = session.get('sid');
        const roleName = session.get('roleName');
        

        let payType = PAY_TYPE.TEST
        //如果有特殊情况，activityId可为0
        if (!productID || !_.isString(productID)) {
            return resResult(STATUS.WRONG_PARMS);
        }

        //商品价格信息
        let productInfo = dicRMB.get(productID)
        if (!productInfo) {
            console.log('productID', productID)
            return resResult(STATUS.NO_PRODUCT_ID);
        }

        let price = productInfo.price;//价格
        let productType = productInfo.type;//类型
        let message = productInfo.message;//商品信息
        let localOrderID = genCode(32);//本地订单号
        let orderID = '';//平台订单号
        let sdkOrderInfo = null;//客户端需要的平台订单信息

        // let { activityGroupId } = await ServerlistModel.findByServerId(serverId);
        // let activityArray: ActivityModelType[] = await ActivityModel.findActivityByType(activityGroupId, productType, -1);
        // if (activityArray.length === 0) {
        //     return resResult(STATUS.ACTIVITY_MISSING);
        // }
        let activityData = await getActivityById(activityId);
        if (!activityData) return resResult(STATUS.ACTIVITY_MISSING);
        await UserOrderModel.applyOrder(serverId, roleId, productID, localOrderID, orderID, price, payType, activityId, paramStr, message);

        //订单成功
        let orderInfo = await UserOrderModel.success(roleId, localOrderID);
        if (orderInfo) {
            //结算奖励
            let result = await makeOrder(localOrderID, sid, orderInfo);
            if (result.code !== 0) {//结算失败
                console.log(`测试支付失败..... ${JSON.stringify(result)}`)
                return resResult(result);
            }
            //推送
            this.app.channelService.pushMessageByUids('onOrder', resResult(STATUS.SUCCESS, {
                data: result.data,
                price: price,
            }), [{ uid: roleId, sid: sid }]);
            //活动统计
            await addRechargeMoney(roleId, serverId, price);
            await addVipRechargeMoney(roleId, serverId, price);
            //成长任务
            await checkActivityTask(serverId, sid, roleId, TASK_TYPE.ACTIVITY_RMB, price, { activityId })
            console.log(`测试支付完成!!!!!!!!!!!!!  serverId:${serverId}, productID:${productID}, productType:${productType}, roleId:${roleId}, localOrderID:${localOrderID}, payType:${payType}`)
            return resResult(STATUS.SUCCESS, result.data);
        }

        return resResult(STATUS.NO_ORDER, {});
    }
}
