
'use strict';

const Service = require('egg').Service;
const moment = require('moment');
const _ = require('lodash');
const TypeConfig = {
    blacklist: 1,
    callrisk: 2
}
const TypeConfigFlip = {
    1: 'blacklist',
    2: 'callrisk',
}
class OrderService extends Service {

    //历史订单
    async getHistoryOrders(order_type) {

        const { ctx } = this;

        const user_id = ctx.userId;
        const app_type_id = ctx.appTypeId;
        const app_user_id = ctx.appUserId;
        const app_id = ctx.appId;

        const type = TypeConfig[order_type];
        // const where = { user_id };
        const order_records = await ctx.prometheusModel.CreditOrder.all({ where: { user_id, type, valid: 1 }, order: [['order_time', 'desc']] });
        const worth_h = [];
        const worth_l = [];

        for (let i in order_records) {

            const order = await this.updateOrderStateToOverdue(order_records[i]);
            if (order.state === '已失效') continue;
            const is_expire = await this.checkOrderExpire(order);

            // const apply = { phone: '15968762898', report_no: '51gjj201909050100001' };//TODO query apply
            const item = {
                order_id: order.id,
                order_no: order.order_no,
                report_id: order.report_id,
                type: order_type,
                created_time: moment(order.order_time).format('YYYY-MM-DD HH:mm'),
                phone: order.phone.replace(order.phone.substring(3, 7), "****"),
                state: order.state,
                state_text: order.state === '已支付' ? '' : order.state,
            };
            if (!is_expire) {
                worth_h.push(item);
            } else {
                worth_l.push(item);
            }
        }

        return { worth_h, worth_l }
    }

    //更新订单状态为已失效
    async updateOrderStateToOverdue(order) {

        const { ctx } = this;
        let { id, order_time, state, pay_status, state_time } = order;
        if (!id || !order_time || !state || typeof (pay_status) === 'undefined') {
            return order;
        }
        const expire_time = moment(order_time).valueOf() + 24 * 3600 * 1000;
        const now_time = moment().valueOf();
        if (['支付中'].includes(state) && moment(state_time).valueOf() + 300 < now_time) {
            await this.logOrder(id);
            await ctx.prometheusModel.CreditOrder.update({ state: '待支付', state_time: state_time }, { where: { id } });
        }
        state_time = moment().format('YYYY-MM-DD HH:mm:ss');
        if (expire_time < now_time && ['待支付', '已取消', '支付中'].includes(state)) {
            await this.logOrder(id);
            const ret = await ctx.prometheusModel.CreditOrder.update({ state: '已失效', state_time: state_time }, { where: { id } });
            if (ret && ret[0]) {
                order.state = '已失效';
                order.state_time = state_time;
            }
        }
        return order;

    }

    //将订单更新为已取消
    async updateOrderStateToCancel(order) {

        const { ctx } = this;
        const user_id = ctx.userId;
        const { id, phone, name, id_card } = order;
        let status = false;
        if (!id || !phone || !name || !id_card) {
            return status;
        }
        const state_time = moment().format('YYYY-MM-DD HH:mm:ss');
        const where = { user_id, name: { $ne: name }, id_card: { $ne: id_card }, id: { $ne: id }, state: { $in: ['待支付', '支付中'] } };
        const other_orders = await ctx.prometheusModel.CreditOrder.findAll({ where, });
        for (let i in other_orders) {
            await this.logOrder(other_orders[i].id);
            // await this.logOrder(other_orders[i]);
        }
        const ret = await ctx.prometheusModel.CreditOrder.update({ state: '已取消', state_time: state_time }, { where });
        if (ret && ret[0]) {
            status = true;
        }
        return status;
    }

    //更新订单优惠价格
    async updateOrderPrice(order) {

        const { ctx } = this;
        const user_id = ctx.userId;
        // const order = await ctx.service.credit.common.getOrderInfo(order_id);
        const { id, type, } = order;
        if (!id || !type) {
            ctx.failed('error order');
        }

        const slag = TypeConfigFlip[type];
        const preferential = await ctx.service.credit.preferential.getPreferential(slag);
        let preferential_price = 0;
        let preferential_id = 0;
        if (preferential && preferential.id) {
            preferential_price = preferential.price;
            preferential_id = preferential.id;
        }
        const price = (order.price - preferential_price).toFixed(2);

        await ctx.prometheusModel.CreditOrder.update({ final_price: price, preferential_price, preferential_id: preferential_id }, { where: { id, pay_status: 0 } });

        return price;

    }

    //检查订单报告是否 还在规定的时间内 是否具有高价值 0：高价值 ;   1：低价值-生成时间过长-
    async checkOrderExpire(order) {

        const { ctx } = this;
        const { id, type, state_time, state, pay_status } = order;
        if (!id || !type || !state_time || !state || typeof (pay_status) === 'undefined') {
            return 0;
        }

        const worth_time = type === 1 ? 15 : 30;
        const expire_time = moment(state_time).valueOf() + worth_time * 86400 * 1000;
        const now_time = moment().valueOf();
        const state_array = ['已支付'];
        if (!state_array.includes(state) || expire_time > now_time) {//还在规定的有效期内 高价值报告
            return 0;
        }

        return 1;
    }

