package com.chinacreator.video.restful.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.chinacreator.video.bean.ChannelBean;
import com.chinacreator.video.bean.OrderInfo;
import com.chinacreator.video.exception.BussinessException;
import com.chinacreator.video.mapper.ChannelDao;
import com.chinacreator.video.mapper.CommConfDao;
import com.chinacreator.video.mapper.CouponDao;
import com.chinacreator.video.mapper.DictionaryDao;
import com.chinacreator.video.service.CommonService;
import com.chinacreator.video.util.DesUtil;
import com.chinacreator.video.util.MD5;
import com.chinacreator.video.validate.ChannelValidate;
import com.chinacreator.video.validate.IpValidate;
import com.chinacreator.video.validate.MobValidate;
import com.chinacreator.video.validate.TimetampValidate;
import org.apache.commons.lang.StringUtils;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * @author zhengrong.yan
 * @date 20210621
 */
@Component
public class CouponService {

    @Autowired
    private ChannelValidate channelValidate;

    @Autowired
    private IpValidate ipValidate;

    @Autowired
    private MobValidate mobValidate;

    @Autowired
    private TimetampValidate timetampValidate;

    @Autowired
    private CommConfDao commConfDao;

    @Autowired
    private CommonService commonService;

    @Autowired
    private CouponDao couponDao;

    @Autowired
    private ChannelDao channelDao;

    @Autowired
    private DictionaryDao dictionaryDao;

    private static Logger logger = Logger.getLogger(CouponService.class);

    private static Logger log = Logger.getLogger("couponquery");

    private static Logger log2 = Logger.getLogger("couponverify");

    public void busiCheck(OrderInfo orderInfo, int type) throws Exception {
        //timetamp验证
        timetampValidate.validate(orderInfo.getTimestamp());
        //渠道验证
        channelValidate.validate(orderInfo.getChannel());
        //ip验证
        ipValidate.volidate(orderInfo);
        //签名验证
        signValidate(orderInfo, type);
        //手机号码验证
        mobValidate(orderInfo);
        //并发访问控制
//        vistVali(orderInfo, type);
    }


