package com.hfkj.service.impl;

import com.hfkj.channel.ccb.CCBTradeService;
import com.hfkj.channel.hsg.HsgIntegralService;
import com.hfkj.channel.tianque.service.TianQueTradeService;
import com.hfkj.channel.weixin.WeiXinPayService;
import com.hfkj.common.exception.BizException;
import com.hfkj.common.exception.ErrorCode;
import com.hfkj.common.exception.ErrorHelp;
import com.hfkj.common.exception.SysCode;
import com.hfkj.dao.BsTradeOrderRefundMapper;
import com.hfkj.entity.*;
import com.hfkj.channel.lakala.LaKaLaTradeService;
import com.hfkj.service.*;
import com.hfkj.sysenum.PlatformTypeEnum;
import com.hfkj.sysenum.StoreDiscountActivityPartakeWayEnum;
import com.hfkj.sysenum.TradeOrderRefundStatusEnum;
import com.hfkj.sysenum.TradeOrderStatusEnum;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

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

@Service("tradeOrderRefundService")
public class BsTradeOrderRefundServiceImpl implements BsTradeOrderRefundService {

    @Resource
    private BsTradeOrderRefundMapper tradeOrderRefundMapper;

    @Resource
    private BsTradeOrderService tradeOrderService;

    @Resource
    private BsStoreDiscountActivityService storeDiscountActivityService;
    @Resource
    private BsStoreDiscountActivityPartakeUserService discountActivityPartakeUserService;

    @Resource
    private LaKaLaTradeService laKaLaTradeService;

    @Resource
    private CCBTradeService ccbTradeService;

    @Resource
    private UserDiscountService userDiscountService;

    @Resource
    private WeiXinPayService weiXinPayService;

    @Resource
    private TianQueTradeService tianQueTradeService;

    @Override
    public void editOrderRefund(BsTradeOrderRefund tradeOrderRefund) {
        if (tradeOrderRefund.getId() == null) {
            tradeOrderRefund.setCreateTime(new Date());
            tradeOrderRefund.setUpdateTime(new Date());
            tradeOrderRefundMapper.insert(tradeOrderRefund);
        } else {
            tradeOrderRefund.setUpdateTime(new Date());
            tradeOrderRefundMapper.updateByPrimaryKey(tradeOrderRefund);
        }
    }

    @Override
    public Map<String, Object> tradeOrderRefund(BsTradeOrderRefund tradeOrderRefund) throws Exception {
        boolean refundStatus = false;

        // 交易订单
        BsTradeOrder tradeOrder = tradeOrderService.getOrderByTradeNoId(tradeOrderRefund.getTradeOrderId());
        try {
            if (tradeOrder == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的交易订单");
            }
            if (StringUtils.isNotBlank(tradeOrder.getUserPhone())) {
                if (HsgIntegralService.recycleIntegral(tradeOrder.getId().toString(),tradeOrder.getOutTradeNo()).equals(false)) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "用户积分不足，暂时无法退款");
                }
            }

            editOrderRefund(tradeOrderRefund);

            Map<String, Object> refund = new HashMap<>();
            if (tradeOrderRefund.getPlatformType().equals(PlatformTypeEnum.type1.getNumber())) {
                refund = laKaLaTradeService.refund(tradeOrderRefund.getRefundNo(), tradeOrderRefund.getRefundAmount());
                refundStatus = true;

            } else if (tradeOrderRefund.getPlatformType().equals(PlatformTypeEnum.type3.getNumber())) {
                refund = ccbTradeService.refund(tradeOrderRefund.getRefundNo(), tradeOrderRefund.getRefundAmount());
                refundStatus = true;

            } else if (tradeOrderRefund.getPlatformType().equals(PlatformTypeEnum.type4.getNumber())) {
                refund = weiXinPayService.refund(tradeOrderRefund.getRefundNo(), tradeOrderRefund.getRefundAmount());
                refundStatus = true;

            } else if (tradeOrderRefund.getPlatformType().equals(PlatformTypeEnum.type5.getNumber())) {
                refund = tianQueTradeService.refund(tradeOrderRefund.getRefundNo(), tradeOrderRefund.getRefundAmount());
                refundStatus = true;
            }

