package cn.com.poc.thirdparty.resource.demand.pay.service.impl;

import cn.com.poc.common.constant.BizSnKeyEnum;
import cn.com.poc.common.constant.CommonConstant;
import cn.com.poc.common.constant.MkpRedisKeyConstant;
import cn.com.poc.common.service.RedisService;
import cn.com.poc.common.utils.*;
import cn.com.poc.support.security.oauth.entity.UserBaseEntity;
import cn.com.poc.thirdparty.resource.demand.dgTools.constants.CurrencyEnum;
import cn.com.poc.thirdparty.resource.demand.dgTools.result.PayResult;
import cn.com.poc.thirdparty.resource.demand.pay.service.DgtoolsPayOrderService;
import cn.com.poc.thirdparty.resource.demand.pay.service.PayService;
import cn.com.poc.thirdparty.resource.demand.pay.constants.DgtoolsPayOrderConstants;
import cn.com.poc.thirdparty.resource.demand.pay.dto.WxMiniPayDto;
import cn.com.poc.thirdparty.resource.demand.pay.entity.DgtoolsPayOrderEntity;
import cn.com.poc.thirdparty.resource.demand.pay.model.DgtoolsPayOrderModel;
import cn.com.poc.thirdparty.resource.demand.pay.repository.DgtoolsPayOrderRepository;
import cn.com.yict.framemax.core.exception.BusinessException;
import cn.com.yict.framemax.core.service.impl.BaseServiceImpl;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @author Roger Wu
 */