    /**
     * 券码查询
     *
     * @param orderInfo
     */
    public com.alibaba.fastjson.JSONArray query(OrderInfo orderInfo) throws Exception {
        com.alibaba.fastjson.JSONArray jsonArray = new com.alibaba.fastjson.JSONArray();
        HashMap map = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMM");
        SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        //如果当前query时间和数据库时间不是同一月份，则拒绝查询 显示券码正在生成中，请稍后再试
        String sqlsysdate = couponDao.getSqlSysDate();
        log.info("---------当前数据库时间是否和服务器时间一致--------");
        if (!sqlsysdate.equals(sdf2.format(new Date()))) {
            log.info("-------不一致，数据库时间" + sqlsysdate + " 服务器时间---" + sdf2.format(new Date()));
            throw new BussinessException("8008", "本月券码正在生成中……请稍后再试");
        }
        log.info("-------一致，数据库时间" + sqlsysdate + " 服务器时间---" + sdf2.format(new Date()));
        try {
            String userid = orderInfo.getUserid();
            //List<HashMap> relations = couponDao.findOrderRela(userid);//更新20210726 只生成有效且查询时间在活动范围内的
            //数据正在生成中，暂无券码
            //List<HashMap> hashMap = couponDao.hasRec();//查找当月是否有数据
            //当月1日0点-0点30分
            String limitstart = sdf.format(new Date());
            limitstart = limitstart.substring(0, 8) + "01" + " 00:00:00";
            String limitend = limitstart.substring(0, 10) + " 00:30:00";
            Date limitstarttime = sdf3.parse(limitstart);//限制开始时间
            Date limitendtime = sdf3.parse(limitend);
            Date today = new Date();
//已下线 20220216
//            if ((hashMap == null || hashMap.size() <= 0) && (relations != null && relations.size() > 0)) {
//                if ((today.getTime() >= limitstarttime.getTime()) && (today.getTime() <= limitendtime.getTime()))
//                    //有资格返回正在生成，无资格，返回空
//                    throw new BussinessException("8008", "本月券码正在生成中……请稍后再试");
//            } else if (hashMap == null || hashMap.size() <= 0) {
//                return jsonArray;
//            }
//            if (relations != null && relations.size() > 0) {
//                for (HashMap rela : relations) {
//                    //20210629逻辑修改
//
//                    //订购关系表状态 status 0：订购 1 退订 但暂未到失效时间 2 退订 已过期
//                    String status = rela.get("STATUS") == null ? "" : rela.get("STATUS").toString();
//                    log.info("userid==>" + userid + "订购关系表中状态status===>" + status);
//
//                    String orderid = rela.get("ID") == null ? "" : rela.get("ID").toString();
//                    String spid = rela.get("SPID") == null ? "" : rela.get("SPID").toString();
//                    String monthlastday = getMonthLastDay();//获取本月的最后一天
//                    String starttime = monthlastday.substring(0, 8) + "01";//本月第一天
//                    String ordertime = rela.get("ORDERTIME") == null ? "" : rela.get("ORDERTIME").toString().substring(0, 10);
//                    String inserttime = sdf3.format(new Date());
//                    String couponmonth = sdf2.format(new Date());
//
//                    Date order = sdf.parse(ordertime);
//                    Date start = sdf.parse(starttime);
//                    if (order.getTime() >= start.getTime()) {//订购时间>=当月第一天，则券码开始时间/发放券码时间 为订购时间
//                        starttime = ordertime;
//                        inserttime = rela.get("ORDERTIME").toString();
//                    } else {//续订用户。发放券码和券码开始时间为本月的第一天
//                        inserttime = starttime + " 00:00:00";
//                    }
//
//                    //当月先生成一张券码
//                    /*公共部分*/
//                    map.put("id", couponDao.getNo());
//                    map.put("orderid", orderid);
//                    map.put("userid", rela.get("USERID"));
//                    map.put("cpid", rela.get("CPID"));
//                    map.put("spid", spid);
//                    map.put("starttime", starttime);
//                    map.put("endtime", monthlastday);
//                    map.put("couponmonth", couponmonth);//当月
//                    map.put("inserttime", inserttime);
//                    map.put("couponid",rela.get("COUPONID"));
//
//
//                    //20210726逻辑修改 新增每个用户仅生成一张券码 活动产品阿里15元
//                    String isUnique = rela.get("ISUNIQUE") == null ? "" : rela.get("ISUNIQUE").toString();//0 此产品一个userid一个唯一券码
//                    map.put("isunique",isUnique);
//                    if ("0".equals(isUnique) || "2".equals(isUnique)) {
//                        //查找表内是否已有该产品数据
//                        List<HashMap> maps = couponDao.hasRec2(userid, spid);
//                        if (maps != null && maps.size() > 0) {
//                            //代表有数据，则此spid本次不生成券码
//                            log.info("表内已有数据，不生成券码，userid=>"+userid+" spid=>"+spid+" isUnique=>"+isUnique);
//                            continue;
//                        } else {
//                            dealProduct(map, spid, isUnique);
//                        }
//                    } else {
//                        if ("99144186".equals(spid)) {
//                            dealProduct(map);
//                        } else {
//                            for (int i = 0; i < 3; i++) {
//                                hasRec(map, i);
//                                map.put("id", couponDao.getNo());
//                                log.info("flag===>" + i + " SPID===>" + spid);
//                            }
//                        }
//                    }
//                }
//            }
//                //有效期内的券码类型没有找到匹配的订购关系，对于实时订购产品，开始找订购日志是否有活动期内可以生成的券码
//            List<HashMap> timelyspids = couponDao.getTimelyCoupon(userid);//数据库内需要实时生成的券码类型(结束日期在三个月内的）
//            for(HashMap timely:timelyspids) {
//                String spid = timely.get("SPID").toString();
//                log.info("需要实时生成的spid-->"+spid);
//                List<HashMap> maps = couponDao.hasRec3(userid, spid);
//                if(maps!=null && maps.size()>0) {
//                    log.info("表内已有数据，不生成实时的券码");
//                }else{
//                    map.put("id", couponDao.getNo());
//                    map.put("orderid", timely.get("ORDERID"));
//                    map.put("userid", userid);
//                    map.put("spid", spid);
//                    map.put("couponid", timely.get("ID"));
//                    map.put("cpid", timely.get("CPID"));
//                    dealProduct(map, spid, "2");
//                }
//            }
            //重新遍历结果
//            List<HashMap> couponrec = couponDao.getCouponRec2(userid);//获取可能需要修改的所有数据
            //20220217修改 使用新表   | 20220819修改  加上千人千面数据
            List<HashMap> couponrec = couponDao.getCouponRec_new(userid);//获取可能需要修改的所有数据
            //处理结果 更新状态
            judgeTime(couponrec);
//            couponrec = couponDao.getCouponRec(userid);//获取最最最新的一条数据（此数据最终要给合作方）
            //20220217修改 使用新表（联合原表+新表一起显示）  | 20220819 加上千人千面数据  | 20220829新增加上是否拆分字段以及拆分规则
            couponrec = couponDao.getCouponRec_show(userid);//获取最最最新的一条数据（此数据最终要给合作方）
            //end
            //20211227 修改 由于并发会生成多条数据，故展示给合作方时仅显示一条
            List<String> keys = new ArrayList<>();
            keys.add("SPID");
            keys.add("COUPONMONTH");
            //couponrec = deleteDuplicatedMapFromListByKeys(couponrec,keys);
            Collections.sort(couponrec, new MyComparator());
            if (couponrec != null && couponrec.size() > 0) {
                for (HashMap map1 : couponrec) {
                    map1.remove("COUPONMONTH");
                    JSONObject jsonObj = new JSONObject(map1);//转化为json格式
                    jsonObj = transToLowerObject(jsonObj.toString());
                    //已下线
//                    if ("979".equals(map1.get("SPID"))) {
//                        log.info("---979需要添加参数是否拆分和拆分规则---");
//                        jsonObj.put("issplit", "0");
//                        jsonObj.put("splitrule", "10+1+1+1+1");
//                    }
                    jsonArray.add(jsonObj);
                }
            }
            log.info("jsonarray===>" + jsonArray);
            return jsonArray;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /*查找上月的日志，进行数据添加or更新*/
    public void findLastmonthRec(HashMap map) {
        String userid = map.get("userid").toString();
        String spid = map.get("spid").toString();
        String orderid = map.get("orderid").toString();
        int flag = map.get("flag") == null ? 1 : (int) map.get("flag");
        Boolean hasOrder = false;//是否已订购过
        Boolean hasCancel = false;//是否退订过
        String lastmonth = getMonthLastDay(flag).replaceAll("-", "").substring(0, 6);
        List<HashMap> lastmonthrec = couponDao.findOrderLog(userid, spid, lastmonth);
        if (lastmonthrec != null && lastmonthrec.size() > 0) {
            for (HashMap map1 : lastmonthrec) {
                BigDecimal bigDecimal = (BigDecimal) map1.get("STATUS");
                if (bigDecimal != null) {
                    Integer recstatus = Integer.parseInt(bigDecimal.toString());
                    if (recstatus == 0) {
                        hasOrder = true;
                    } else if (recstatus == 1) {
                        hasCancel = true;
                    }
                }
                log.info("status===>" + map1.get("STATUS"));
                log.info("size===>" + map1.size());
                log.info("status2===>" + map1.get("STATUS"));
                log.info(lastmonth + "有数据：hasOrder==" + hasOrder + "  hasCancel==" + hasCancel);
            }
            //无0有1 or 有0有1 or 有0无1 都生成
            if ((!hasOrder && hasCancel) || hasOrder) {
                //查找是否表内已有数据
                map.put("couponmonth", lastmonth);
                hasRec(map, flag);
            } else if (!hasOrder && !hasCancel) {//无0无1
                flag++;
                if (flag == 3) {
                    return;//只查两个月
                }
                map.put("flag", flag);
                findLastmonthRec(map);//继续查找上个月数据
            }
        }
    }


    /*查找上月的日志，进行数据添加or更新*/
    public Boolean findLastmonthRec2(HashMap map, String type) {
        Boolean add = false;
        String userid = map.get("userid").toString();
        String spid = map.get("spid").toString();
        int flag = map.get("flag") == null ? 1 : (int) map.get("flag");
        Boolean hasOrder = false;//是否已订购过
        Boolean hasCancel = false;//是否退订过
        String lastmonth = getMonthLastDay(flag).replaceAll("-", "").substring(0, 6);
        List<HashMap> lastmonthrec = null;
        if ("1".equals(type)) {
            lastmonthrec = couponDao.findOrderLogCap(userid, spid, lastmonth);
        } else {
            lastmonthrec = couponDao.findOrderLog(userid, spid, lastmonth);
        }
        log.info("查询订购日志表start====" + userid + " month==>" + lastmonth);
        if (lastmonthrec != null && lastmonthrec.size() > 0) {
            for (HashMap map1 : lastmonthrec) {
                BigDecimal bigDecimal = (BigDecimal) map1.get("STATUS");
                if (bigDecimal != null) {
                    Integer recstatus = Integer.parseInt(bigDecimal.toString());
                    if (recstatus == 0) {
                        hasOrder = true;
                    } else if (recstatus == 1) {
                        hasCancel = true;
                    }
                }
                log.info("status===>" + map1.get("STATUS"));
                log.info("size===>" + map1.size());
                log.info("status2===>" + map1.get("STATUS"));
                log.info(lastmonth + "有数据：hasOrder==" + hasOrder + "  hasCancel==" + hasCancel);
            }
        }
        //无0有1 or 有0有1 or 有0无1 都生成
        if ((!hasOrder && hasCancel) || hasOrder) {
            map.put("couponmonth", lastmonth);
            if ("1".equals(type)) {
                //查看之前是否有退订（在活动范围之间）
                String hascancel = couponDao.findOrderLogCapSpid(userid, spid, lastmonth);
                if (hasCancel != null && Integer.parseInt(hascancel) > 0) {//之前有过退订
//                    flag++;
//                    if(flag==3){
//                        add = false;
//                        return add;
//                    }
//                    map.put("flag", flag);
//                    return findLastmonthRec2(map,type);//继续查找上个月数据
                    //查看最早的退订时间（活动范围之内）是否等于当前传过来的日期）

                    //当前时间
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");
                    String now = sdf.format(new Date());
                    String earlycancelmonth = couponDao.findEarlyCancelMonth(userid, spid);
                    String searchmonth = map.get("searchmonth") == null ? now : map.get("searchmonth").toString();
                    log.info("----搜索month--" + searchmonth + "  ---最早退订month---" + earlycancelmonth);
                    if (searchmonth.equals(earlycancelmonth)) {
                        //查找有无最早订购月份，有则生成，无则代表只有退订，订购是在时间之外
                        log.info("---退订月份和搜索月份一致---查看是否在活动时间（退订月份之前）内有过订购-，有则生成，无则代表只有退订，订购是在时间之外");
                        String lastOrderMonth = couponDao.getTheEarlyOrderByMonth(userid, spid, earlycancelmonth);
                        if (lastOrderMonth != null && !"".equals(lastOrderMonth)) {
                            add = true;
                        } else {
                            add = false;
                        }
                    } else {
                        //查找在最早退订月份之前是否还有订购，如果有订购记录则本月不生成，没有的话代表是新订购，需要生成
                        //即查看活动范围内是否还有最早的一次订购
                        log.info("-----有退订，且最早退订月份和当前月份不一致--查看是否在活动时间（退订月份之前）内有过订购-----");
                        String lastOrderMonth = couponDao.getTheEarlyOrderByMonth(userid, spid, earlycancelmonth);
                        if (lastOrderMonth != null && !"".equals(lastOrderMonth)) {
                            add = false;
                        } else {
                            add = true;
                        }
                    }
                    return add;
                } else {
                    //之前没有过退订，查看当前的订购时间是否是在活动范围之内
                    log.info("之前没有过退订，查看当前的订购时间是否是在活动范围之内");
                    String lastOrderMonth = couponDao.getTheEarlyOrder(userid, spid);
                    if (lastOrderMonth != null && !"".equals(lastOrderMonth)) {
                        add = true;
                    } else {
                        add = false;
                    }
                }
            } else {
                add = true;
            }
        } else if (!hasOrder && !hasCancel) {//无0无1
            flag++;
            if (flag == 3) {//如果到顶了，开始查离此月最近的一条数据
                map.put("couponmonth", lastmonth);
                HashMap recentRec = null;
                if ("1".equals(type)) {
                    recentRec = couponDao.getRecentStatus_Cap(map);
                } else {
                    recentRec = couponDao.getRecentStatus(map);
                }
                if (recentRec != null && recentRec.size() > 0) {
                    BigDecimal bigDecimal = (BigDecimal) recentRec.get("STATUS");
                    if (bigDecimal != null) {
                        Integer recstatus = Integer.parseInt(bigDecimal.toString());
                        if (recstatus == 0) {
                            add = true;
                        } else if (recstatus == 1) {
                            add = false;
                        }
                    }
                    log.info("status===>" + recentRec.get("STATUS"));
                    log.info(lastmonth + "月份封顶后查到最近的一条数据：month==" + lastmonth + "  是否添加==" + add);
                }
                return add;
            }
            map.put("flag", flag);
            map.put("searchmonth", lastmonth);
            return findLastmonthRec2(map, type);//继续查找上个月数据
        }
        return add;
    }

    /*查看表内是否已有数据并处理*/
    public void hasRec(HashMap map, int flag) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String userid = map.get("userid").toString();
        String orderid = map.get("orderid").toString();
        String spid = map.get("spid").toString();
        String couponmonth = map.get("couponmonth").toString();
        String starttime = map.get("starttime").toString();

        //查找是否表内已有数据
        try {
            String endtime_new = getMonthLastDay();
            String monthlastday = getMonthLastDay() + " 23:59:59";
            if (flag != 0) {
                endtime_new = getMonthLastDay(flag);
                monthlastday = getMonthLastDay(flag) + " 23:59:59";
                couponmonth = getMonthLastDay(flag).replaceAll("-", "").substring(0, 6);
            }
            String recstatus = null;
            List<HashMap> recstatus_cap = null;
            if ("99144186".equals(spid)) {
                recstatus_cap = couponDao.getStatus_cap(userid, spid, couponmonth);
            } else {
                recstatus = couponDao.getStatus(userid, spid, couponmonth);
            }
            Date endtime = sdf.parse(monthlastday);//endtime = 2021-06-30 23:59:59
            Date today = new Date();//当前日期

            if ((!"".equals(recstatus) && recstatus != null) || (recstatus_cap != null & recstatus_cap.size() > 0)) {//如果表内已有数据，根据当前订购状态
                HashMap couponrec = null;
                List<HashMap> couponrecMap = null;
                if ("99144186".equals(spid)) {
                    couponrecMap = couponDao.findCouponRec(userid, orderid, couponmonth, "1");//获取最新的一条数据
                } else {
                    couponrec = couponDao.findCouponRec(userid, orderid, couponmonth);//获取最新的一条数据
                }
                String id = "";
                //获取券码内的最后一天有效期
                if (couponrec != null) {
                    String end = couponrec.get("COUPONENDTIME") == null ? "" : couponrec.get("COUPONENDTIME").toString() + " 23:59:59";
                    if (!"".equals(end)) {
                        endtime = sdf.parse(end);
                    }
                    id = couponrec.get("ID") == null ? "" : couponrec.get("ID").toString();

                    log.info("userid===>" + userid + " couponmonth===>" + couponmonth + " endtime==>" + endtime);
                    if ((endtime.getTime() < today.getTime()) && "0".equals(recstatus)) {
                        log.info("userid===>" + userid + " couponmonth===>" + couponmonth + " endtime==>" + endtime + " 数据在有效期外");
                        //有效期外
                        recstatus = "2"; //已失效
                    }
                    map.put("status", recstatus);
                    log.info(couponmonth + "表内有数据，update==>" + recstatus + " couponmonth==>" + couponmonth);
                    map.put("couponmonth", couponmonth);
                    map.put("id", id);
                    couponDao.upCouponRec2(map);
                } else if (couponrecMap != null) {
                    log.info("---------带美团券的产品，有多个产品，需要循环遍历将数据更新----------");
                    for (HashMap c : couponrecMap) {//因为有多个 所以循环遍历
                        String end = c.get("COUPONENDTIME") == null ? "" : c.get("COUPONENDTIME").toString() + " 23:59:59";
                        if (!"".equals(end)) {
                            endtime = sdf.parse(end);
                        }
                        id = c.get("ID") == null ? "" : c.get("ID").toString();
                        //获取当前表内的状态，用id
                        recstatus = couponDao.getStatusById(id);
                        log.info("userid===>" + userid + " couponmonth===>" + couponmonth + " endtime==>" + endtime);
                        if ((endtime.getTime() < today.getTime()) && "0".equals(recstatus)) {
                            log.info("userid===>" + userid + " couponmonth===>" + couponmonth + " endtime==>" + endtime + " 数据在有效期外");
                            //有效期外
                            recstatus = "2"; //已失效
                        }
                        map.put("status", recstatus);
                        log.info(couponmonth + "表内有数据，update==>" + recstatus + " couponmonth==>" + couponmonth);
                        map.put("couponmonth", couponmonth);
                        map.put("id", id);
                        couponDao.upCouponRec2(map);
                    }
                    log.info("-------带美团券的产品循环遍历更新结束--------");
                }
            } else {//没有数据，直接添加
                log.info("=============表内无数据========" + couponmonth);
                /*查订购日志表数据*/
                map.put("flag", flag);
                Boolean add = false;
                String type = "0";
                if ("99144186".equals(spid)) {
                    type = "1";
                    map.put("searchmonth", couponmonth);
                    add = findLastmonthRec2(map, "1");
                } else {
                    add = findLastmonthRec2(map, "0");
                }
                log.info("查找订购日志表结果====flag==" + flag + " 是否添加===" + add + "   type===>" + type);
                if ("0".equals(type)) {
                    if ((flag != 0 && add) || flag == 0) {
                        recstatus = "0";//默认
                        if (flag != 0 && (endtime.getTime() > today.getTime())) {
                            recstatus = "0";
                        } else if (endtime.getTime() < today.getTime()) {
                            recstatus = "2";//已失效
                        }
                        String inserttime = map.get("inserttime").toString();
                        log.info("inserttime===>" + inserttime);
                        Date insert = sdf.parse(inserttime);
                        if (flag != 0) {
                            starttime = endtime_new.substring(0, 8);
                            starttime = starttime + "01";
                            inserttime = starttime + " 00:00:00";
                            insert = sdf.parse(inserttime);
                        }
                        map.put("inserttime", insert);
                        map.put("starttime", starttime);
                        map.put("endtime", endtime_new);
                        map.put("status", recstatus);
                        map.put("couponmonth", couponmonth);
                        log.info(couponmonth + "表内无数据，add==>" + recstatus + " starttime==>" + starttime + " endtime==>" + endtime_new);
                        couponDao.addCouponRec(map);
                        //添加完毕后将inserttime重置为string类型
                        map.put("inserttime", inserttime);
                    }
                } else {
                    if (add) {
                        recstatus = "0";//默认
                        if (flag != 0 && (endtime.getTime() > today.getTime())) {
                            recstatus = "0";
                        } else if (endtime.getTime() < today.getTime()) {
                            recstatus = "2";//已失效
                        }
                        String inserttime = map.get("inserttime").toString();
                        log.info("inserttime===>" + inserttime);
                        Date insert = sdf.parse(inserttime);
                        if (flag != 0) {
                            starttime = endtime_new.substring(0, 8);
                            //查找是否当月有订购的数据，赋值starttime（当月最晚的那条数据）
                            String theLastOrder = couponDao.getTheLastOrder(userid, spid, starttime.replaceAll("-", ""));
                            log.info(" starttime==>" + starttime + " endtime==>" + endtime_new);
                            log.info("----------thelastOrder---" + theLastOrder);
                            if (theLastOrder != null && !"".equals(theLastOrder)) {
                                starttime = theLastOrder;
                            } else {
                                starttime = starttime + "01";
                            }
                            inserttime = starttime + " 00:00:00";
                            insert = sdf.parse(inserttime);
                        }
                        map.put("inserttime", insert);
                        map.put("starttime", starttime);
                        map.put("endtime", endtime_new);
                        map.put("status", recstatus);
                        map.put("couponmonth", couponmonth);
                        log.info(couponmonth + "表内无数据，add==>" + recstatus + " starttime==>" + starttime + " endtime==>" + endtime_new);
                        couponDao.addCouponRec(map);
                        //是否需要发放美团券码
                        //1.2 是否需要生成美团券
                        String meituan = couponDao.meituanCheck(spid, starttime);
                        log.info("------------是否要生成美团券--------->" + meituan);
                        Boolean needmt = false;
                        if (meituan != null && !"".equals(meituan) && "1".equals(meituan)) {
                            needmt = true;
                        }
                        if (needmt) {//是否需要生成美团券
                            log.info("------开始生成美团券------");
                            map.put("couponid","202106221340000012");//99146186 美团券id
                            for (int i = 0; i < 6; i++) {
                                map.put("id", couponDao.getNo());//每次都重新生成一个新的id
                                couponDao.addMeiTuan(map);//添加数据到券码表
                            }
                            log.info("------------生成完成--------");
                        }
                        //添加完毕后将inserttime重置为string类型
                        map.put("inserttime", inserttime);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /*重新遍历数据查看是否有失效的数据，有则修改为失效*/
    public void judgeTime(List<HashMap> maps) throws Exception {
        log.info("================重新遍历数据start===================");
        if (maps != null && maps.size() > 0) {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String recstatus = "0";//默认0
            Date today = new Date();
            Date endtime = new Date();
            for (HashMap couponrec : maps) {
                //获取券码内的最后一天有效期
                recstatus = couponrec.get("STATUS") == null ? "" : couponrec.get("STATUS").toString();
                String userid = couponrec.get("USERID") == null ? "" : couponrec.get("USERID").toString();
                String couponmonth = couponrec.get("COUPONMONTH") == null ? "" : couponrec.get("COUPONMONTH").toString();
                String end = couponrec.get("ENDTIME") == null ? "" : couponrec.get("ENDTIME").toString() + " 23:59:59";
                if (!"".equals(end)) {
                    endtime = sdf.parse(end);
                }
                log.info("userid===>" + userid + " couponmonth===>" + couponmonth + " endtime==>" + endtime);
                if ((endtime.getTime() < today.getTime()) && "0".equals(recstatus)) {
                    log.info("userid===>" + userid + " couponmonth===>" + couponmonth + " endtime==>" + endtime + " 数据在有效期外");
                    //有效期外
                    recstatus = "2"; //已失效
                }
                couponrec.put("status", recstatus);
//                log.info(couponmonth+"表内有数据，update==>"+recstatus+" starttime==>"+starttime+" endtime==>"+endtime_new);
                log.info(couponmonth + "表内有数据，update==>" + recstatus + " couponmonth==>" + couponmonth);
                couponrec.put("couponmonth", couponmonth);
//                couponDao.upCouponRec3(couponrec);
                if(couponrec.get("ACTIVITYCODE")!=null && couponrec.get("ACTIVITYCODE").toString().indexOf("reflowActivity")!=-1){
//                if("reflowActivity".equals(couponrec.get("ACTIVITYCODE"))){
                    couponDao.upCouponRec_reflow(couponrec);
                }else {
                    if("telecomActivity".equals(couponrec.get("ACTIVITYCODE"))){
                        couponDao.upCouponRec_telecom(couponrec);
                    } else if ("cancelActivity".equals(couponrec.get("ACTIVITYCODE"))) {
                        couponDao.upCouponRec_cancel(couponrec);
                    } else if("youtuTwoActivity".equals(couponrec.get("ACTIVITYCODE"))){
                        couponDao.upCouponRec_youtu(couponrec);
                    }else {
                        couponDao.upCouponRec_new(couponrec);
                    }
                }
            }
        }
        log.info("================重新遍历数据end===================");
    }

    /**
     * 券码核销
     *
     * @param orderInfo
     */
    public void verify(OrderInfo orderInfo) throws Exception {
        String jsonParams = "";
        JSONArray jsonArray = new JSONArray();
        HashMap map = new HashMap();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            String id = orderInfo.getId();
            String userid = orderInfo.getUserid();
            String verifymonth = orderInfo.getVerifymonth();
            String activitycode = orderInfo.getActivitycode();
//            HashMap couponrec = couponDao.findCouponRec2(userid, id);//获取最新的一条数据
            //20220216修改 新表查询
            HashMap couponrec = null;
            //20220426修改，回流三级活动加入 与二级回流活动并行 且此时虎年开门红活动新增央视评产品
            if(activitycode.indexOf("reflowActivity")!=-1){
//            if("reflowActivity".equals(activitycode)){
                couponrec = couponDao.findCouponRec_reflow(userid, id);//获取最新的一条数据
            } else if ("telecomActivity".equals(activitycode)) {
                couponrec = couponDao.findCouponRec_telecom(userid, id);
            } else if ("cancelActivity".equals(activitycode)){
                couponrec = couponDao.findCouponRec_cancel(userid, id);//获取最新的一条数据
            } else if("youtuTwoActivity".equals(activitycode)){
                couponrec = couponDao.findCouponRec_youtu(userid,id);
            } else{
                couponrec = couponDao.findCouponRec_new(userid, id);//获取最新的一条数据
            }

            if (couponrec != null) {
                //券码表兑换状态 状态：0去兑换，1已兑换，2失效，3兑换失败，4兑换中，5作废
                String status = couponrec.get("STATUS") == null ? "" : couponrec.get("STATUS").toString();
                log2.info("userid==>" + userid + "券码表兑换状态status===>" + status);
                String couponmonth = couponrec.get("COUPONMONTH") == null ? "" : couponrec.get("COUPONMONTH").toString();
                //20220428 判断是否日期是否一致
                if(!couponmonth.equals(verifymonth) && activitycode.indexOf("reflowActivity")==-1){
                    log2.info("couponmonth===>" + couponmonth);
                    log2.info("verifymonth===>" + verifymonth);
                    throw new BussinessException("8007", "券码可核销月份与核销月份不一致！");
                }

                if (!"1".equals(status) ) {//如果不是已兑换状态，则可以更改核销结果
                    map.put("id", id);
                    map.put("verifymonth", verifymonth);
                    map.put("verifyres", orderInfo.getVerifyres());
//                    couponDao.verifyCoupon(map);
                    if(activitycode.indexOf("reflowActivity")!=-1){
//                    if("reflowActivity".equals(activitycode)){
                        couponDao.verifyCoupon_reflow(map);
                    }else if(couponmonth.equals(verifymonth)){
                        if("telecomActivity".equals(activitycode)){
                            couponDao.verifyCoupon_telecom(map);
                        } else if ("cancelActivity".equals(activitycode)){
                            couponDao.verifyCoupon_cancel(map);
                        }else if("youtuTwoActivity".equals(activitycode)){
                            couponDao.verifyCoupon_youtu(map);
                        }else {
                            couponDao.verifyCoupon_new(map);
                        }
                    }
                } else if ("1".equals(status)) {
                    throw new BussinessException("8006", "券码已兑换");
                }
            } else {
                throw new BussinessException("8005", "券码表中无数据");
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 验证访问限制，1分钟内同一业务只能办理一次
     *
     * @param orderInfo
     * @throws Exception
     */
    private void vistVali(OrderInfo orderInfo, int type) throws Exception {
        String[] params = new String[3];
        params[0] = orderInfo.getChannel();
        params[1] = orderInfo.getUserid();
        if (type == 0) {
            if (commonService.vistVali2(params, "couponQuery")) {
                throw new BussinessException("8001", "指定时间内重复请求");
            }
        } else {
            if (commonService.vistVali2(params, "couponverify")) {
                throw new BussinessException("8001", "指定时间内重复请求");
            }
        }
    }

    /**
     * 拼接签名信息 orderid+channel+timestamp
     *
     * @param
     * @return
     */
    public String getSign(OrderInfo orderInfo, int type) throws Exception {
        StringBuilder strb = new StringBuilder();
        String userid = orderInfo.getUserid();
        strb.append(userid);
        if (type == 1) {
            strb.append(orderInfo.getSpid());
        }
        strb.append(orderInfo.getChannel());
        strb.append(orderInfo.getTimestamp());
        return strb.toString();
    }

    /**
     * 签名验证
     *
     * @param
     * @throws Exception
     */
    public void signValidate(OrderInfo orderInfo, int type) throws Exception {
        String lcalsign = getSign(orderInfo, type);
        String channel = orderInfo.getChannel();
        lcalsign += channelDao.queryChannel(channel).getPassword();
        System.out.println("local-->" + lcalsign);
        lcalsign = MD5.MD5Encode(lcalsign);
        System.out.println("orderinfo==>" + orderInfo.getSignature());
        System.out.println("lcalsign===>" + lcalsign);
        if (!lcalsign.equals(orderInfo.getSignature())) {
            throw new BussinessException("10006", "签名校验失败");
        }
    }


    /**
     * 手机号码验证
     *
     * @param
     * @throws Exception
     */
    private void mobValidate(OrderInfo orderInfo) throws Exception {
        String userid = orderInfo.getUserid();
        if (StringUtils.isEmpty(userid)) {
            throw new BussinessException("10007", "手机号不能为空");
        }
        ChannelBean channelBean = channelDao.queryChannel(orderInfo.getChannel());
        try {
            userid = DesUtil.decode(userid, channelBean.getPassword());//解密
            if (isValid(userid) && userid.length() == 11) {
                orderInfo.setUserid(userid);//重新设置手机号码为源码
            } else {
                throw new BussinessException("10009", "手机号错误");
            }
        } catch (Exception e) {
            if (e instanceof BussinessException) {
                throw e;
            } else {
                throw new BussinessException("10008", "手机号加密错误");
            }
        }
    }

    private boolean isValid(String usermob) {
        if (usermob == null) {
            return false;
        }
        usermob = usermob.replaceAll("[\\s-]", "");

        return usermob.matches(".*(1\\d{10}).*");
    }

    public static String md5(String str) {
        try {
            MessageDigest alga = MessageDigest.getInstance("MD5");
            alga.update(str.getBytes());
            byte[] digesta = alga.digest();
            return byte2hex(digesta);
        } catch (Exception e) {
        }
        return "";
    }

    public static String byte2hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = Integer.toHexString(b[n] & 0xFF);
            if (stmp.length() == 1)
                hs = hs + "0" + stmp;
            else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }

    private String getMonthLastDay() {
        //设置时间格式
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        //获得实体类
        Calendar ca = Calendar.getInstance();
        //设置最后一天
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        //最后一天格式化
        String lastDay = format.format(ca.getTime());
        return lastDay;
    }

    private String getMonthLastDay(int x) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        //设置为指定日期
        c.setTime(new Date());
        //指定日期月份减去一
        c.add(Calendar.MONTH, -x);
        //指定日期月份减去一后的 最大天数
        c.set(Calendar.DATE, c.getActualMaximum(Calendar.DATE));
        //获取最终的时间
        Date lastDateOfPrevMonth = c.getTime();
        String lastday = sdf.format(lastDateOfPrevMonth);
        System.out.println("上月最后一天：" + lastday);
        return lastday;
    }

    private static String getMonthLastDay(String starttime) throws Exception {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar c = Calendar.getInstance();
        //设置为指定日期
        Date date = sdf.parse(starttime);
        c.setTime(date);
        c.set(Calendar.DATE, c.getActualMaximum(Calendar.DATE));
        //获取最终的时间
        Date lastDateOfPrevMonth = c.getTime();
        String lastday = sdf.format(lastDateOfPrevMonth);
        System.out.println("最后一天：" + lastday);
        return lastday;
    }

    private static String getNextMonth(String startmonth) throws Exception {
        String month = startmonth;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMM");//注意月份是MM
        Date date = simpleDateFormat.parse(month);
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);//设置起时间
        cal.add(Calendar.MONTH, 1);//增加一个月
        date = cal.getTime();
        month = simpleDateFormat.format(date);
        return month;
    }

    /**
     * json大写转小写
     *
     * @return JSONObject
     */
    public static JSONObject transToLowerObject(String json) {
        JSONObject JSONObject2 = new JSONObject();
        JSONObject JSONObject1 = JSON.parseObject(json);
        for (String key : JSONObject1.keySet()) {
            Object object = JSONObject1.get(key);
            if (object.getClass().toString().endsWith("JSONObject")) {
                JSONObject2.put(key.toLowerCase(), transToLowerObject(object.toString()));
            } else if (object.getClass().toString().endsWith("JSONArray")) {
                JSONObject2.put(key.toLowerCase(), transToArray(JSONObject1.getJSONArray(key).toString()));
            } else {
                JSONObject2.put(key.toLowerCase(), object);
            }
        }
        return JSONObject2;
    }

    /**
     * jsonArray转jsonArray
     *
     * @return JSONArray
     */
    public static JSONArray transToArray(String jsonArray) {
        JSONArray jSONArray2 = new JSONArray();
        com.alibaba.fastjson.JSONArray jSONArray1 = JSON.parseArray(jsonArray);
        for (int i = 0; i < jSONArray1.size(); i++) {
            Object jArray = jSONArray1.getJSONObject(i);
            if (jArray.getClass().toString().endsWith("JSONObject")) {
                jSONArray2.add(transToLowerObject(jArray.toString()));
            } else if (jArray.getClass().toString().endsWith("JSONArray")) {
                jSONArray2.add(transToArray(jArray.toString()));
            }
        }
        return jSONArray2;
    }

    public void dealProduct(HashMap map) {
        log.info("------------新逻辑处理开始----------");
        map.put("status", "0");
        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            //1.查订购日志表，找到最小的订购时间和退订时间
            String userid = map.get("userid").toString();
            String spid = map.get("spid").toString();
            String nowmonth = map.get("couponmonth").toString();
            log.info("当前查询月份是否在活动范围之间 在的话用当前月份 不在的话用活动的最后一个月份");
            HashMap active = couponDao.activeTimeCap(spid, nowmonth);
            if (active == null) {
                log.info("当前查询月份不在活动月中，则查询月份使用活动的最后一个月");
                String isunique = map.get("isunique")==null?"":map.get("isunique").toString();
                active = couponDao.activetime(spid,isunique);
                nowmonth = active.get("ENDTIME").toString().substring(0, 7).replaceAll("-", "");
            }
            log.info("查找是否表内已有三个月内的数据，有则不生成");
            List<String> hasThreeMonth = couponDao.getHasMonthCoupon(spid, userid);
            if (hasThreeMonth != null && hasThreeMonth.size() >= 3) {
                log.info("用户" + userid + "库表内已有三个月数据，不生成券码");
                log.info("------------新逻辑处理结束----------");
                return;
            }

            SimpleDateFormat sMonth = new SimpleDateFormat("yyyyMM");//注意月份是MM
            Date start = new Date();
            Date end = new Date();

            List<HashMap> earlyOrdertimeMaps = couponDao.getTheEarlyOrderTimeMaps(userid, spid);
            List<HashMap> earlyCanceltimeMaps = couponDao.getTheEarlyCancelTimeMaps(userid, spid);
            String earlyOrdertime = "";
            String earlyCanceltime = "";

//            String meituan = couponDao.meituanCheck(spid, "2021-09-01");
//            log.info("------------是否要生成美团券--------->" + meituan);
//            Boolean needmt = false;
//            if (meituan != null && !"".equals(meituan) && "1".equals(meituan)) {
//                needmt = true;
//            }
            //只有订购的情况 按照月份开始逐月生成
            if ((earlyOrdertimeMaps != null && earlyOrdertimeMaps.size() > 0) &&
                    (earlyCanceltimeMaps == null || earlyCanceltimeMaps.size() <= 0)) {
                log.info("日志表内只有订购的数据");
                //表内是否有数据 有数据则不动，找到当前有数据最晚的月份，然后查看和当前月份的差值，往下继续生成券码，无数据则开始逐月添加
                List<HashMap> recstatus_cap = couponDao.hasRec2(userid, spid);
                if (recstatus_cap != null && recstatus_cap.size() > 0) {
                    String hasCreateMonth = recstatus_cap.get(0).get("COUPONMONTH").toString();
                    start = sMonth.parse(hasCreateMonth);
                    end = sMonth.parse(nowmonth);
                    if (!nowmonth.equals(hasCreateMonth)) {
                        log.info("已经生成的月份和当前查询时的月份不一致，开始计算差值，往下继续生成券码");
                        log.info("查找是否表内已有三个月内的数据，有则不生成");
                        hasThreeMonth = couponDao.getHasMonthCoupon(spid, userid);
                        if (hasThreeMonth != null && hasThreeMonth.size() >= 3) {
                            log.info("用户" + userid + "库表内已有三个月数据，不生成券码");
                            log.info("------------新逻辑处理结束----------");
                            return;
                        }
                        earlyOrdertime = couponDao.getTheEarlyOrderTime(userid, spid);
                        if (hasRecAdd(map, hasCreateMonth, nowmonth, earlyOrdertime, start, end)) {
                            log.info("添加剩余券码已完成");
                        } else {
                            log.info("添加剩余券码失败");
                        }
                    } else {
                        log.info("已经生成的月份和当前查询时的月份一致，不进行处理");
                    }
                } else {
                    log.info("表内无数据，则直接开始循环生成券码，从订购时间开始的月份直到查询的月份");
                    earlyOrdertime = couponDao.getTheEarlyOrderTime(userid, spid);
                    String addMonth = earlyOrdertime.substring(0, 7).replaceAll("-", "");
                    start = sMonth.parse(addMonth);
                    end = sMonth.parse(nowmonth);
                    int flag = 0;
                    while (start.getTime() <= end.getTime()) {
                        log.info("--开始添加--" + addMonth);
                        log.info("查找是否表内已有三个月内的数据，有则不生成");
                        hasThreeMonth = couponDao.getHasMonthCoupon(spid, userid);
                        if (hasThreeMonth != null && hasThreeMonth.size() >= 3) {
                            log.info("用户" + userid + "库表内已有三个月数据，不生成券码");
                            log.info("------------新逻辑处理结束----------");
                            return;
                        }
                        map.put("id", couponDao.getNo());//每次都重新生成一个新的id
                        StringBuffer stringBuilder1 = new StringBuffer(addMonth);
                        stringBuilder1.insert(4, "-");
                        String starttime = stringBuilder1.toString() + "-01";//续订 有效期从此月的第一天开始
                        if (flag == 0) {
                            starttime = earlyOrdertime.substring(0, 10);
                        }
                        String endtime = getMonthLastDay(starttime);
                        map.put("starttime", starttime);
                        map.put("couponmonth", addMonth);
                        map.put("endtime", endtime);
                        String inserttime = map.get("starttime").toString() + " 00:00:00";
                        log.info("inserttime===>" + inserttime);
                        Date insert = sdf.parse(inserttime);
                        map.put("inserttime", insert);
                        couponDao.addCouponRec(map);//添加数据到券码表
                        log.info("---开始生成美团券--");
                        map.put("couponid","202106221340000012");//99146186 美团券id
                        for (int i = 0; i < 6; i++) {
                            map.put("id", couponDao.getNo());//每次都重新生成一个新的id
                            couponDao.addMeiTuan(map);//添加数据到券码表
                        }
                        log.info("--美团券生成完毕--");
                        addMonth = getNextMonth(addMonth);
                        start = sMonth.parse(addMonth);
                        flag++;
                    }
                    log.info("表内无数据，且只有订购状态的，添加剩余券码已完成");
                }
            } else if ((earlyOrdertimeMaps != null && earlyOrdertimeMaps.size() > 0) &&
                    (earlyCanceltimeMaps != null && earlyCanceltimeMaps.size() > 0)) {
                log.info("表内既有订购也有退订的数据，查看两者最早的时间进行比较");
                earlyOrdertime = couponDao.getTheEarlyOrderTime(userid, spid);
                earlyCanceltime = couponDao.getTheEarlyCancelTime(userid, spid);
                Date order = sdf.parse(earlyOrdertime);
                Date cancel = sdf.parse(earlyCanceltime);
                String addMonth = earlyOrdertime.substring(0, 7).replaceAll("-", "");
                String cancelMonth = earlyCanceltime.substring(0, 7).replaceAll("-", "");
                if (order.getTime() < cancel.getTime()) {
                    log.info("先订购再退订，则生成时间为从订购月开始一直到退订月");
                    log.info("订购月：" + addMonth + " 退订月:" + cancelMonth);
                    //表内是否有数据 有数据则不动，找到当前有数据最晚的月份，然后查看和当前月份的差值，往下继续生成券码，无数据则开始逐月添加
                    List<HashMap> recstatus_cap = couponDao.hasRec2(userid, spid);
                    if (recstatus_cap != null && recstatus_cap.size() > 0) {
                        String hasCreateMonth = recstatus_cap.get(0).get("COUPONMONTH").toString();
                        log.info("----已经生成的月份到--" + hasCreateMonth);
                        if (!cancelMonth.equals(hasCreateMonth)) {
                            log.info("已经生成的月份和当前查询时的月份不一致，开始计算差值，往下继续生成券码直到退订月");
                            log.info("查找是否表内已有三个月内的数据，有则不生成");
                            hasThreeMonth = couponDao.getHasMonthCoupon(spid, userid);
                            if (hasThreeMonth != null && hasThreeMonth.size() >= 3) {
                                log.info("用户" + userid + "库表内已有三个月数据，不生成券码");
                                log.info("------------新逻辑处理结束----------");
                                return;
                            }
                            start = sMonth.parse(hasCreateMonth);
                            end = sMonth.parse(cancelMonth);
                            if (hasRecAdd(map, hasCreateMonth, cancelMonth, earlyOrdertime, start, end)) {
                                log.info("添加剩余券码已完成");
                            } else {
                                log.info("添加剩余券码失败");
                            }
                        } else {
                            log.info("已经生成的月份和当前查询时的月份一致，不进行处理");
                        }
                    } else {
                        log.info("----表内无数据，直接开始添加--");
                        int flag = 0;
                        start = sMonth.parse(addMonth);
                        end = sMonth.parse(cancelMonth);
                        while (start.getTime() <= end.getTime()) {
                            log.info("--开始添加--" + addMonth);
                            log.info("查找是否表内已有三个月内的数据，有则不生成");
                            hasThreeMonth = couponDao.getHasMonthCoupon(spid, userid);
                            if (hasThreeMonth != null && hasThreeMonth.size() >= 3) {
                                log.info("用户" + userid + "库表内已有三个月数据，不生成券码");
                                log.info("------------新逻辑处理结束----------");
                                return;
                            }
                            map.put("id", couponDao.getNo());//每次都重新生成一个新的id
                            StringBuffer stringBuilder1 = new StringBuffer(addMonth);
                            stringBuilder1.insert(4, "-");
                            String starttime = stringBuilder1.toString() + "-01";//续订 有效期从此月的第一天开始
                            if (flag == 0) {
                                starttime = earlyOrdertime.substring(0, 10);
                            }
                            String endtime = getMonthLastDay(starttime);
                            map.put("starttime", starttime);
                            map.put("couponmonth", addMonth);
                            map.put("endtime", endtime);
                            String inserttime = map.get("starttime").toString() + " 00:00:00";
                            log.info("inserttime===>" + inserttime);
                            Date insert = sdf.parse(inserttime);
                            map.put("inserttime", insert);
                            couponDao.addCouponRec(map);//添加数据到券码表
                            log.info("---开始生成美团券--");
                            map.put("couponid","202106221340000012");//99146186 美团券id
                            for (int i = 0; i < 6; i++) {
                                map.put("id", couponDao.getNo());//每次都重新生成一个新的id
                                couponDao.addMeiTuan(map);//添加数据到券码表
                            }
                            log.info("--美团券生成完毕--");
                            addMonth = getNextMonth(addMonth);
                            start = sMonth.parse(addMonth);
                            flag++;
                        }
                        log.info("添加剩余券码已完成");
                    }
                } else {//先退订再订购
                    log.info("先退订再订购，则从最早的订购时间开始，逐月生成，直到下一个退订月份");
                    log.info("订购月：" + addMonth + " 退订月:" + cancelMonth);
                    HashMap nextCancel = null;
                    if (earlyCanceltimeMaps.size() >= 2) {
                        nextCancel = earlyCanceltimeMaps.get(1);
                    }
                    if (nextCancel != null) {
                        cancelMonth = nextCancel.get("INSERTTIME").toString().substring(0, 6);
                    } else {
                        cancelMonth = nowmonth;
                    }
                    List<HashMap> recstatus_cap = couponDao.hasRec2(userid, spid);
                    if (recstatus_cap != null && recstatus_cap.size() > 0) {
                        String hasCreateMonth = recstatus_cap.get(0).get("COUPONMONTH").toString();
                        log.info("----已经生成的月份到--" + hasCreateMonth);
                        if (!cancelMonth.equals(hasCreateMonth)) {
                            log.info("已经生成的月份和当前查询时的月份不一致，开始计算差值，往下继续生成券码直到退订月");
                            log.info("查找是否表内已有三个月内的数据，有则不生成");
                            hasThreeMonth = couponDao.getHasMonthCoupon(spid, userid);
                            if (hasThreeMonth != null && hasThreeMonth.size() >= 3) {
                                log.info("用户" + userid + "库表内已有三个月数据，不生成券码");
                                log.info("------------新逻辑处理结束----------");
                                return;
                            }
                            start = sMonth.parse(hasCreateMonth);
                            end = sMonth.parse(cancelMonth);
                            if (hasRecAdd(map, hasCreateMonth, cancelMonth, earlyOrdertime, start, end)) {
                                log.info("添加剩余券码已完成");
                            } else {
                                log.info("添加剩余券码失败");
                            }
                        } else {
                            log.info("已经生成的月份和当前查询时的月份一致，不进行处理");
                        }
                    } else {
                        log.info("----表内无数据，直接开始添加--");
                        int flag = 0;
                        start = sMonth.parse(addMonth);
                        end = sMonth.parse(cancelMonth);
                        while (start.getTime() <= end.getTime()) {
                            log.info("--开始添加--" + addMonth);
                            log.info("查找是否表内已有三个月内的数据，有则不生成");
                            hasThreeMonth = couponDao.getHasMonthCoupon(spid, userid);
                            if (hasThreeMonth != null && hasThreeMonth.size() >= 3) {
                                log.info("用户" + userid + "库表内已有三个月数据，不生成券码");
                                log.info("------------新逻辑处理结束----------");
                                return;
                            }
                            map.put("id", couponDao.getNo());//每次都重新生成一个新的id
                            StringBuffer stringBuilder1 = new StringBuffer(addMonth);
                            stringBuilder1.insert(4, "-");
                            String starttime = stringBuilder1.toString() + "-01";//续订 有效期从此月的第一天开始
                            if (flag == 0) {
                                starttime = earlyOrdertime.substring(0, 10);
                            }
                            String endtime = getMonthLastDay(starttime);
                            map.put("starttime", starttime);
                            map.put("couponmonth", addMonth);
                            map.put("endtime", endtime);
                            String inserttime = map.get("starttime").toString() + " 00:00:00";
                            log.info("inserttime===>" + inserttime);
                            Date insert = sdf.parse(inserttime);
                            map.put("inserttime", insert);
                            couponDao.addCouponRec(map);//添加数据到券码表
                            log.info("---开始生成美团券--");
                            map.put("couponid","202106221340000012");//99146186 美团券id
                            for (int i = 0; i < 6; i++) {
                                map.put("id", couponDao.getNo());//每次都重新生成一个新的id
                                couponDao.addMeiTuan(map);//添加数据到券码表
                            }
                            log.info("--美团券生成完毕--");
                            addMonth = getNextMonth(addMonth);
                            start = sMonth.parse(addMonth);
                            flag++;
                        }
                        log.info("添加剩余券码已完成");
                    }
                }
            } else { //只有退订的情况 不生成券码
                log.info("----日志表内只有退订的数据，则不生成券码");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("------------新逻辑处理结束----------");
    }

    public void dealProduct(HashMap map, String spid) throws Exception {
        log.info("------979产品处理----(注：只生成一张券）");
        String orderid = map.get("orderid").toString();
        String userid = map.get("userid").toString();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        //判断订购时间和订购渠道orderchannel2是否符合
        HashMap relations = couponDao.isAssignChanneldata(orderid, spid);
        if (relations != null && relations.size() > 0) {
            //将本月的券码的生效时间修改为订购时间
            log.info("订购时间和查询券码时间均在活动范围内，生成有效券码");
            String ordertime = relations.get("ORDERTIME") == null ? map.get("starttime").toString() : relations.get("ORDERTIME").toString();
            map.put("starttime", ordertime);
            map.put("endtime", getMonthLastDay(ordertime));
            map.put("inserttime", format.parse(ordertime));
            System.out.println(format.parse(ordertime));
            map.put("couponmonth", ordertime.substring(0, 7).replace("-", ""));
            map.put("status", "0");
            couponDao.addCouponRec(map);//添加数据到券码表
        }
    }

    public void dealProduct(HashMap map, String spid, String isUnique) throws Exception {
        //二次验证订购时间是否在可领券范围内
        //阿里产品
        // 7月15日以后（含当日）新增的订购用户没有退订，在8月发放券码
        //2） 8月新增的订购用户没有退订，在9月发放券码
        //新春活动
//        活动时间：
//        2021年12月15日 — 2022年2月28日 （只要在活动范围内已订购则立即发券，券码时间为你订购的时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMM");
        SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.info(">>>>>>>>>只生成一张券产品处理>>>>>>>");
        HashMap pro_map = couponDao.activetime(spid,isUnique);
        String pro_starttime = pro_map.get("STARTTIME") == null ? "" : pro_map.get("STARTTIME").toString();
        String now = sdf.format(new Date());//2021-07-11
        Date pro_start = sdf.parse(pro_starttime);//活动开始时间
        Date search_now = sdf.parse(now);//查询时间

        Calendar calendar_pro = Calendar.getInstance();
        calendar_pro.setTime(pro_start);
        Calendar calendar_now = Calendar.getInstance();
        calendar_now.setTime(search_now);

        String userid = map.get("userid").toString();
        String early_ordertime = null;//验证订购日志表是否可以生成券码
        String verifymonth;//精确到月
        String verifyend;//精确到日
        String date_verifystart;//精确到时分秒
        String date_verifyend;//精确到时分秒
        List<HashMap> map_uniques = null;
        log.info("spid==>"+spid+" isUnique=>"+isUnique);
        if ("2".equals(isUnique)) {
            //3 用户仅生成一张券，且即时生成，发券时间为订购时间 且查询月份=活动开始月份 即用户12月订购
            //1) 直接查日志表，活动范围内的第一条订购数据，生成此月券码，且不再发放
            early_ordertime = couponDao.secondverify_timely(userid, spid);
            if(early_ordertime!=null && !"".equals(early_ordertime)){
                Date insert = sdf3.parse(early_ordertime);
                log.info(">>>>>>一个用户只生成唯一代码，找到活动时间内最早订购时间，生成此月券码>>>>>>>");
                map.put("starttime", sdf.format(insert));
                map.put("endtime", getMonthLastDay(sdf.format(insert)));
                map.put("couponmonth", sdf2.format(insert));
                map.put("status", "0");
                map.put("inserttime", insert);
                couponDao.addCouponRec(map);//添加数据到券码表
            }
        } else if (!(now.substring(0, 7)).equals(pro_starttime.substring(0, 7)) && (search_now.getTime() > pro_start.getTime())) {
            //查询时间不是当前月且日期大于开始日期
            int currmonth = calendar_now.get(Calendar.MONTH) + 1;//当前月份
            int promonth = calendar_pro.get(Calendar.MONTH) + 1;//开始月份
            while (currmonth > promonth) {
                //逐步递减
                currmonth--;
                log.info("月份" + currmonth + "开始验证是否可以生成券码");
                verifymonth = now.substring(0, 5) + currmonth;
                String out_month = now.substring(0, 5) + (currmonth + 1);
                if (currmonth + 1 < 10) {
                    out_month = now.substring(0, 5) + "0" + (currmonth + 1);
                    verifymonth = now.substring(0, 5) + "0" + currmonth;
                }
                String coupon_end = getMonthLastDay(out_month + "-01");
                verifyend = getMonthLastDay(verifymonth + "-01");
                date_verifystart = verifymonth + "-01 00:00:01";
                date_verifyend = verifyend + " 23:59:59";
                if (pro_starttime.substring(0, 7).equals(verifymonth)) {
                    date_verifystart = pro_starttime + " 00:00:01";
                }
                log.info("----验证参数--" + verifymonth + "  start:" + date_verifystart + "  end:" + date_verifyend);
                map_uniques = couponDao.secondverify(userid, spid, verifymonth, date_verifystart, date_verifyend);
                HashMap map_unique = null;
                if (map_uniques != null && map_uniques.size() > 0) {
                    map_unique = map_uniques.get(0);//取第一条
                    log.info("status====>" + map_unique.get("STATUS"));
                }
                if (map_unique != null && "0".equals(map_unique.get("STATUS").toString())) {
                    //符合情况，生成券码，跳出循环
                    Date insert = new Date();
                    String inserttime = out_month + "-01 00:00:00";
                    insert = sdf.parse(inserttime);
                    log.info(">>>>>>一个用户只生成唯一代码，符合条件，生成券码>>>>>>>");
                    map.put("starttime", out_month + "-01");//验证月的下个月分
                    map.put("endtime", coupon_end);
                    map.put("couponmonth", out_month.replaceAll("-", ""));
                    map.put("status", "0");
                    map.put("inserttime", insert);
                    couponDao.addCouponRec(map);//添加数据到券码表
                    break;
                }
                log.info("月份" + currmonth + "结束验证");
            }
        }
    }

    public boolean hasRecAdd(HashMap map, String hasCreateMonth, String nowmonth, String earlyOrdertime, Date start, Date end) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Boolean res = false;
        SimpleDateFormat sMonth = new SimpleDateFormat("yyyyMM");//注意月份是MM
        log.info("----已经生成的月份到--" + hasCreateMonth);
        List<String> hasThreeMonth = new ArrayList<>();
        String userid = map.get("userid").toString();
        String spid = map.get("spid").toString();
        try {
            String addMonth = getNextMonth(hasCreateMonth);
            start = sMonth.parse(addMonth);
            int flag = 0;
            while (start.getTime() <= end.getTime()) {
                log.info("--开始添加--" + addMonth);
                log.info("库表内是否已有三个月数据 hasrecadd");
                hasThreeMonth = couponDao.getHasMonthCoupon(spid, userid);
                if (hasThreeMonth != null && hasThreeMonth.size() >= 3) {
                    log.info("用户" + userid + "库表内已有三个月数据，不生成券码");
                    break;
                }
                map.put("id", couponDao.getNo());//每次都重新生成一个新的id
                StringBuffer stringBuilder1 = new StringBuffer(addMonth);
                stringBuilder1.insert(4, "-");
                String starttime = stringBuilder1.toString() + "-01";//续订 有效期从此月的第一天开始
                String earlyOrderMonth = earlyOrdertime.replaceAll("-", "");
                if (flag == 0 && start.getTime() < end.getTime() && earlyOrderMonth.equals(addMonth)) {//flag=0，循环第一次（首次生成or已生成部分）start<end 不是本月 20211019添加是库表里未生成最早月份的数据
                    starttime = earlyOrdertime.substring(0, 10);
                }
                String endtime = getMonthLastDay(starttime);
                map.put("starttime", starttime);
                map.put("couponmonth", addMonth);
                map.put("endtime", endtime);
                String inserttime = map.get("starttime").toString() + " 00:00:00";
                log.info("inserttime===>" + inserttime);
                Date insert = sdf.parse(inserttime);
                map.put("inserttime", insert);
                couponDao.addCouponRec(map);//添加数据到券码表
                log.info("---开始生成美团券--");
                map.put("couponid","202106221340000012");//99146186 美团券id
                for (int i = 0; i < 6; i++) {
                    map.put("id", couponDao.getNo());//每次都重新生成一个新的id
                    couponDao.addMeiTuan(map);//添加数据到券码表
                }
                log.info("--美团券生成完毕--");
                addMonth = getNextMonth(addMonth);
                start = sMonth.parse(addMonth);
                flag++;
            }
            res = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }

    public static List deleteDuplicatedMapFromListByKeys(List<HashMap> originMapList,List keys){
        Map tempMap = new HashMap();
        int flag = 1;
        for (Map originMap : originMapList) {
            String objHashCode = "";
            for (Object key : keys) {
                String value = originMap.get(key) != null ? originMap.get(key).toString()  : "";
                objHashCode += value.hashCode();
            }
            if(originMap.get("SPID").toString().equals("99144186")){
                tempMap.put(flag,originMap);
                flag++;
            }else {
                tempMap.put(objHashCode, originMap);
            }
        }
        List<HashMap> valueList = new ArrayList<>(tempMap.values());
        return valueList;
    }
}

class MyComparator implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        // TODO Auto-generated method stub
        int result = 0;
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try {
            HashMap<String, String> map1 = (HashMap<String, String>) o1, map2 = (HashMap<String, String>) o2;
            Date map1_time = format.parse(map1.get("COUPONSTARTTIME"));
            Date map2_time = format.parse(map2.get("COUPONSTARTTIME"));
            if(map1_time.after(map2_time)){
                result = -1;
            }else if(map1_time.before(map2_time)){
                result = 1;
            }else if(map1_time.equals(map2_time)){
                result = 0;
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return result;
    }
}