            if (tradeOrder != null) {
                // 退回门店优惠活动
                if (tradeOrder.getStoreDiscountId() != null) {
                    BsStoreDiscountActivity storeDiscountActivity = storeDiscountActivityService.getDetailById(tradeOrder.getStoreDiscountId());
                    if (storeDiscountActivity != null
                            && !storeDiscountActivity.getPartakeWay().equals(StoreDiscountActivityPartakeWayEnum.type1.getNumber())
                            && StringUtils.isNotBlank(tradeOrder.getUserPhone())) {

                        BsStoreDiscountActivityPartakeUser partakeUser = discountActivityPartakeUserService.getPartakeUser(tradeOrder.getUserPhone(), tradeOrder.getStoreDiscountId());
                        if (partakeUser != null) {
                            partakeUser.setPartakeSurplusNum(partakeUser.getPartakeSurplusNum() + 1);
                            partakeUser.setPartakeUseNum(partakeUser.getPartakeUseNum() - 1);
                            discountActivityPartakeUserService.editData(partakeUser);
                        }
                    }
                }

                if (tradeOrder.getUserDiscountId() != null) {
                    userDiscountService.userDiscountReturn(tradeOrder.getUserDiscountId(), tradeOrder.getUserPhone());
                }
            }
            return refund;

        } catch (BizException e) {
            tradeOrderRefund.setStatus(TradeOrderRefundStatusEnum.status0.getNumber());
            editOrderRefund(tradeOrderRefund);
            throw e;

        } catch (Exception e) {
            tradeOrderRefund.setStatus(TradeOrderRefundStatusEnum.status0.getNumber());
            editOrderRefund(tradeOrderRefund);
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, e.getMessage());
        } finally {
            HsgIntegralService.refundReturn(tradeOrder.getId().toString(),tradeOrder.getOutTradeNo(), refundStatus);
        }
    }

    @Override
    public BsTradeOrderRefund getRefundByOutTradeOrder(String outTradeOrder) {
        BsTradeOrderRefundExample example = new BsTradeOrderRefundExample();
        example.createCriteria().andOutTradeNoEqualTo(outTradeOrder);
        List<BsTradeOrderRefund> list = tradeOrderRefundMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public BsTradeOrderRefund getRefundByRefundNo(String refundNo) {
        BsTradeOrderRefundExample example = new BsTradeOrderRefundExample();
        example.createCriteria().andRefundNoEqualTo(refundNo);
        List<BsTradeOrderRefund> list = tradeOrderRefundMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<BsTradeOrderRefund> getRefundList(Map<String, Object> param) {
        BsTradeOrderRefundExample example = new BsTradeOrderRefundExample();
        BsTradeOrderRefundExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getInteger(param, "status") != null) {
            criteria.andStatusEqualTo(MapUtils.getInteger(param, "status"));
        }

        if (MapUtils.getLong(param, "refundTimeS") != null) {
            criteria.andRefundTimeGreaterThanOrEqualTo(new Date(MapUtils.getLong(param, "refundTimeS")));
        }

        if (MapUtils.getLong(param, "refundTimeE") != null) {
            criteria.andRefundTimeLessThanOrEqualTo(new Date(MapUtils.getLong(param, "refundTimeE")));
        }

        if (MapUtils.getBoolean(param, "settleAmountIsNull") != null) {
            criteria.andSettleAmountIsNull();
        }

        if (MapUtils.getBoolean(param, "shdFeeAmtIsNull") != null) {
            criteria.andShdFeeAmtIsNull();
        }

        example.setOrderByClause("create_time desc");
        return tradeOrderRefundMapper.selectByExample(example);
    }

}
