package com.hai.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.hai.common.GenerateCode;
import com.hai.common.exception.ErrorCode;
import com.hai.common.exception.ErrorHelp;
import com.hai.common.exception.SysCode;
import com.hai.common.utils.DateUtil;
import com.hai.common.utils.ResponseMsgUtil;
import com.hai.config.HuiLianTongConfig;
import com.hai.config.HuiLianTongUnionCardConfig;
import com.hai.dao.*;
import com.hai.entity.*;
import com.hai.enum_type.OrderPushType;
import com.hai.model.AgentSalesModel;
import com.hai.service.*;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Auther: 胡锐
 * @Description:
 * @Date: 2021/4/20 23:02
 */
@Service("highCouponAgentService")
public class HighCouponAgentServiceImpl implements HighCouponAgentService {

    @Resource
    private HighCouponAgentRelMapper highCouponAgentRelMapper;

    @Resource
    private HighMerchantService highMerchantService;

    @Resource
    private HighCouponAgentCodeMapper highCouponAgentCodeMapper;

    @Resource
    private HighCouponAgentRecordMapper highCouponAgentRecordMapper;

    @Resource
    private HighCouponCodeService highCouponCodeService;

    @Resource
    private HighCouponService highCouponService;

    @Resource
    private HighAgentService highAgentService;

    @Resource
    private HuiLianTongConfig huiLianTongConfig;

    @Resource
    private HighGasOrderPushMapper highGasOrderPushMapper;

    @Resource
    private HighCouponCodeOtherMapper highCouponCodeOtherMapper;

    @Resource
    private HighCouponCodeOtherService couponCodeOtherService;

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public void assignCouponAgent(HighCouponAgentRel highCouponAgentRel,Integer stockCount) {
        if (highCouponAgentRel.getId() != null) {
            highCouponAgentRelMapper.updateByPrimaryKey(highCouponAgentRel);
        } else {
            highCouponAgentRelMapper.insert(highCouponAgentRel);
        }

        // 查询代理商
        HighAgent highAgent = highAgentService.findByAgentMsgId(highCouponAgentRel.getAgentId());

        // 查询卡券
        HighCoupon highCoupon = highCouponService.getCouponById(highCouponAgentRel.getCouponId());

        // 库存记录
        HighCouponAgentRecord record = new HighCouponAgentRecord();
        record.setCouponAgentId(highCouponAgentRel.getId());
        record.setCouponId(highCouponAgentRel.getCouponId());
        record.setCouponName(highCoupon.getCouponName());
        record.setSalesPrice(highCoupon.getSalesPrice());
        record.setAgentId(highCouponAgentRel.getAgentId());
        record.setAgentName(highAgent.getAgentName());
        record.setStockCount(stockCount);
        record.setOperatorId(highCouponAgentRel.getOperatorId());
        record.setOperatorName(highCouponAgentRel.getOperatorName());
        record.setCreateTime(new Date());
        highCouponAgentRecordMapper.insert(record);

        if (highCouponAgentRel.getParentCouponAgentId() == null) {
            if (highCouponAgentRel.getType() == 1) {
                // 查询未销售的卡券
                List<HighCouponCode> codeList = highCouponCodeService.getNoSaleCode(highCouponAgentRel.getCouponId());
                if (stockCount > codeList.size()) {
                    throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "无法分配，分配数量超过库存数量");
                }
                List<HighCouponCode> assignCouponCodeList = codeList.stream().limit(stockCount).collect(Collectors.toList());
                HighCouponAgentCode highCouponAgentCode;
                for (HighCouponCode code : assignCouponCodeList) {
                    code.setAgentId(highCouponAgentRel.getAgentId());
                    code.setIsAssignAgent(true);
                    highCouponCodeService.updateCouponCode(code);

                    highCouponAgentCode = new HighCouponAgentCode();
                    highCouponAgentCode.setType(highCouponAgentRel.getType());
                    highCouponAgentCode.setCouponAgentId(highCouponAgentRel.getId());
                    highCouponAgentCode.setCouponAgentRecordId(record.getId());
                    highCouponAgentCode.setCouponId(code.getCouponId());
                    highCouponAgentCode.setAgentId(highCouponAgentRel.getAgentId());
                    highCouponAgentCode.setCouponCodeId(code.getId());
                    highCouponAgentCode.setCouponCode(code.getSalesCode());
                    highCouponAgentCode.setQrCode(code.getExt1());
                    highCouponAgentCode.setStatus(1);
                    highCouponAgentCode.setCreateTime(new Date());
                    highCouponAgentCode.setOperatorId(highCouponAgentRel.getOperatorId());
                    highCouponAgentCode.setOperatorName(highCouponAgentRel.getOperatorName());
                    highCouponAgentCodeMapper.insert(highCouponAgentCode);
                }
            }

            if (highCouponAgentRel.getType() == 2) {
                HighCouponAgentCode highCouponAgentCode;
                for (int i = 0; i < stockCount; i++) {
                    highCouponAgentCode = new HighCouponAgentCode();
                    highCouponAgentCode.setType(highCouponAgentRel.getType());
                    highCouponAgentCode.setCouponAgentId(highCouponAgentRel.getId());
                    highCouponAgentCode.setCouponAgentRecordId(record.getId());
                    highCouponAgentCode.setCouponId(highCoupon.getId());
                    highCouponAgentCode.setAgentId(highCouponAgentRel.getAgentId());
                    highCouponAgentCode.setConvertCode(generateConvertCode(highCouponAgentRel.getId()));
                    highCouponAgentCode.setStatus(1);
                    highCouponAgentCode.setCreateTime(new Date());
                    highCouponAgentCode.setOperatorId(highCouponAgentRel.getOperatorId());
                    highCouponAgentCode.setOperatorName(highCouponAgentRel.getOperatorName());
                    highCouponAgentCodeMapper.insert(highCouponAgentCode);
                }
            }
        }