    /**
     * 
     * @param {*} type 报告类型(黑名单blacklist通话callrisk)
     * @param {*} reportId 订单编号
     */
    async getReportValid(type, reportId) {
        const { ctx } = this;
        let valid = 0;
        if (!TypeConfig.hasOwnProperty(type)) {
            return valid;
        }
        let timeLine = (TypeConfig[type] === 1) ? 15 : 30;
        let orderFilter = {
            where: {
                report_id: reportId,
                type: TypeConfig[type],
                valid: 1
            }
        };
        let orderInfo = await ctx.prometheusModel.CreditOrder.findOne(orderFilter);
        if (orderInfo != null) {
            if (orderInfo.state === '已支付' && moment(orderInfo.state_time).add(timeLine, 'days').format('YYYY-MM-DD HH:mm:ss') > moment().format('YYYY-MM-DD HH:mm:ss')) {
                valid = 1;
            }
        }
        return valid;
    }

    async getOrderInfo(order_id) {

        const { ctx } = this;
        const order = await ctx.prometheusModel.CreditOrder.findOne({ where: { id: order_id } });
        if (!order || !order.id) {
            ctx.failed('error order');
        }
        return order;
    }

    //获取支付详细信息
    async getOrderPayInfo(order_id) {

        const { ctx } = this;
        const user_id = ctx.userId;
        const order = await ctx.prometheusModel.CreditOrder.findOne({ where: { id: order_id, user_id } });
        if (!order || !order.id) {
            ctx.failed('error order');
        }
        const preferential = await ctx.service.credit.preferential.getPreferential(TypeConfigFlip[order.type]);
        let preferential_price = 0;
        let preferential_title = '';
        if (preferential && preferential.id) {
            preferential_price = preferential.price;
            preferential_title = preferential.title;
        }

        const price = await this.updateOrderPrice(order);
        const type = order.type;
        const countdown = moment(order.order_time).format('X') - moment(new Date()).format('X') + 86400;
        const ret = {
            price,
            original_price: order.price,
            original_price_title: '原价',
            preferential_price,
            preferential_title,
            order_no: order.order_no,
            type: TypeConfigFlip[type],
            type_title: type === 1 ? '黑名单检测' : '个人通话风险检测',
            notice: type === 1 ? '温馨提示：15天内无需重复付费查询' : '温馨提示：30天内无需重复付费查询',
            countdown,
        }

        return ret;
    }

    //检查是否支付成功
    async checkOrderPay(order_id) {

        const { ctx } = this;
        const user_id = ctx.userId;
        const order = await ctx.prometheusModel.CreditOrder.findOne({ where: { id: order_id, user_id } });
        if (!order || !order.id) {
            ctx.failed('error order');
        }
        if (order && order.pay_status === 1) {
            return true;
        }
        const credit_pay = await ctx.prometheusModel.CreditPay.findOne({ where: { order_id }, order: [['id', 'desc']] });
        if (!credit_pay || !credit_pay.id) {
            ctx.failed('error credit pay');
        }
        if (order.pay_method === 'wxpay') {
            const { transaction_id, trade_no } = credit_pay;
            const wexin_check_pay_ret = await ctx.service.credit.common.WexinCheckPay({ transaction_id, trade_no });
            const price = ((order.price - order.preferential_price) * 100).toFixed();

            if (price === wexin_check_pay_ret.total_fee) {
                await ctx.prometheusModel.CreditPay.edit({ where: { id: credit_pay.id }, params: { pay_result: JSON.stringify(wexin_check_pay_ret), status: 1 } });
                const state_time = moment().format('YYYY-MM-DD HH:mm:ss');
                await this.logOrder(order.id);
                await ctx.prometheusModel.CreditOrder.update({ state: '已支付', state_time, pay_status: 1 }, { where: { id: order.id, pay_status: 0 } })
                await this.updateOrderStateToCancel(order);//更新其他同姓名和身份证号的订单状态
                return true;
            }
        }

        return false;
    }

    /**
     * 获得当前三要素是否有待支付的订单
     * @param {*} type 类型blacklist/callrisk
     * @param {*} threeParams 三要素
     */
    async getBePayOrderByThree(type, threeParams) {
        const { ctx } = this;
        if (!TypeConfig.hasOwnProperty(type)) {
            ctx.failed('undefined type in getBePayOrderByThree');
        }
        let orderFilter = {
            where: {
                user_id: ctx.userId,
                type: TypeConfig[type],
                name: threeParams.name,
                phone: threeParams.phone,
                id_card: threeParams.id_card,
                state: { $in: ['待支付', '支付中'] },
                pay_status: 0,
                valid: 1,
                state_time: { $gte: moment().subtract(1, 'days').format('YYYY-MM-DD HH:mm:ss') }
            }
        }
        let order = await ctx.prometheusModel.CreditOrder.findOne(orderFilter);
        return order;
    }

