import { Application, BackendSession, HandlerService, } from 'pinus';
import { genCode, resResult } from '../../../pubUtils/util';
import { ACTIVITY_TYPE, DEBUG_MAGIC_WORD, DEBUG_PRICE, ITEM_CHANGE_REASON, ORDER_STATE, PAY_TYPE, STATUS, TASK_TYPE, TA_EVENT } from '../../../consts';
import { dicRMB } from '../../../pubUtils/dictionary/DicRMB';
import { UserOrderModel } from '../../../db/UserOrder';
import _ = require('underscore');
import { applyOrderWX } from '../../../services/pay/weixinPay';
import { applyOrderALI } from '../../../services/pay/aliPay';
import { applyOrder37 } from '../../../services/pay/37Pay';
import { checkOrderCanBuy, settleOrder, settleOrderAli, settleOrderFromHandler, settleOrderWx } from '../../../services/orderService';
import { getActivityById } from '../../../services/activity/activityService';
import { reportTAEvent } from '../../../services/sdkService';
import { canPay, isDebugPay } from '../../../pubUtils/sdkUtil';
import { isDevelopEnv } from '../../../services/utilService';
import { getVoucherObject, handleCost } from '../../../services/role/rewardService';
import { CheckMeterial } from '../../../services/role/checkMaterial';

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, useVoucher: boolean }, session: BackendSession) {
        const { productID, payType, activityId, paramStr, useVoucher } = msg;
        const roleId = session.get('roleId');
        const serverId = session.get('serverId');
        const ip = session.get('ip');

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

        if(!canPay()) {
            return resResult(STATUS.PAY_NOT_OPEN)
        }

        //商品价格信息
        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;//客户端需要的平台订单信息

        if(useVoucher) {
            let voucher = getVoucherObject(price);
            let check = new CheckMeterial(roleId);
            let isEnough = await check.decrease([voucher]);
            if (!isEnough) return resResult(STATUS.VOUCHER_NOT_ENOUGH);
        } else {
            switch (payType) {
                case PAY_TYPE.THREE_SEVEN:
                case PAY_TYPE.THREE_SEVEN_IOS:
                    {
                        let pay37Order = await applyOrder37(localOrderID, roleId, productInfo);
                        if (pay37Order.code == -1) {
                            console.log('37下单失败')
                            return pay37Order.resData;
                        }
                        sdkOrderInfo = pay37Order.data;
                        orderID = ''
                        break;
                    }
                case PAY_TYPE.WX:
                    {
                        let weixinOrder = await applyOrderWX(localOrderID, price * 100, message);
                        if (weixinOrder.code == -1) {
                            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 == -1) {
                            console.log('支付宝下单失败')
                            return resResult(STATUS.APPLY_ORDER_ERROR);
                        }
                        sdkOrderInfo = aliOrder.data;
                        orderID = aliOrder.data;//支付宝订单
    
                        break;
                    }
    
                case PAY_TYPE.TEST:
                    {
                        if(!isDevelopEnv()) {
                            return resResult(STATUS.NO_PAY_TYPE);
                        }
                        break;
                    }
                case PAY_TYPE.APPLE:
                    {
                        break;
                    }
                default:
                    console.log('未知支付类型');
                    return resResult(STATUS.NO_PAY_TYPE);
            }
        }

        if(activityId > 0) {
            let activityData = await getActivityById(activityId);
            let check = await checkOrderCanBuy(roleId, serverId, activityData, productID, paramStr);
            if(!check) return resResult(STATUS.ORDER_CANNOT_BUY)
        }


        await UserOrderModel.applyOrder(serverId, roleId, productID, localOrderID, orderID, price, payType, activityId, paramStr, message, useVoucher);
        reportTAEvent(roleId, TA_EVENT.RECHARGE, { 
            pay_id: localOrderID, chargeId: productID, pay_name: message, pay_amount: price, pay_channel: payType
        }, ip)
        if(isDebugPay()) {
            productInfo = {...productInfo, price: DEBUG_PRICE}
        }
        return resResult(STATUS.SUCCESS, { orderInfo: sdkOrderInfo, productInfo: { 
            productID: productInfo.channelProductID,
            message: productInfo.message,
            price: productInfo.price,
         }, 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);
        }

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

        if(orderInfo.useVoucher) {
            let voucher = getVoucherObject(productInfo.price);
            let result = await handleCost(roleId, sid, [voucher], ITEM_CHANGE_REASON.USE_VOUCHER);
            if(!result) return resResult(STATUS.VOUCHER_NOT_ENOUGH);

            let res = await settleOrderFromHandler(localOrderID, roleId, serverId, sid);
            if(res.code != 0) {
                return resResult(res);
            }
            orderInfo = await UserOrderModel.findOrder(localOrderID);
        } else {
            switch (orderInfo.payType) {
                case PAY_TYPE.TEST:
                    {
                        let res = await settleOrderFromHandler(localOrderID, roleId, serverId, sid);
                        if(res.code != 0) {
                            return resResult(res);
                        }
                        orderInfo = await UserOrderModel.findOrder(localOrderID);
                        break;
                    }
                case PAY_TYPE.THREE_SEVEN:
                case PAY_TYPE.THREE_SEVEN_IOS:
                case PAY_TYPE.APPLE:
                    {
                        break;
                    }
                case PAY_TYPE.WX:
                    {
                        let res = await settleOrderWx(orderInfo, serverId, sid);
                        if(res.code != 0) {
                            return resResult(res);
                        }
                        orderInfo = await UserOrderModel.findOrder(localOrderID);
                        break;
                    }
                case PAY_TYPE.ALI:
                    {
                        let res = await settleOrderAli(orderInfo, serverId, sid);
                        if(res.code != 0) {
                            return resResult(res);
                        }
                        orderInfo = await UserOrderModel.findOrder(localOrderID);
                        break;
                    }
    
                default:
                    console.log('未知支付类型');
                    return resResult(STATUS.NO_PAY_TYPE);
            }
        }

        //订单成功
        console.log('结算完成', localOrderID)
        let res: any = {};
        try {
            res = orderInfo.rewardResult? JSON.parse(orderInfo.rewardResult): {};
        } catch(e) {
            console.log('order rewardResult', e);
        }
        if(res.code && res.code != 0) {
            return resResult(STATUS.APPLY_ORDER_ERROR);
        }
        
        return resResult(STATUS.SUCCESS, {
            ...res, 
            price: orderInfo.price,
            state: orderInfo.state,
            localOrderID: orderInfo.localOrderID
        });
    }


    /**
   * @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);
        let check = await checkOrderCanBuy(roleId, serverId, activityData, productID, paramStr);
        if(!check) return resResult(STATUS.ORDER_CANNOT_BUY)

        let orderInfo = await UserOrderModel.applyOrder(serverId, roleId, productID, localOrderID, orderID, price, payType, activityId, paramStr, message, false);

        //订单成功
        if(!orderInfo) {
            return resResult(STATUS.NO_ORDER);
        }
        let result = await settleOrder(orderInfo, serverId, sid);
        orderInfo = await UserOrderModel.success(roleId, localOrderID, JSON.stringify(result));
        console.log(`测试支付完成!!!!!!!!!!!!!  serverId:${serverId}, productID:${productID}, productType:${productType}, roleId:${roleId}, localOrderID:${localOrderID}, payType:${payType}`)
        return resResult(STATUS.SUCCESS, {...result, localOrderID});
    }
}