@Service
public class DgtoolsPayOrderServiceImpl extends BaseServiceImpl
        implements DgtoolsPayOrderService {

    @Resource
    private DgtoolsPayOrderRepository repository;

    @Resource
    private RedisService redisService;


    @Resource
    private PayService payService;


    /**
     * 创建付款订单
     *
     * @param preDgtoolsPayOrderEntity
     * @return
     */
    @Override
    public DgtoolsPayOrderEntity createPayOrder(DgtoolsPayOrderEntity preDgtoolsPayOrderEntity) throws Exception {

        Assert.notNull(preDgtoolsPayOrderEntity.getAmount(), "支付金额不能为空");
        Assert.notBlank(preDgtoolsPayOrderEntity.getPayOrderType(), "支付类型不能为空");

        UserBaseEntity currentUser = BlContext.getCurrentUser();

        DgtoolsPayOrderModel dgtoolsPayOrderModel = new DgtoolsPayOrderModel();

        Integer memberId = currentUser.getUserId().intValue();

        dgtoolsPayOrderModel.setPayOrderType(preDgtoolsPayOrderEntity.getPayOrderType());
        dgtoolsPayOrderModel.setPayOrderSn(GeneratingSnUtils.generationSn(BizSnKeyEnum.paySn));
        dgtoolsPayOrderModel.setTotalAmount(preDgtoolsPayOrderEntity.getAmount());
        dgtoolsPayOrderModel.setPaidAmount(0);
        dgtoolsPayOrderModel.setMemberId(memberId);
        dgtoolsPayOrderModel.setNeedPayAmount(preDgtoolsPayOrderEntity.getAmount());
        dgtoolsPayOrderModel.setCurrency(StringUtils.isNoneBlank(preDgtoolsPayOrderEntity.getCurrency()) ? preDgtoolsPayOrderEntity.getCurrency() : CurrencyEnum.CHINA.getCurrencyCode());
        dgtoolsPayOrderModel.setOrderStatus(DgtoolsPayOrderConstants.OrderStatus.CREATE);
        dgtoolsPayOrderModel.setPayStatus(DgtoolsPayOrderConstants.PayStatus.NO_PAYMENT);
        dgtoolsPayOrderModel.setRetainInformation(preDgtoolsPayOrderEntity.getRetainInformation());
        dgtoolsPayOrderModel.setDescription(preDgtoolsPayOrderEntity.getDescription());
        dgtoolsPayOrderModel.setMarketingGameFlowNo(preDgtoolsPayOrderEntity.getMarketingGameFlowNo());
        dgtoolsPayOrderModel.setCancelTime(DateUtils.addMinute(new Date(), 15));


        DgtoolsPayOrderModel saved = repository.save(dgtoolsPayOrderModel);

        //todo 设置付款订单过期
//        redisService.set(MkpRedisKeyConstant.PRE_PAY_ORDER_EXPIRED + ":" + saved.getPayOrderSn(), "", 15 * 60);

        DgtoolsPayOrderEntity savedEntity = new DgtoolsPayOrderEntity();
        BeanUtils.copyProperties(saved, savedEntity);
        return savedEntity;
    }


    @Override
    public DgtoolsPayOrderEntity createPayOrder(DgtoolsPayOrderEntity preDgtoolsPayOrderEntity, Long memberId) throws Exception {
        Assert.notNull(preDgtoolsPayOrderEntity.getAmount(), "支付金额不能为空");
        Assert.notBlank(preDgtoolsPayOrderEntity.getPayOrderType(), "支付类型不能为空");

        DgtoolsPayOrderModel dgtoolsPayOrderModel = new DgtoolsPayOrderModel();
        dgtoolsPayOrderModel.setPayOrderType(preDgtoolsPayOrderEntity.getPayOrderType());
        dgtoolsPayOrderModel.setPayOrderSn(GeneratingSnUtils.generationSn(BizSnKeyEnum.paySn));
        dgtoolsPayOrderModel.setTotalAmount(preDgtoolsPayOrderEntity.getAmount());
        dgtoolsPayOrderModel.setPaidAmount(0);
        dgtoolsPayOrderModel.setMemberId(memberId.intValue());
        dgtoolsPayOrderModel.setNeedPayAmount(preDgtoolsPayOrderEntity.getAmount());
        dgtoolsPayOrderModel.setCurrency(StringUtils.isNoneBlank(preDgtoolsPayOrderEntity.getCurrency()) ? preDgtoolsPayOrderEntity.getCurrency() : CurrencyEnum.CHINA.getCurrencyCode());
        dgtoolsPayOrderModel.setOrderStatus(DgtoolsPayOrderConstants.OrderStatus.CREATE);
        dgtoolsPayOrderModel.setPayStatus(DgtoolsPayOrderConstants.PayStatus.NO_PAYMENT);
        dgtoolsPayOrderModel.setRetainInformation(preDgtoolsPayOrderEntity.getRetainInformation());
        dgtoolsPayOrderModel.setDescription(preDgtoolsPayOrderEntity.getDescription());
        dgtoolsPayOrderModel.setMarketingGameFlowNo(preDgtoolsPayOrderEntity.getMarketingGameFlowNo());
        dgtoolsPayOrderModel.setCancelTime(DateUtils.addMinute(new Date(), 15));

        DgtoolsPayOrderModel saved = repository.save(dgtoolsPayOrderModel);

        DgtoolsPayOrderEntity savedEntity = new DgtoolsPayOrderEntity();
        BeanUtils.copyProperties(saved, savedEntity);
        return savedEntity;
    }

    /**
     * 更新付款订单明细
     *
     * @param payOrderSn
     * @param description
     * @param retainInformation
     * @return
     * @throws Exception
     */
    @Override
    public DgtoolsPayOrderEntity updatePayOrderDetailInfo(String payOrderSn, String description, String retainInformation) throws Exception {
        DgtoolsPayOrderModel example = new DgtoolsPayOrderModel();
        example.setPayOrderSn(payOrderSn);
        example.setIsDeleted(CommonConstant.IsDeleted.N);
        List<DgtoolsPayOrderModel> dgtoolsPayOrderModelList = repository.findByExample(example);
        if (CollectionUtils.isEmpty(dgtoolsPayOrderModelList)) {
            throw new BusinessException("找不到该订单");
        }
        DgtoolsPayOrderModel dgtoolsPayOrderModel = dgtoolsPayOrderModelList.get(0);
        dgtoolsPayOrderModel.setDescription(description);
        dgtoolsPayOrderModel.setRetainInformation(retainInformation);
        DgtoolsPayOrderModel saved = repository.save(dgtoolsPayOrderModel);

        DgtoolsPayOrderEntity savedEntity = new DgtoolsPayOrderEntity();
        BeanUtils.copyProperties(saved, savedEntity);
        return savedEntity;
    }


    /**
     * 通过预付款号查询付款订单
     *
     * @param payOrderSn
     */
    @Override
    public DgtoolsPayOrderEntity findPayOrderByPaySn(String payOrderSn) {
        Assert.notBlank(payOrderSn, "查询付款订单,付款订单号不能为空");
        DgtoolsPayOrderModel dgtoolsPayOrderModel = new DgtoolsPayOrderModel();
        dgtoolsPayOrderModel.setPayOrderSn(payOrderSn);
        dgtoolsPayOrderModel.setIsDeleted(CommonConstant.IsDeleted.N);
        List<DgtoolsPayOrderModel> dgtoolsPayOrderModelList = repository.findByExample(dgtoolsPayOrderModel);
        if (CollectionUtils.isEmpty(dgtoolsPayOrderModelList)) {
            return null;
        }
        DgtoolsPayOrderEntity savedEntity = new DgtoolsPayOrderEntity();
        BeanUtils.copyProperties(dgtoolsPayOrderModelList.get(0), savedEntity);
        return savedEntity;
    }

    /**
     * 取消付款订单
     *
     * @param payOrderSn
     */
    @Override
    public void changePayOrder2CancelStatus(String payOrderSn) {
        Assert.notBlank(payOrderSn, "取消付款订单,付款订单号不能为空");
        DgtoolsPayOrderModel dgtoolsPayOrderModel = new DgtoolsPayOrderModel();
        dgtoolsPayOrderModel.setPayOrderSn(payOrderSn);
        dgtoolsPayOrderModel.setIsDeleted(CommonConstant.IsDeleted.N);
        List<DgtoolsPayOrderModel> dgtoolsPayOrderModelList = repository.findByExample(dgtoolsPayOrderModel);
        if (CollectionUtils.isNotEmpty(dgtoolsPayOrderModelList)) {
            DgtoolsPayOrderModel model = dgtoolsPayOrderModelList.get(0);
            if (!DgtoolsPayOrderConstants.PayStatus.NO_PAYMENT.equals(model.getPayStatus())) {
                return;
            }
            model.setOrderStatus(DgtoolsPayOrderConstants.OrderStatus.CANCEL);
            model.setPayStatus(DgtoolsPayOrderConstants.PayStatus.CANCEL);
            repository.save(model);
        }
    }

    /**
     * 改变付款订单到已支付
     *
     * @param payOrderSn
     * @param amount
     */
    @Override
    public void changePayOrder2PaidStatus(String payOrderSn, Integer amount) {
        Assert.notBlank(payOrderSn, "更改付款订单状态,付款订单号不能为空");
        Assert.notNull(amount, "更改付款订单状态,付款金额不能为空");
        DgtoolsPayOrderModel dgtoolsPayOrderModel = new DgtoolsPayOrderModel();
        dgtoolsPayOrderModel.setPayOrderSn(payOrderSn);
        dgtoolsPayOrderModel.setIsDeleted(CommonConstant.IsDeleted.N);
        List<DgtoolsPayOrderModel> dgtoolsPayOrderModelList = repository.findByExample(dgtoolsPayOrderModel);
        if (CollectionUtils.isNotEmpty(dgtoolsPayOrderModelList)) {
            DgtoolsPayOrderModel model = dgtoolsPayOrderModelList.get(0);
            if (!DgtoolsPayOrderConstants.PayStatus.NO_PAYMENT.equals(model.getPayStatus())) {
                return;
            }
            model.setOrderStatus(DgtoolsPayOrderConstants.OrderStatus.COMPLETED);
            model.setPayTime(new Date());
            model.setPaidAmount(amount);
            model.setPayStatus(DgtoolsPayOrderConstants.PayStatus.PAID);
            repository.save(model);
        }
    }

    @Override
    public void changePayOrder2PaidStatus(String payOrderSn, Integer amount, String payChannel) {
        Assert.notBlank(payOrderSn, "更改付款订单状态,付款订单号不能为空");
        Assert.notNull(amount, "更改付款订单状态,付款金额不能为空");
        DgtoolsPayOrderModel dgtoolsPayOrderModel = new DgtoolsPayOrderModel();
        dgtoolsPayOrderModel.setPayOrderSn(payOrderSn);
        dgtoolsPayOrderModel.setIsDeleted(CommonConstant.IsDeleted.N);
        List<DgtoolsPayOrderModel> dgtoolsPayOrderModelList = repository.findByExample(dgtoolsPayOrderModel);
        if (CollectionUtils.isNotEmpty(dgtoolsPayOrderModelList)) {
            DgtoolsPayOrderModel model = dgtoolsPayOrderModelList.get(0);
            if (!DgtoolsPayOrderConstants.PayStatus.NO_PAYMENT.equals(model.getPayStatus())) {
                return;
            }
            model.setOrderStatus(DgtoolsPayOrderConstants.OrderStatus.COMPLETED);
            model.setPayTime(new Date());
            model.setPaidAmount(amount);
            model.setPayStatus(DgtoolsPayOrderConstants.PayStatus.PAID);
            model.setPayChannel(payChannel);
            repository.save(model);
        }
    }

    /**
     * 创建付款单并且支付
     *
     * @param dgtoolsPayOrderEntity
     * @return
     */
    public PayResult createPayOrderAndPay(DgtoolsPayOrderEntity dgtoolsPayOrderEntity) throws Exception {
        DgtoolsPayOrderEntity payOrder = createPayOrder(dgtoolsPayOrderEntity);
        WxMiniPayDto wxMiniPayDto = new WxMiniPayDto();
        wxMiniPayDto.setPayOrderSn(payOrder.getPayOrderSn());
        wxMiniPayDto.setCurrency(payOrder.getCurrency());
        wxMiniPayDto.setAmount(payOrder.getNeedPayAmount());
        return payService.wxMiniPay(wxMiniPayDto);
    }


}