package com.chinacreator.video.restful.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.chinacreator.video.bean.OrderInfo;
import com.chinacreator.video.exception.BussinessException;
import com.chinacreator.video.mapper.AqyDrawDao;
import com.chinacreator.video.mapper.ChannelDao;
import com.chinacreator.video.mapper.CommConfDao;
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.util.RedisService;
import com.chinacreator.video.util.SendSmsUtil;
import com.chinacreator.video.validate.*;
import com.sun.org.apache.bcel.internal.generic.IF_ACMPEQ;
import com.sun.org.apache.xpath.internal.operations.Or;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.jboss.logging.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 爱奇艺20元抽奖服务类
 *
 * @author yanzhengrong
 * @date 20201105
 */
@Component
public class AqyDrawService {

    @Autowired
    private ChannelValidate channelValidate;

    @Autowired
    private IpValidate ipValidate;

    @Autowired
    private MobValidate mobValidate;

    @Autowired
    private TimetampValidate timetampValidate;

    @Autowired
    private CommonService commonService;

    @Autowired
    private AqyDrawDao aqyDrawDao;

    @Autowired
    RedisService redisService;

    @Autowired
    private DictionaryDao dictionaryDao;

    @Autowired
    private ChannelDao channelDao;

    private static Logger logger = Logger.getLogger("aqydraw");

    public void busiCheck(OrderInfo orderInfo) throws Exception {

        //paramValidate.validate(orderInfo, null);

        //timetamp验证
        timetampValidate.validate(orderInfo.getTimestamp());
        //渠道验证
        channelValidate.validate(orderInfo.getChannel());
        //ip验证
        ipValidate.volidate(orderInfo);
        //签名验证
        signValidate(orderInfo);

        //手机号码验证
        mobValidate(orderInfo.getUserid());

        //并发访问控制
        vistVali(orderInfo);

        valiEndtime();//判断是否已经过时间或直接返回未中奖

        //订购状态有效验证
        orderRelationVali(orderInfo);

        //本月是否已经抽过奖
        hasDraw(orderInfo);
    }

    /*
     * 添加奖品
     * */
    public JSONArray getPrize(String spid) throws BussinessException {
        //String PPTVdraw_goodsinfo = "[{\"GOODSCODE\":\"GOODS1\",\"GOODSNAME\":\"爱奇艺VR眼镜\",\"GOODSSEQ\":\"3\",\"TOTALNUM\":\"20\",\"DAYNUM\":\"1\"},{\"GOODSCODE\":\"GOODS2\",\"GOODSNAME\":\"鼠标垫+马克杯+帆布包\",\"GOODSSEQ\":\"2,21,33,42\",\"TOTALNUM\":\"80\",\"DAYNUM\":\"4\"}]";
        //redisService.set("PPTVDRAW_GOODSINFO", PPTVdraw_goodsinfo);
//        System.out.println("++++++++++++++++++++++++++" + redisService.get("PPTVDRAW_GOODSINFO"));
        JSONArray jsonObjects;
//        if (redisService.get("PPTVDRAW_GOODSINFO") == null) {
//            //查数据库 并添加进redis
//            List<HashMap> temps = aqyDrawDao.getPrizeList();
//            if (temps != null && temps.size() > 0) {
//                Object tmpobj = JSON.toJSON(temps);
//                System.out.println(tmpobj.toString());
//                redisService.set("PPTVDRAW_GOODSINFO", tmpobj.toString());
//            }
//        }
//        Object goodsInfo = redisService.get("PPTVDRAW_GOODSINFO");
//        System.out.println(goodsInfo);
        List<HashMap> temps = aqyDrawDao.getPrizeList(spid);

        if(temps!=null && temps.size()>0) {
            jsonObjects=JSONArray.parseArray(JSON.toJSONString(temps));
//            for (HashMap map : temps) {
//                JSONObject paramsObj = new JSONObject();
//                paramsObj.put("GOODSNAME", map.get("GOODSNAME"));
//                paramsObj.put("GOODSSEQ", map.get("GOODSSEQ"));
//                paramsObj.put("DAYNUM", map.get("DAYNUM"));
//                paramsObj.put("GOODSCODE", map.get("GOODSCODE"));
//                paramsObj.put("TOTALNUM", map.get("TOTALNUM"));
//                jsonObjects.add(paramsObj);
//            }


//        if (PPTVdraw_goodsinfo != null) {
//            //String str = (String) redisService.get("PPTVDRAW_GOODSINFO");
//            String str = PPTVdraw_goodsinfo;
//            str = str.replace("[", "");
//            str = str.replace("]", "");
//            System.out.println(str);
//            String[] strings = str.split("},");
//            int flag = 0;
//            for (String s : strings) {
//                if (flag == 0) s += "}";
//                JSONObject paramsObj = JSONObject.fromObject(s);
//                jsonObjects.add(paramsObj);
//                flag++;
//            }
//        } else {
//            throw new BussinessException("8000", "无奖品配置信息！");
//        }

//        String str = (String) redisService.get("PPTVDRAW_GOODSINFO");
//        List<JSONObject> jsonObjects = new ArrayList<>();
//        str = str.replace("[", "");
//        str = str.replace("]", "");
//        System.out.println(str);
//        String[] strings = str.split("},");
//        int flag = 0;
//        for (String s : strings) {
//            if (flag == 0) s += "}";
//            JSONObject paramsObj = JSONObject.fromObject(s);
//            jsonObjects.add(paramsObj);
//            flag++;
//        }
            return jsonObjects;
        } else {
            throw new BussinessException("8000", "无奖品配置信息！");
        }
    }