        if (highCouponAgentRel.getParentCouponAgentId() != null) {

            // 父级代理商库存
            HighCouponAgentRel parentRel = getRelById(highCouponAgentRel.getParentCouponAgentId());
            if (parentRel == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到代理商");
            }
            parentRel.setStockCount(parentRel.getStockCount() - stockCount);
            parentRel.setSalesCount(parentRel.getSalesCount() + stockCount);
            highCouponAgentRelMapper.updateByPrimaryKey(parentRel);

            // 查询父代理商未分配的码值
            List<HighCouponAgentCode> codeList = getNoSaleCode(parentRel.getId());
            if (codeList.size() < stockCount) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "库存数量不足");
            }
            for (int i = 0; i < stockCount; i++) {
                HighCouponAgentCode code = codeList.get(i);
                code.setAssignCouponAgentId(highCouponAgentRel.getId());
                code.setAssignAgentId(highAgent.getId());
                code.setAssignAgentName(highAgent.getAgentName());
                code.setStatus(4);
                highCouponAgentCodeMapper.updateByPrimaryKey(code);

                code.setId(null);
                code.setAssignCouponAgentId(null);
                code.setAssignAgentId(null);
                code.setAssignAgentName(null);
                code.setStatus(1);
                code.setAgentId(highCouponAgentRel.getAgentId());
                code.setCouponAgentId(highCouponAgentRel.getId());
                code.setCouponAgentRecordId(record.getId());
                code.setCreateTime(new Date());
                code.setOperatorId(highCouponAgentRel.getOperatorId());
                code.setOperatorName(highCouponAgentRel.getOperatorName());
                highCouponAgentCodeMapper.insert(code);
            }
        }
    }

    @Override
    public void updateCouponAgentCode(HighCouponAgentCode highCouponAgentCode) {
        highCouponAgentCodeMapper.updateByPrimaryKey(highCouponAgentCode);
    }

    @Override
    public HighCouponAgentRel getRelByCouponAgent(Long couponId, Long agentId,Integer type) {
        HighCouponAgentRelExample example = new HighCouponAgentRelExample();
        example.createCriteria().andCouponIdEqualTo(couponId).andAgentIdEqualTo(agentId).andTypeEqualTo(type);
        List<HighCouponAgentRel> list = highCouponAgentRelMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public HighCouponAgentRel getRelById(Long couponAgentRelId) {
        return highCouponAgentRelMapper.selectByPrimaryKey(couponAgentRelId);
    }

    @Override
    public List<HighCouponAgentRel> getCouponAgentList(Map<String, Object> map) {
        HighCouponAgentRelExample example = new HighCouponAgentRelExample();
        HighCouponAgentRelExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getInteger(map, "type") != null) {
            criteria.andTypeEqualTo(MapUtils.getInteger(map, "type"));
        }

        if (MapUtils.getLong(map, "couponId") != null) {
            criteria.andCouponIdEqualTo(MapUtils.getLong(map, "couponId"));
        }

        if (MapUtils.getLong(map, "agentId") != null) {
            criteria.andAgentIdEqualTo(MapUtils.getLong(map, "agentId"));
        }

        criteria.andStatusEqualTo(1);
        example.setOrderByClause("create_time desc");
        return highCouponAgentRelMapper.selectByExample(example);
    }

    @Override
    public List<HighCouponAgentCode> getCouponCodeList(Map<String, Object> map) {
        HighCouponAgentCodeExample example = new HighCouponAgentCodeExample();
        HighCouponAgentCodeExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getLong(map, "couponAgentId") != null) {
            criteria.andCouponAgentIdEqualTo(MapUtils.getLong(map, "couponAgentId"));
        }

        if (MapUtils.getInteger(map, "type") != null) {
            criteria.andTypeEqualTo(MapUtils.getInteger(map, "type"));
        }

        if (MapUtils.getLong(map, "couponId") != null) {
            criteria.andCouponIdEqualTo(MapUtils.getLong(map, "couponId"));
        }

        if (MapUtils.getLong(map, "agentId") != null) {
            criteria.andAgentIdEqualTo(MapUtils.getLong(map, "agentId"));
        }

        if (MapUtils.getLong(map, "createTimeS") != null) {
            criteria.andCreateTimeGreaterThanOrEqualTo(new Date(MapUtils.getLong(map, "createTimeS")));
        }

        if (MapUtils.getLong(map, "createTimeE") != null) {
            criteria.andCreateTimeLessThanOrEqualTo(new Date(MapUtils.getLong(map, "createTimeE")));
        }

        if (StringUtils.isNotBlank(MapUtils.getString(map, "status"))) {
            String[] strings = MapUtils.getString(map, "status").split(",");
            List<Integer> statusList = new ArrayList<>();
            for (String i : strings) {
                statusList.add(Integer.parseInt(i));
            }
            criteria.andStatusIn(statusList);
        }

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

    @Override
    public HighCouponAgentCode getCodeById(Long couponAgentCodeId) {
        return highCouponAgentCodeMapper.selectByPrimaryKey(couponAgentCodeId);
    }

    @Override
    public HighCouponAgentCode getAgentCodeByCodeIdAgent(Long codeId, Long agentId) {
        HighCouponAgentCodeExample example = new HighCouponAgentCodeExample();
        example.createCriteria().andCouponCodeIdEqualTo(codeId).andAgentIdEqualTo(agentId);
        List<HighCouponAgentCode> list = highCouponAgentCodeMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW)
    public Map<String, Object> generateCode(Long couponAgentCodeId,String remark) {
        // 查询卡券销售码
        HighCouponAgentCode couponAgentCode = getCodeById(couponAgentCodeId);
        if (couponAgentCode == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未找到销售码");
        }
        if (couponAgentCode.getStatus() != 1) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "销售码已被销售");
        }
        couponAgentCode.setStatus(2);  // 状态：1.待销售 2.未使用 3.已使用
        couponAgentCode.setRemark(remark);
        couponAgentCode.setSalesTime(new Date());
        highCouponAgentCodeMapper.updateByPrimaryKey(couponAgentCode);

        HighCouponAgentRel couponAgent = getRelByCouponAgent(couponAgentCode.getCouponId(), couponAgentCode.getAgentId(), couponAgentCode.getType());
        couponAgent.setStockCount(couponAgent.getStockCount() - 1);
        couponAgent.setSalesCount(couponAgent.getSalesCount() + 1);
        highCouponAgentRelMapper.updateByPrimaryKey(couponAgent);


        HighCouponCode couponCode = null;
        if (couponAgentCode.getType() == 1) {
            couponCode = highCouponCodeService.getCouponCodeById(couponAgentCode.getCouponCodeId());
            couponCode.setStatus(2);
            couponCode.setReceiveTime(new Date());
            highCouponCodeService.updateCouponCode(couponCode);
        }

        Map<String, Object> map = new HashMap<>();
        map.put("couponInfo", highCouponService.getCouponById(couponAgentCode.getCouponId()));
        map.put("couponCode", couponCode);
        map.put("couponAgentCode", couponAgentCode);
        return map;
    }

    @Override
    public Map<String, Object> getSalesCountByAgent(Long agentId, Integer type) throws Exception {
        BigDecimal surplusCountPrice = new BigDecimal("0");
        BigDecimal salesCountPrice = new BigDecimal("0");

        Map<String,Object> listMap = new HashMap<>();
        listMap.put("agentId", agentId);
        listMap.put("type", type);
        List<HighCouponAgentRel> list = getCouponAgentList(listMap).stream().sorted(Comparator.comparing(HighCouponAgentRel::getSalesPrice)).collect(Collectors.toList());
        for (HighCouponAgentRel highCouponAgentRel : list) {
            BigDecimal surplusPrice = new BigDecimal(highCouponAgentRel.getStockCount()).multiply((highCouponAgentRel.getSalesPrice()));
            surplusCountPrice = surplusCountPrice.add(surplusPrice);

            BigDecimal salesPrice = new BigDecimal(highCouponAgentRel.getSalesCount()).multiply((highCouponAgentRel.getSalesPrice()));
            salesCountPrice = salesCountPrice.add(salesPrice);
        }

        // 当前日时间
        Calendar consumeTimeS = Calendar.getInstance();
        consumeTimeS.setTime(new Date());
        consumeTimeS.set(Calendar.HOUR_OF_DAY, 00);
        consumeTimeS.set(Calendar.MINUTE, 00);
        consumeTimeS.set(Calendar.SECOND, 00);

        Calendar consumeTimeE = Calendar.getInstance();
        consumeTimeE.setTime(new Date());
        consumeTimeE.set(Calendar.HOUR_OF_DAY, 23);
        consumeTimeE.set(Calendar.MINUTE, 59);
        consumeTimeE.set(Calendar.SECOND, 59);

        AgentSalesModel agentSales = highCouponAgentRelMapper.getAgentSales(agentId, DateUtil.date2String(consumeTimeS.getTime(), "yyyy-MM-dd HH:mm:ss"), DateUtil.date2String(consumeTimeE.getTime(), "yyyy-MM-dd HH:mm:ss"));

        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("orderCount", agentSales.getCount());
        returnMap.put("turnoverPrice", agentSales.getSalesCountPrice());

        returnMap.put("laveStockCount", highCouponAgentRelMapper.getAgentCodeCount(agentId, "1", type));  // 库存数量
        returnMap.put("soldCount", highCouponAgentRelMapper.getAgentCodeCount(agentId, "2,3", type));       // 销售数量

        returnMap.put("surplusCountPrice", surplusCountPrice); // 剩余总额
        returnMap.put("salesCountPrice", salesCountPrice);   // 销售总额
        returnMap.put("list", list);
        return returnMap;
    }

    @Override
    public Map<String, Object> getConvertCodeCountByAgent(Long agentId) {
        Map<String,Object> listMap = new HashMap<>();
        listMap.put("agentId", agentId);
        listMap.put("type", 2);
        List<HighCouponAgentRel> list = getCouponAgentList(listMap).stream().sorted(Comparator.comparing(HighCouponAgentRel::getSalesPrice)).collect(Collectors.toList());

        for (HighCouponAgentRel couponAgentRel : list) {
            Map<String, Object> map = highCouponAgentRelMapper.getUseNum(couponAgentRel.getId());
            couponAgentRel.setUsedNum(MapUtils.getInteger(map, "usedNum"));
            couponAgentRel.setUsedPrice(new BigDecimal(MapUtils.getString(map, "usedPrice")));
            couponAgentRel.setNoUsedNum(MapUtils.getInteger(map, "noUsedNum"));
            couponAgentRel.setNoUsedPrice(new BigDecimal(MapUtils.getString(map, "noUsedPrice")));
        }

        Map<String, Object> returnMap = new HashMap<>();
        returnMap.put("list", list);

        // 待销售
        returnMap.put("noSalesNum", highCouponAgentRelMapper.getAgentCodeCount(agentId, "1", 2));
        returnMap.put("noSalesPrice", highCouponAgentRelMapper.getAgentCodePrice(agentId, "1", 2));

        // 已销售
        returnMap.put("salesNum", highCouponAgentRelMapper.getAgentCodeCount(agentId, "2", 2));
        returnMap.put("salesPrice", highCouponAgentRelMapper.getAgentCodePrice(agentId, "2", 2));

        // 待使用
        returnMap.put("noUsedNum", highCouponAgentRelMapper.getAgentCodeCount(agentId, "2", 2));
        returnMap.put("noUsedPrice", highCouponAgentRelMapper.getAgentCodePrice(agentId, "2", 2));

        // 已使用
        returnMap.put("usedNum", highCouponAgentRelMapper.getAgentCodeCount(agentId, "3", 2));
        returnMap.put("usedPrice", highCouponAgentRelMapper.getAgentCodePrice(agentId, "3", 2));

        return returnMap;
    }

    @Override
    public List<HighCouponAgentRecord> getRecordList(Map<String, Object> map) {
        HighCouponAgentRecordExample example = new HighCouponAgentRecordExample();
        HighCouponAgentRecordExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getLong(map, "couponAgentId") != null) {
            criteria.andCouponAgentIdEqualTo(MapUtils.getLong(map, "couponAgentId"));
        }

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

    @Override
    public List<HighCouponAgentCode> getCouponAgentCodeList(Map<String, Object> map) {
        HighCouponAgentCodeExample example = new HighCouponAgentCodeExample();
        HighCouponAgentCodeExample.Criteria criteria = example.createCriteria();

        if (MapUtils.getLong(map, "recordId") != null) {
            criteria.andCouponAgentRecordIdEqualTo(MapUtils.getLong(map, "recordId"));
        }

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

    @Override
    public List<HighCouponAgentCode> getAgentSalesCodeList(Long agentId, String consumeTimeS, String consumeTimeE) {
        List<HighCouponAgentCode> list = highCouponAgentRelMapper.getAgentSalesCodeList(agentId, consumeTimeS, consumeTimeE);
        if (list != null && list.size() > 0) {
            for (HighCouponAgentCode code : list) {
                code.setHighCoupon(highCouponService.getCouponDetail(code.getCouponId()));
                code.setHighCouponCode(highCouponCodeService.getCouponCodeById(code.getCouponCodeId()));
            }
            return list;
        }
        return new ArrayList<>();
    }

    @Override
    public String generateConvertCode(Long couponAgentRelId) {
        // 生成兑换码
        String code = GenerateCode.convertCode(couponAgentRelId);
        if (getConvertCode(code) != null){
            return generateConvertCode(couponAgentRelId);
        }
        return code;
    }

    @Override
    public HighCouponAgentCode getConvertCode(String convertCode) {
        HighCouponAgentCodeExample example = new HighCouponAgentCodeExample();
        example.createCriteria().andConvertCodeEqualTo(convertCode);
        List<HighCouponAgentCode> list = highCouponAgentCodeMapper.selectByExample(example);
        if (list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    @Transactional(propagation= Propagation.REQUIRES_NEW,isolation= Isolation.SERIALIZABLE)
    public Map<String, Object> useConvertCode(String phone, String code) throws Exception {
        // 查询兑换码
        HighCouponAgentCode convertCode = getConvertCode(code);
        if (convertCode == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "无效的兑换码");
        }
        if (convertCode.getStatus() == 3) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "兑换码已被使用");
        }
        if (convertCode.getCouponCodeId() != null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "兑换码已被使用");
        }
        // 查询卡券
        HighCoupon coupon = highCouponService.getCouponById(convertCode.getCouponId());
        if (coupon == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的卡券");
        }
        if (!coupon.getStatus().equals(2)) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "暂时无法使用兑换码");
        }
        // 卡券来源：1.中石化 2.消费券 3.其他  4：贵州中石化
        if (coupon.getCouponSource().equals(4)) {
            if (StringUtils.isBlank(phone)) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "需要填写手机手机号");
            }
            convertCode.setConvertUserPhone(phone);
            convertCode.setCouponCode(System.currentTimeMillis()+"");

            // 下单请求
            JSONObject rechargeObject = HuiLianTongConfig.recharge(convertCode.getConvertCode(),
                    1,
                    coupon.getCouponKey(),
                    phone);
            if (!rechargeObject.getString("respCode").equals("0000")) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "下单失败");
            }
            JSONObject response = HuiLianTongUnionCardConfig.resolveResponse(rechargeObject.getString("data"));
            convertCode.setExt1(response.getJSONObject("data").getString("rechargeOrderId"));
            highCouponAgentCodeMapper.updateByPrimaryKey(convertCode);

            // 购买卡券
            JSONObject returnParam = HuiLianTongConfig.costRechargeOrder(convertCode.getExt1());
            if (returnParam != null && returnParam.getString("respCode").equals("0000")) {
                // 解密
                JSONObject jsonObject = HuiLianTongUnionCardConfig.resolveResponse(returnParam.getString("data"));
                JSONArray dataArray = JSONObject.parseObject(jsonObject.getString("data"), JSONArray.class);
                for (Object data : dataArray) {
                    JSONObject dataObject = (JSONObject) data;
                    HighCouponCodeOther couponCodeOther = new HighCouponCodeOther();
                    couponCodeOther.setType(1);
                    couponCodeOther.setCouponAgentCodeId(convertCode.getId());
                    couponCodeOther.setCouTypeCode(dataObject.getString("couTypeCode"));
                    couponCodeOther.setCouNo(dataObject.getString("couNo"));
                    couponCodeOther.setActiveTime(dataObject.getDate("activeTime"));
                    couponCodeOther.setValidStartDate(dataObject.getDate("validStartDate"));
                    couponCodeOther.setValidEndDate(dataObject.getDate("validEndDate"));
                    couponCodeOther.setStatus(20);
                    couponCodeOther.setCreateTime(new Date());
                    highCouponCodeOtherMapper.insert(couponCodeOther);
                }
            }
            // 推送记录
            HighGasOrderPush highGasOrderPush = new HighGasOrderPush();
            highGasOrderPush.setType(OrderPushType.type6.getType());
            highGasOrderPush.setOrderNo(convertCode.getCouponCode());
            highGasOrderPush.setCreateTime(new Date());
            highGasOrderPush.setCode(returnParam.getString("respCode"));
            highGasOrderPush.setRequestContent(convertCode.getExt2());
            highGasOrderPush.setReturnContent(returnParam.toJSONString());
            highGasOrderPushMapper.insert(highGasOrderPush);

        } else {
            // 查询未销售的卡券
            List<HighCouponCode> codeList = highCouponCodeService.getNoSaleCode(convertCode.getCouponId());
            if (codeList.size() == 0) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "暂时无法使用兑换码");
            }
            HighCouponCode couponCode = codeList.get(0);
            couponCode.setIsAssignAgent(true);
            couponCode.setAgentId(convertCode.getAgentId());
            couponCode.setReceiveTime(new Date());
            couponCode.setStatus(2);
            highCouponCodeService.updateCouponCode(couponCode);

            convertCode.setCouponCodeId(couponCode.getId());
            convertCode.setCouponCode(couponCode.getSalesCode());
            convertCode.setQrCode(couponCode.getExt1());
        }
        convertCode.setStatus(3);
        highCouponAgentCodeMapper.updateByPrimaryKey(convertCode);

        // 查询卡券销售码
        Map<String, Object> map = new HashMap<>();
        map.put("couponInfo", highCouponService.getCouponById(convertCode.getCouponId()));
        map.put("couponCode", highCouponCodeService.getCouponCodeById(convertCode.getCouponCodeId()));
        map.put("couponAgentCode", convertCode);
        return map;

    }

    @Override
    @Transactional(rollbackFor=Exception.class,isolation = Isolation.SERIALIZABLE,propagation= Propagation.REQUIRES_NEW)
    public Map<String, Object> pushGzSinopec(Long couponAgentRelId, String phone, String remark) throws Exception {
        // 查询兑换码
        HighCouponAgentCode convertCode = getCodeById(couponAgentRelId);
        if (convertCode == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "无效的数据");
        }
        if (convertCode.getStatus() == 3) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "卡券已被使用");
        }
        // 查询卡券
        HighCoupon coupon = highCouponService.getCouponById(convertCode.getCouponId());
        if (coupon == null) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "未知的卡券");
        }
        // 卡券来源：1.中石化 2.消费券 3.其他  4：贵州中石化
        if (!coupon.getCouponSource().equals(4)) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "不是中石化卡券");
        }
        if (StringUtils.isBlank(phone)) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "需要填写手机手机号");
        }
        convertCode.setConvertUserPhone(phone);
        convertCode.setRemark(remark);
        convertCode.setCouponCode(System.currentTimeMillis()+"");
        convertCode.setSalesTime(new Date());
        convertCode.setStatus(2);
        highCouponAgentCodeMapper.updateByPrimaryKey(convertCode);

        HighCouponAgentRel couponAgent = highCouponAgentRelMapper.selectByPrimaryKey(convertCode.getCouponAgentId());
        couponAgent.setStockCount(couponAgent.getStockCount() - 1);
        couponAgent.setSalesCount(couponAgent.getSalesCount() + 1);
        highCouponAgentRelMapper.updateByPrimaryKey(couponAgent);

        // 第一次，下单请求
        JSONObject rechargeObject = HuiLianTongConfig.recharge(convertCode.getConvertCode(),
                1,
                coupon.getCouponKey(),
                phone);

        System.out.println("第一次下单" + rechargeObject.toJSONString());
        if (!rechargeObject.getString("respCode").equals("0000")) {
            throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "下单失败");
        }
        JSONObject response = HuiLianTongUnionCardConfig.resolveResponse(rechargeObject.getString("data"));
        if (response == null || response.getJSONObject("data") == null) {
             // 第二次，下单请求
             // 重新生成兑换码
             convertCode.setConvertCode(generateConvertCode(couponAgent.getId()));
             rechargeObject = HuiLianTongConfig.recharge(convertCode.getConvertCode(),
                    1,
                    coupon.getCouponKey(),
                    phone);
            System.out.println("第二次下单" + rechargeObject.toJSONString());
            response = HuiLianTongUnionCardConfig.resolveResponse(rechargeObject.getString("data"));
            if (response == null || response.getJSONObject("data") == null) {
                throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, "下单失败");
            }
        }
        convertCode.setExt1(response.getJSONObject("data").getString("rechargeOrderId"));
        highCouponAgentCodeMapper.updateByPrimaryKey(convertCode);

        // 购买卡券
        JSONObject returnParam = HuiLianTongConfig.costRechargeOrder(convertCode.getExt1());
        if (returnParam != null && returnParam.getString("respCode").equals("0000")) {
            // 解密
            JSONObject jsonObject = HuiLianTongUnionCardConfig.resolveResponse(returnParam.getString("data"));
            JSONArray dataArray = JSONObject.parseObject(jsonObject.getString("data"), JSONArray.class);
            for (Object data : dataArray) {
                JSONObject dataObject = (JSONObject) data;
                HighCouponCodeOther couponCodeOther = new HighCouponCodeOther();
                couponCodeOther.setType(1);
                couponCodeOther.setCouponAgentCodeId(convertCode.getId());
                couponCodeOther.setCouTypeCode(dataObject.getString("couTypeCode"));
                couponCodeOther.setCouNo(dataObject.getString("couNo"));
                couponCodeOther.setActiveTime(dataObject.getDate("activeTime"));
                couponCodeOther.setValidStartDate(dataObject.getDate("validStartDate"));
                couponCodeOther.setValidEndDate(dataObject.getDate("validEndDate"));
                couponCodeOther.setStatus(20);
                couponCodeOther.setCreateTime(new Date());
                highCouponCodeOtherMapper.insert(couponCodeOther);
            }
        }
        // 推送记录
        HighGasOrderPush highGasOrderPush = new HighGasOrderPush();
        highGasOrderPush.setType(OrderPushType.type6.getType());
        highGasOrderPush.setOrderNo(convertCode.getCouponCode());
        highGasOrderPush.setCreateTime(new Date());
        highGasOrderPush.setCode(returnParam.getString("respCode"));
        highGasOrderPush.setRequestContent(convertCode.getExt2());
        highGasOrderPush.setReturnContent(returnParam.toJSONString());
        highGasOrderPushMapper.insert(highGasOrderPush);

        // 查询卡券销售码
        Map<String, Object> map = new HashMap<>();
        map.put("couponInfo", highCouponService.getCouponById(convertCode.getCouponId()));
        map.put("couponCode", highCouponCodeService.getCouponCodeById(convertCode.getCouponCodeId()));
        map.put("couponCodeOther", couponCodeOtherService.getDetailByCouponAgentCodeId(couponAgentRelId));
        map.put("couponAgentCode", convertCode);
        return map;
    }

    @Override
    public List<HighCouponAgentCode> getNoSaleCode(Long couponAgentRelId) {
        HighCouponAgentCodeExample example = new HighCouponAgentCodeExample();
        example.createCriteria().andStatusEqualTo(1).andCouponAgentIdEqualTo(couponAgentRelId);
        example.setOrderByClause("create_time desc");
        return highCouponAgentCodeMapper.selectByExample(example);
    }

}