    //统一下单
    async unifiedOrder(type, order_id) {

        const { ctx } = this;

        const order = await ctx.service.credit.order.getOrderInfo(order_id);
        if (order && order.pay_status === 1) {
            ctx.failed('订单已支付无需重复支付');
        }
        const expire_time = moment(order.order_time).valueOf() + 24 * 3600 * 1000 + 10 * 1000;
        const now_time = moment().valueOf();
        if (expire_time <= now_time) {
            ctx.failed('order_failure');//订单失效，前端会取这个判断跳转
        }

        const price = ((order.price - order.preferential_price) * 100).toFixed();

        if (price <= 0) {
            ctx.failed('error price');
        }
        if (type === 'wxpay') {

            let body = '黑名单报告检测支付';
            if (order.type === 2) {
                body = '个人通话风险检测支付';
            }
            const data = {
                body,
                order_id,
                trade_no: moment().valueOf() + ctx.helper.PrefixInteger(order_id, 11),
                total_fee: price,
                notify_url: `${this.config.OUT_P_NODE_URL}/51business/api/credit/order/wx_pay_notice`,
                product_id: order.order_no,
                scene_info: JSON.stringify({ h5_info: { type: 'Wap', wap_url: this.config.OUT_P_NODE_URL, wap_name: '我的信用' }, }),
            };

            const ret = await ctx.service.credit.common.WexinUnifiedOrder(data);//微信统一下单

            const pay_data = {
                order_id,
                trade_no: data.trade_no,
                description: data.body,
                prepay_id: ret.prepay_id || 0,
                amount: data.total_fee / 100,
                unifiedorder_result: JSON.stringify(ret),
                client_ip: ctx.helper.getClientIP(),
            };
            await this.addCreditPay(pay_data);//添加下单记录
            // await this.updateOrderStateToCancel(order);//更新其他同姓名和身份证号的订单状态//2019-10-14 14:52:23 移动到支付完成时通知那里
            await this.updateOrderPrice(order);//更新金额
            await this.logOrder(order.id);//订单状态变化日志记录
            const state_time = moment().format('YYYY-MM-DD HH:mm:ss');
            await ctx.prometheusModel.CreditOrder.update({ pay_method: type, state: '支付中', state_time }, { where: { id: order.id } });//更新状态
            return { url: ret.mweb_url, order_id: order_id, trade_no: data.trade_no };

        } else if (type === 'alipay') {
            //TODO
        }
        return false;
    }


    async addCreditPay(params) {

        const { ctx } = this;
        const { order_id, trade_no, prepay_id, amount, description, unifiedorder_result, client_ip } = params;
        const data = {
            order_id,
            trade_no,
            prepay_id,
            amount,
            description,
            unifiedorder_result,
            client_ip,
        }
        const ret = await ctx.prometheusModel.CreditPay.add(data);

        return ret;
    }


    /**
     * 获取用户的待支付订单,时间倒序
     * @param {*} type 黑名单blacklist通话callrisk
     */
    async getBePayOrder(type) {
        const { ctx } = this;
        let ret = [];
        if (!TypeConfig.hasOwnProperty(type)) {
            return ret;
        }
        let filter = {
            where: {
                user_id: ctx.userId,
                // user_id: '8c3172a5-23b2-43d6-aa6c-5193f445bbe3',
                type: TypeConfig[type],
                state: { $in: ['待支付', '支付中'] },
                valid: 1,
                state_time: { $gte: moment().subtract(1, 'days').format('YYYY-MM-DD HH:mm:ss') }
            },
            order: [['state_time', 'desc']]
        }
        let list = await ctx.prometheusModel.CreditOrder.findAll(filter);
        if (list === undefined) {
            return ret;
        }
        ret = list;
        return ret;
    }


    /**
     * 初始化生成订单
     * @param {*} params 
     */
    async createOrder(params) {
        const { ctx } = this;
        let data = {
            type: params.type,
            phone: params.phone,
            name: params.name,
            id_card: params.id_card,
            user_id: ctx.userId,
            app_user_id: ctx.userId,
            app_id: ctx.appId,
            app_type_id: ctx.appTypeId,
            price: params.type === 1 ? 29.90 : 19.90,
            valid: 0,
        }
        let order = await ctx.prometheusModel.CreditOrder.create(data);
        return order;
    }

    //记录订单状态
    async logOrder(order_id) {

        const { ctx } = this;
        const order = await ctx.prometheusModel.CreditOrder.findOne({ where: { id: order_id } });
        if (!order || !order.id) {
            ctx.failed('error order');
        }
        const { id, type, phone, name, id_card, price, preferential_id, preferential_price, final_price, state, pay_status, pay_method, state_time, } = order;
        const data = {
            order_id,
            type,
            phone,
            name,
            id_card,
            price,
            preferential_id,
            preferential_price,
            final_price,
            state,
            pay_status,
            pay_method,
            state_time,
        }
        await ctx.prometheusModel.CreditLogOrder.add(data);

        return true;
    }


}

module.exports = OrderService;