    /**
     * 业务处理
     *
     * @param orderInfo
     */
    public HashMap busiOper(OrderInfo orderInfo) throws Exception {
        HashMap resMap = new HashMap();
        String resultcode = "0";
        String errorcode = "0";
        String errorinfo = "";
        String userid = orderInfo.getUserid();
        String prizename = "";//中奖名称
        String detail = "";//抽奖明细

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMM");//月份作为副key
        SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");
        SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMddHHmmss");
        Date d = new Date();
        String month = sdf.format(d);
        String day = sdf2.format(d);
        String now = sdf3.format(d);

        HashMap map = new HashMap();//抽奖记录map
        map.put("USERID", userid);
        map.put("PRIZEMONTH", month);
        map.put("SPID", orderInfo.getSpid());

        //添加抽奖记录表，看有没有抽奖记录（验证抽奖资格此时已通过验证，但此处仍需要添加）
        try {
            try {
                map.put("ID",aqyDrawDao.getNo());
                aqyDrawDao.addPrizeRec(map);//约束（month userid） 添加异常抛出无法抽奖
            } catch (Exception e) {
                throw new BussinessException("8004", "本月已抽奖！");
            }
            SimpleDateFormat sdfd = new SimpleDateFormat("yyyyMM");//月份作为副key
            Date ds = new Date();
            String monthd = sdf.format(ds);
            //查询中奖表
            HashMap map1 = aqyDrawDao.hasDrawPrizelist(orderInfo.getUserid(), monthd);
            if (map1 != null && map1.size() > 0) {//无中奖信息
                throw new BussinessException("8005", "未中奖！");
            }
            //valiDraw();
            /*查看是否在有奖品期间*/
            //NoWindate();

            //添加成功记录抽奖序号
            Long user_seq = redisService.hincr("PPTVDRAW_SEQ", day, 1);//redis 序列号增加1 不存在则默认添加

            //获取奖品信息
            JSONArray prizelist = getPrize("1167");
            int day_max = 0;
            int totalMax=0;
            for (int i=0;i<prizelist.size();i++){
                com.alibaba.fastjson.JSONObject jsonObject=prizelist.getJSONObject(i);
                int day_limit = Integer.parseInt(jsonObject.getString("DAYNUM"));
                day_max += day_limit;
                int totalLimit = Integer.parseInt(jsonObject.getString("TOTALNUM"));
                totalMax += totalLimit;
            }

//            for (JSONObject jsonObject : prizelist) {
//                int day_limit = Integer.parseInt(jsonObject.getString("DAYNUM"));
//                day_max += day_limit;
//            }

            //开始抽奖
            //1.查询是否抽奖号码与中奖号码一致
            for (int i=0;i<prizelist.size();i++){
                com.alibaba.fastjson.JSONObject jsonObject=prizelist.getJSONObject(i);
                String drawtime = jsonObject.getString("DRAWTIME");
                if (StringUtils.isNotEmpty(drawtime)){
                    String[] split = drawtime.split("-");
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
                    String format = simpleDateFormat.format(new Date());
                    if (Integer.parseInt(format)<Integer.parseInt(split[0])||Integer.parseInt(format)>Integer.parseInt(split[1])){
                          continue;
                    }
                }
                String prizeseq =  jsonObject.getString("GOODSSEQ");
                int totalLimit = Integer.parseInt(jsonObject.getString("TOTALNUM"));
                System.out.println("PRIZESEQ===>"+prizeseq);
                 String  goodsCode =  jsonObject.getString("GOODSCODE");
                Long cnt =redisService.hincr("TOTAL_GIFT_" + month, goodsCode,1);
                if (cnt<=totalLimit){
                    if(prizeseq.indexOf(",")>-1){
                        String[] strings = prizeseq.split(",");
                        for(String s:strings){
                            if(s.equals(user_seq+"")){
                                resultcode =  jsonObject.getString("GOODSCODE");
                                prizename =   jsonObject.getString("GOODSNAME");
                            }
                        }
                    }else if(prizeseq.equals(user_seq+"")){
                        resultcode =  jsonObject.getString("GOODSCODE");
                        prizename = jsonObject.getString("GOODSNAME");
                    }
                }
                redisService.hincr("TOTAL_GIFT_" + month, goodsCode,-1);
            }

            //中奖
            // 查询当天库存
            if (!"0".equals(resultcode)) {//中奖
                //是否当天中奖个数已达最大数值
                Object obj = redisService.hincr("PPTVDRAW_REC", day, 1);
                if (obj != null && Integer.parseInt(obj + "") > day_max) {
                    throw new BussinessException("80061", "当日奖品已抽完");
                }
                Long total = redisService.hincr("PPTVDRAW_STOCK", month, 1);
                if (total!=null&&total>totalMax){
                    throw new BussinessException("80061", "活动奖品已抽完");
                }
//                //查询库存
//                String daystock =  (String)redisService.hmGet("PPTVDRAW_STOCK", day);
//                try {
//                    int day_stock = Integer.parseInt(daystock);//获取当天库存
//                    System.out.println(day_stock);
//                    if (day_stock > 0) {
//                        Long stock = redisService.hincr("PPTVDRAW_STOCK", day, -1);//库存减1 //获取stock
//                    } else {
//                        throw new BussinessException("8006", "当日奖品已抽完（无库存）");
//                    }
//                }catch (Exception e){
//                    throw new BussinessException("8009", "未配置库存！");
//                }

                //查询中奖表是否已有数据
                Long inPrize = redisService.hincr("PPTVDRAW_MOHTH_" + month, userid, 1);
                if (inPrize == 1) {//无数据，添加到库表中奖表中和中奖明细表
                    //抽奖时间#抽奖序号#奖品编号#奖品名称
                    HashMap prizemap = new HashMap();//中奖map 保存到中奖表
                    prizemap.put("userid", userid);
                    prizemap.put("userseq", user_seq);
                    prizemap.put("prizeid", resultcode);
                    prizemap.put("prizename", prizename);
                    prizemap.put("prizemonth", month);
                    prizemap.put("prizesec", user_seq);
                    try {
                        aqyDrawDao.addPrize(prizemap);//添加到中奖表
                        detail = now + "#" + user_seq + "#" + resultcode + "#" + prizename;
                        System.out.println("8019----------->"+detail);
                        redisService.hmSet("PPTVDRAW_DAY_" + day, userid, detail);//添加到中奖明细表中
                        redisService.hincr("TOTAL_GIFT_"+month,resultcode,1);
/*                        try {
                            SendSmsUtil.send(userid,"【中国联通】"+userid+"手机用户，恭喜你！成功参与PP体育定向流量会员包“初春享0元，购后大抽奖”活动，并抽中足球通年卡一张，价值518元/张，活动结束后，我们将统一充值到您订购的手机号码中。感谢您的参与。");
                        } catch (Exception e) {
                            e.printStackTrace();
                            SendSmsUtil.send(userid,"【中国联通】"+userid+"手机用户，恭喜你！成功参与PP体育定向流量会员包“初春享0元，购后大抽奖”活动，并抽中足球通年卡一张，价值518元/张，活动结束后，我们将统一充值到您订购的手机号码中。感谢您的参与。");
                        }*/
                    }catch (Exception e){
                        e.printStackTrace();
                        errorinfo = e.getMessage();
                        redisService.hincr("PPTVDRAW_MOHTH_" + month, userid, -1);
                        redisService.hincr("PPTVDRAW_STOCK", month, -1);//总抽奖次数
                        redisService.hincr("PPTVDRAW_REC", day, -1);//当天中奖次数回退
                        redisService.hincr("TOTAL_GIFT_"+month,resultcode,-1); //中奖礼物减1
                        throw new BussinessException("8019", "添加到TD_AQYDRAW_PRIZELIST库失败");
                    }
                } else {//表中已有数据，回退redis，该用户无法抽奖
                    redisService.hincr("PPTVDRAW_MOHTH_" + month, userid, -1);
                    redisService.hincr("PPTVDRAW_STOCK", month, -1);//总抽奖次数
                    redisService.hincr("PPTVDRAW_REC", day, -1);//当天中奖次数回退
                    redisService.hincr("TOTAL_GIFT_"+month,resultcode,-1);//中奖礼物减1
                    throw new BussinessException("8004 ", "用户本月已抽过奖（redis中奖表已有信息）");
                }
            }else{
                detail = "未中奖";
            }

        } catch (Exception e) {
            e.printStackTrace();
            if (e instanceof BussinessException) {
                errorcode = ((BussinessException) e).getCode();
                errorinfo = ((BussinessException) e).getMessage();
            } else {
                errorcode = "8000";
                errorinfo = "出现异常，" + e.getMessage();
            }
            detail = errorcode + "  " + errorinfo;
            throw e;
        } finally {
            //更新可抽奖用户的抽奖记录
            if (!("8004").equals(errorcode)) {
                map.put("DETAIL", detail);
                try {
                    aqyDrawDao.updatePrizeRec(map);
                }catch (Exception e){
                    logger.info(e.getMessage());
                }
            }
            logger.info(userid +"===="+ detail);
        }



        resMap.put("resultcode", resultcode);
        resMap.put("detail", detail);

        return resMap;
    }

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

