package com.liquidnet.service.dragon.biz;

import com.liquidnet.commons.lang.util.IDGenerator;
import com.liquidnet.service.base.SqlMapping;
import com.liquidnet.service.dragon.bo.PayNotifyReqBo;
import com.liquidnet.service.dragon.constant.DragonConstant;
import com.liquidnet.service.dragon.dto.DragonOrdersDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseReqDto;
import com.liquidnet.service.dragon.dto.DragonPayBaseRespDto;
import com.liquidnet.service.dragon.dto.PayNotifyDto;
import com.liquidnet.service.dragon.utils.DataUtilsDragon;
import com.liquidnet.service.dragon.utils.MqHandleUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @author AnJiabin <anjiabin@zhengzai.tv>
 * @version V1.0
 * @Description: TODO
 * @class: DragonServiceCommonBiz
 * @Package com.liquidnet.service.dragon.biz
 * @Copyright: LightNet @ Copyright (c) 2021
 * @date 2021/7/19 18:06
 */
@Slf4j
@Component
public class DragonServiceCommonBiz {
    @Autowired
    private MqHandleUtil mqHandleUtil;

    @Autowired
    private DataUtilsDragon dataUtilsDragon;

    public DragonOrdersDto buildPayOrders(DragonPayBaseReqDto dragonPayBaseReqDto, DragonPayBaseRespDto respDto){
        //构造订单
        DragonOrdersDto orders = DragonOrdersDto.getNew();
//        orders.setMid();
        orders.setOrderId(IDGenerator.nextTimeId());
        orders.setStatus(Integer.valueOf(DragonConstant.PayStatusEnum.STATUS_UNPAID.getCode()));
        orders.setCode(dragonPayBaseReqDto.getCode());
        orders.setType(dragonPayBaseReqDto.getType());
        orders.setPrice(dragonPayBaseReqDto.getPrice());
        orders.setName(dragonPayBaseReqDto.getName());
        orders.setDetail(dragonPayBaseReqDto.getDetail());
        orders.setOrderCode(dragonPayBaseReqDto.getOrderCode());
        orders.setOrderCodeId(dragonPayBaseReqDto.getOrderId());
        orders.setClientIp(dragonPayBaseReqDto.getClientIp());
        orders.setNotifyUrl(dragonPayBaseReqDto.getNotifyUrl());
        orders.setNotifyStatus(Integer.valueOf(DragonConstant.PayNotifyStatusEnum.NOTIFY_INIT.getCode()));
        if (dragonPayBaseReqDto.getAppIdType() != null && !dragonPayBaseReqDto.getAppIdType().trim().isEmpty()) {
            orders.setPaymentType((dragonPayBaseReqDto.getDeviceFrom() + dragonPayBaseReqDto.getAppIdType() + dragonPayBaseReqDto.getPayType()).toUpperCase());
        } else {
            orders.setPaymentType((dragonPayBaseReqDto.getDeviceFrom() + dragonPayBaseReqDto.getPayType()).toUpperCase());
        }
//        orders.setPaymentId();
        orders.setPaymentAt(LocalDateTime.now());
//        orders.setFinishedAt();
        orders.setCreatedAt(LocalDateTime.now());
//        orders.setUpdatedAt();
        orders.setReceiptData(dragonPayBaseReqDto.getReceiptData());


        long startTime = System.currentTimeMillis();
        //放到redis缓存中
        dataUtilsDragon.createPayOrder(orders.getCode(),orders);
        log.info("redis-createPayOrder->耗时:{}",(System.currentTimeMillis() - startTime)+"毫秒");
        // 持久化到数据库
        startTime = System.currentTimeMillis();
        boolean insertResult = mqHandleUtil.sendMySqlRedis(
                SqlMapping.get("dragon_orders.insert"),
                new Object[]{orders.getOrderId(),orders.getStatus(), orders.getCode(), orders.getType()
                        , orders.getPrice(), orders.getName(), orders.getDetail()
                        , orders.getOrderCode(),orders.getOrderCodeId(), orders.getClientIp()
                        , orders.getNotifyUrl(), orders.getNotifyStatus(),orders.getPaymentType(),
                        orders.getPaymentId(), orders.getPaymentAt()
                        , orders.getFinishedAt(), orders.getCreatedAt()
                        , orders.getUpdatedAt(),orders.getDeletedAt(),orders.getReceiptData()}
                ,DragonConstant.MysqlRedisQueueEnum.DRAGON_PAY_KEY.getCode()
        );
        log.info("redis-queue-sendMySqlRedis->耗时:{}",(System.currentTimeMillis() - startTime)+"毫秒");
        return orders;
    }

