package com.chinacreator.process.job;


import com.alibaba.fastjson.JSON;
import com.chinacreator.common.util.MD5;
import com.chinacreator.common.util.URLUtil;
import com.chinacreator.process.dao.HuaweiWalletOrderDao;
import com.chinacreator.process.util.DesUtil;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.PersistJobDataAfterExecution;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;

import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.*;

@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class HuaweiWalletOrderJob {

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

    @Autowired
    private HuaweiWalletOrderDao huaweiWalletOrderDao;

    /**
     * 华为钱包订购
     * @throws Exception
     */
    @Scheduled(cron = "0/10 * * * * *")
    public void doProcess() throws Exception{
        logger.info("开始处理华为钱包订购订单job");
        try {
            //获取表中需要订购的数据
            List<HashMap> dataList = huaweiWalletOrderDao.queryList();
            logger.info("获取数据条数" + dataList.size());
            if (dataList != null && dataList.size() > 0) {
                dataList = paraseData(dataList); //去重复数据
                logger.info("去重复后用户数：" + dataList.size());
                CountDownLatch threadSignal = new CountDownLatch(dataList.size());
                ExecutorService executorService = new ThreadPoolExecutor(10, 20, 10L, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>(), new ThreadPoolExecutor.CallerRunsPolicy());


                for (HashMap<String, String> data : dataList) {
                    huaweiWalletOrderDao.updataQueryList(data.get("ID"), "0");
                }
                for (HashMap<String, String> data : dataList) {
                    HuaweiWalletOrderService continueService = new HuaweiWalletOrderService(dataList.size(), threadSignal, data, huaweiWalletOrderDao);
                    executorService.execute(continueService);
                }
                executorService.shutdown();
                try {
                    executorService.awaitTermination(5L, TimeUnit.MINUTES);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            Thread.sleep(100);


            //获取执行状态为0且执行时间超过2分钟的数据为待处理
            List<HashMap> queryListlong = huaweiWalletOrderDao.getQueryListlong();
            for (HashMap<String,String> map:queryListlong ){
                //查订购关系表是否已有订购关系
                String count = huaweiWalletOrderDao.queryOrder(map.get("USERID"),map.get("SPID"));
                logger.info("count"+count);
                if ("0".equals(count)){
                    huaweiWalletOrderDao.updataQueryNotifydata(map.get("ID"), "2","超时");
                }else {
                    huaweiWalletOrderDao.updataQueryNotifydata(map.get("ID"), "1","超时");
                }
            }

            if (queryListlong.size() > 0) {
                logger.info("更新状态为0处理中且执行时间超过2分钟的数据为待处理的异常数据条数【" + queryListlong.size() + "】");
            }
        }catch (Exception ee){
            ee.printStackTrace();
            logger.info("华为钱包订购订单jo执行出现异常，"+ee.getMessage());
        }
        logger.info("结束华为钱包订购订单job");
    }

    /**
     * 按手机号码与spid去除重复数据，确保获取的同一组数据里手机号码与spid不相同，防止同一手机号码订购同一产品并发而造成处理异常
     * @param dataList
     * @return
     */
    private List<HashMap> paraseData(List<HashMap> dataList){
        //去重复后的数据集
        List<HashMap> reDataList = new ArrayList<HashMap>();
        HashMap<Object, Object> tmpMap = new HashMap<Object, Object>();
        for (HashMap dataMap : dataList) {
            if(tmpMap.containsKey(dataMap.get("USERID").toString()+dataMap.get("SPID").toString())){
                logger.info("重复数据，"+dataMap);
            }else{
                tmpMap.put(dataMap.get("USERID").toString()+dataMap.get("SPID").toString(), dataMap);
                reDataList.add(dataMap);
            }
        }
        return reDataList;
    }

}

/**
 * 处理类
 * @author xinlong.liu
 * @date 20220721
 */
class HuaweiWalletOrderService implements Runnable {

    private static Logger logger = Logger.getLogger("HuaweiWalletOrder");
    private int totalSize;
    private CountDownLatch threadSignal;
    private HuaweiWalletOrderDao huaweiWalletOrderDao;
    private HashMap<String,String> data; //订购数据

    public HuaweiWalletOrderService(int totalSize,CountDownLatch threadSignal,HashMap<String,String> data,HuaweiWalletOrderDao huaweiWalletOrderDao){
        this.totalSize = totalSize;
        this.threadSignal = threadSignal;
        this.data = data;
        this.huaweiWalletOrderDao = huaweiWalletOrderDao;
    }

    @Override
    public void run() {
        String result = null;
        String status = "2";
        HashMap<String,Object> logmap = new HashMap<String, Object>();
        //组件订购参数
        logmap.put("data",data);
        String cpid = data.get("CPID");
        String spid = data.get("SPID");
        String channel = data.get("CHANNEL");
        String type = data.get("TYPE");
        String userid = data.get("USERID");
        String token = data.get("TOKEN");
        String access = "1";
        String timestamp = Long.toString(System.currentTimeMillis()/1000);
        try{
        String pwd = huaweiWalletOrderDao.getPwd(cpid);
        String signStr  = cpid+spid+userid+type+channel+timestamp+pwd;
        String signature = MD5.MD5Encode(signStr);
//                    String url = "http://10.0.17.151:6060/videoif/order.do";
            String url = huaweiWalletOrderDao.getValue("commonOrderUrl");
            String urlStr = url+"order.do?userid="+ URLEncoder.encode(DesUtil.encode(userid, pwd), "UTF-8")+"&cpid="+cpid+"&token="+token+"&spid="+spid+"&channel="+channel+"&apptype=2";;
            logmap.put("url",urlStr);
            result = URLUtil.get(urlStr,60000);
            logmap.put("result",result);
            JSONObject obj = JSONObject.fromObject(result);
            if("0".equals(obj.getString("resultcode"))){
                status = "1";
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.info("调videoif订购接口出错，"+"userid: "+userid+",cpid: "+cpid+",spid: "+spid+"错误信息: "+e);
        }finally {
            try {
                huaweiWalletOrderDao.updataQueryNotifydata(data.get("ID"),status,result);
            } catch (Exception throwables) {
                throwables.printStackTrace();
                logger.info("订购结果入库失败"+throwables.getMessage());
            }
            logger.info(JSON.toJSONString(logmap));
        }
    }

}