    /**
     * 订购状态认证 0已订购1已退订2已失效
     *
     * @param orderInfo
     * @throws Exception
     */
    public void orderRelationVali(OrderInfo orderInfo) throws Exception {
/*        HashMap map = commonService.getOrderStatus(orderInfo.getUserid(), orderInfo.getSpid());
        String status = map.get("ORDERSTATUS").toString();
        String orderTime = String.valueOf(map.get("orderTime"));
        if (!"0".equals(status)) {
            throw new BussinessException("8002", "未订购指定产品，无抽奖资格");
        }else {
            String orderTimeActive = dictionaryDao.getValue("pptvOrderTimeActive");
            String[] split = orderTimeActive.split("\\|");
            String startTime=split[0];
            String endTime=split[1];
            if (Long.parseLong(orderTime)<Long.parseLong(startTime)||Long.parseLong(orderTime)>Long.parseLong(endTime)){
                throw new BussinessException("8002","不在指定时间订购,无抽奖资格");
            }
        }*/
           int count= aqyDrawDao.isActive(orderInfo.getUserid(),orderInfo.getSpid());
           if (count<1){
               throw new BussinessException("8002", "未订购指定产品，无抽奖资格");
           }

    }

    /*
     *本月是否已经抽过奖 （每月只可抽奖一次）
     * */
    public void hasDraw(OrderInfo orderInfo) throws Exception {
        HashMap map = aqyDrawDao.hasDraw(orderInfo.getUserid(),orderInfo.getSpid());
        if (map != null && map.size() > 0) {
            throw new BussinessException("8003", "本月已抽过奖！无法再次抽奖");
        }
    }