    /**
     * 更新支付状态
     * @param code
     * @param paymentId
     * @return
     */
    public boolean updateOrderStatus(String code,Integer status,String paymentId){
        try {
            LocalDateTime finishedAt = LocalDateTime.now();
            LocalDateTime updateAt = LocalDateTime.now();
            //t.status = ?  ,t.payment_id = ?,t.finished_at = ?,t.updated_at =? where t.code = ?
            boolean insertResult = mqHandleUtil.sendMySqlRedis(
                    SqlMapping.get("dragon_orders.updateOrderStatus"),
                    new Object[]{status,paymentId,finishedAt, updateAt,code}
                    ,DragonConstant.MysqlRedisQueueEnum.DRAGON_PAY_KEY.getCode()
            );
            if(insertResult) return true;
        } catch (Exception e) {
            log.error("dragon:updateDragonOrderStatus:error msg:{}",e);
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 更新支付通知状态
     * @param code
     * @return
     */
    public boolean updateNotifyStatus(String code,Integer status){
        try {
            LocalDateTime updateAt = LocalDateTime.now();
            //update dragon_orders t set t.notify_status = ? ,t.updated_at =? where t.code = ?
            boolean insertResult = mqHandleUtil.sendMySqlRedis(
                    SqlMapping.get("dragon_orders.updateNotifyStatus"),
                    new Object[]{status,updateAt,code}
                    ,DragonConstant.MysqlRedisQueueEnum.DRAGON_PAY_KEY.getCode()
            );
            if(insertResult) return true;
        } catch (Exception e) {
            log.error("dragon:updateNotifyStatus:error msg:{}",e);
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 三方异步通知入库
     * @param paymentType
     * @param content
     */
    public void createDragonOrderLogs(String code,String paymentType,String content){
        try {
            String orderId = IDGenerator.nextTimeId();
            LocalDateTime createAt = LocalDateTime.now();
            LocalDateTime updateAt = null;
            LocalDateTime deleteAt = null;
            boolean insertResult = mqHandleUtil.sendMySqlRedis(
                    SqlMapping.get("dragon_order_logs.insert"),
                    new Object[]{code,paymentType,content, createAt, updateAt,deleteAt}
                    ,DragonConstant.MysqlRedisQueueEnum.DRAGON_PAY_NOTIFY_KEY.getCode()
            );
        } catch (Exception e) {
            log.error("dragon:createOrderLog:error msg:{}",e);
            e.printStackTrace();
        }
    }

    /**
     * 商户异步通知入库
     * @param payNotifyReqBo
     * @param notifyParam
     */
    public void createDragonPayNotify(PayNotifyReqBo payNotifyReqBo,String notifyParam){
        PayNotifyDto payNotifyDto = payNotifyReqBo.getPayNotifyDto();
        try {
            String code = payNotifyDto.getCode();
            String orderCode = payNotifyDto.getOrderCode();
            String notifyUrl = payNotifyReqBo.getNotifyUrl();
            String notifyData = notifyParam;
            LocalDateTime createAt = LocalDateTime.now();
            LocalDateTime updateAt = LocalDateTime.now();
            boolean insertResult = mqHandleUtil.sendMySqlRedis(
                    SqlMapping.get("dragon_pay_notify.insert"),
                    new Object[]{code,orderCode,notifyUrl,notifyData, createAt, updateAt}
                    ,DragonConstant.MysqlRedisQueueEnum.PAY_MCH_NOTIFY_KEY.getCode()
            );
            log.info("dragon:createDragonPayNotify:success code:{}",code);
        } catch (Exception e) {
            log.error("dragon:createDragonPayNotify:error msg:{}",e);
            e.printStackTrace();
        }
    }

    /**
     * 商户异步通知失败入库
     * @param payNotifyReqBo
     * @param notifyParam
     */
    public void createDragonPayNotifyFail(PayNotifyReqBo payNotifyReqBo, String notifyParam){
        PayNotifyDto payNotifyDto = payNotifyReqBo.getPayNotifyDto();
        try {
            String code = payNotifyDto.getCode();
            String orderCode = payNotifyDto.getOrderCode();
            String notifyUrl = payNotifyReqBo.getNotifyUrl();
            String notifyData = notifyParam;
            String failDesc = "通知失败";
            LocalDateTime createAt = LocalDateTime.now();
            LocalDateTime updateAt = LocalDateTime.now();
            boolean insertResult = mqHandleUtil.sendMySqlRedis(
                    SqlMapping.get("dragon_pay_notify_fail.insert"),
                    new Object[]{code,orderCode,notifyUrl,notifyData,failDesc,createAt, updateAt}
                    , DragonConstant.MysqlRedisQueueEnum.PAY_MCH_NOTIFY_ERROR_KEY.getCode()
            );
            log.info("dragon:createDragonPayNotifyFail:success code:{}",code);
        } catch (Exception e) {
            log.error("dragon:createDragonPayNotifyFail:error msg:{}",e);
            e.printStackTrace();
        }
    }
}