    /**
     * 判断活动是否已结束或该时间内未中奖
     *
     * @throws Exception
     */
    private void valiEndtime() throws Exception {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmmss");
        String currtime = dateformat.format(new Date());
        String aqy20drawendtime = dictionaryDao.getValue("aqy20drawendtime");
        String[] split = aqy20drawendtime.split("\\|");
        logger.info(split);
        String startTime= split[0];
        String endTime =   split[1];
        if (Long.parseLong(currtime) < Long.parseLong(startTime)) {
            throw new BussinessException("9028", "活动暂未开始");
        }
        if (Long.parseLong(currtime) > Long.parseLong(endTime)) {
            throw new BussinessException("9028", "活动已经结束");
        }
    }

    public void valiDraw() throws BussinessException {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmmss");
        String currtime = dateformat.format(new Date());
        String aqy20drawendtime = dictionaryDao.getValue("aqy20drawendtime");
        String[] split = aqy20drawendtime.split("\\|");
        logger.info(split);
        String drawTiem =   split[2];
        if (Long.parseLong(currtime) >= Long.parseLong(drawTiem)) {
            String cur = new SimpleDateFormat("yyyyMMdd").format(new Date());
            if (Integer.parseInt(cur)%2!=0){
                throw new BussinessException("80061", "未中奖");
            }
        }
    }

    private void NoWindate() throws BussinessException {
        SimpleDateFormat dateformat = new SimpleDateFormat("yyyyMMddHHmmss");
        String currtime = dateformat.format(new Date());
        //到11月20号，21号到30开始的全部不中奖
        //String limitstart =
        //数据库配置 不中奖时间 202011.21-30 202012.1-10/
        String datelimit = dictionaryDao.getValue("aqy20drawlimitdate");
        String[] split = datelimit.split(",");

        for (String s1 : split) {
            String datestart = s1.substring(0, s1.lastIndexOf("-"));
            String datetend = s1.substring(s1.lastIndexOf("-") + 1);
            if (s1.indexOf("-") != -1) {
                if (Long.parseLong(currtime) >= Long.parseLong(datestart) && Long.parseLong(currtime) <= Long.parseLong(datetend)) {
                    throw new BussinessException("8005", "未中奖！");
                }
            }
        }
    }

    /**
     * 签名验证
     *
     * @param
     * @throws Exception
     */
    public void signValidate(OrderInfo orderInfo) throws Exception {
        String lcalsign = getSign(orderInfo);
        lcalsign += channelDao.queryChannel("aqy20active").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", "签名校验失败");
        }
    }

    /**
     * 拼接签名信息 orderid+channel+timestamp
     *
     * @param
     * @return
     */
    public String getSign(OrderInfo orderInfo) throws Exception {
        StringBuilder strb = new StringBuilder();
        String pwd = channelDao.queryChannel("aqy20active").getPassword();
        String userid = DesUtil.encode(orderInfo.getUserid(), pwd);
        strb.append(userid);
        strb.append(orderInfo.getChannel());
        strb.append(orderInfo.getTimestamp());
        return strb.toString();
    }

    /**
     * 手机号码验证
     *
     * @param usermob
     * @throws Exception
     */
    private void mobValidate(String usermob) throws Exception {
        boolean res = false;
        if (usermob != null && usermob.length() == 11) {
            usermob = usermob.replaceAll("[\\s-]", "");
            res = usermob.matches(".*(1\\d{10}).*");
        }
        if (res == false) {
            throw new BussinessException("9022", "手机号码不合法");
        }
    }


    public static void main(String[] args) {
/*        String PPTVdraw_goodsinfo  = "[{\"GOODSCODE\":\"GOODS1\",\"GOODSNAME\":\"爱奇艺VR眼镜\",\"GOODSSEQ\":\"3\",\"TOTALNUM\":\"20\",\"DAYNUM\":\"1\"},{\"GOODSCODE\":\"GOODS2\",\"GOODSNAME\":\"鼠标垫+马克杯+帆布包\",\"GOODSSEQ\":\"2,21,33,42\",\"TOTALNUM\":\"80\",\"DAYNUM\":\"4\"}]";
        if (PPTVdraw_goodsinfo != null) {
            //String str = (String) redisService.get("PPTVDRAW_GOODSINFO");
            String str = PPTVdraw_goodsinfo;
            str = str.replace("[", "");
            str = str.replace("]", "");
            System.out.println(str);
            String[] strings = str.split("},");
            int flag = 0;
            for (String s : strings) {
                if (flag == 0) s += "}";
                JSONObject paramsObj = JSONObject.fromObject(s);
                //jsonObjects.add(paramsObj);
                flag++;
            }
        } else {
            System.out.println("1");
        }*/
    }
}
