import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.bailuntec.domain.constant.Constant;
import com.bailuntec.domain.entity.DcBaseStock;
import com.bailuntec.domain.entity.JobPointLog;
import com.bailuntec.domain.enumerate.PlatformType;
import com.bailuntec.domain.example.DcBaseWarehouseExample;
import com.bailuntec.domain.pojo.StockInfoData;
import com.bailuntec.domain.pojo.StockInfoPOJO;
import com.bailuntec.job.StockSyncJob;
import com.bailuntec.mapper.DcBaseWarehouseMapper;
import com.bailuntec.utils.OkHttpUtil;
import com.bailuntec.utils.PropertiesUtil;
import com.bailuntec.utils.SessionUtil;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.beanutils.BeanUtils;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*;

public class DailyStockTest {
//    @Test
    public void test() {
        String warehouseStr = null;
        int totalPage = 0;
        try {
            DcBaseWarehouseMapper baseWarehouseMapper = SessionUtil.getSession().getMapper(DcBaseWarehouseMapper.class);
            int countWarehouse = (int)baseWarehouseMapper.countByExample(DcBaseWarehouseExample.newAndCreateCriteria().andWarehouseExtendNameNotEqualTo("").andSystemFlagNotEqualTo(PlatformType.FBA.value()).example());
            if (countWarehouse % Constant.STOCKS_LIMIT > 0) {
                totalPage = countWarehouse / Constant.STOCKS_LIMIT + 1;
            } else {
                totalPage = countWarehouse / Constant.STOCKS_LIMIT;
            }
        } catch (Exception e) {
            throw new RuntimeException("Mybatis操作DB失败", e);
        } finally {
            SessionUtil.closeSession();
        }
        for (int i = 0; i < totalPage; i++) {
            try {
                DcBaseWarehouseMapper baseWarehouseMapper = SessionUtil.getSession().getMapper(DcBaseWarehouseMapper.class);
                warehouseStr = baseWarehouseMapper.getWarehouseCodeStr(i * Constant.STOCKS_LIMIT, Constant.STOCKS_LIMIT);
            } catch (Exception e) {
                throw new RuntimeException("Mybatis操作DB失败", e);
            } finally {
                SessionUtil.closeSession();
            }
        }
        StockSyncJob stockSyncJob = new StockSyncJob();
        JobPointLog pointJob = new JobPointLog("base-sync-stock",1, 10,1,1,LocalDateTime.now().minusDays(1), LocalDateTime.now());
        stockSyncJob.executeJob(null, pointJob);
    }

    private static final String secret = "SCGAPPSECRET5D7C969233948CE053FC4A50477C3FC02A4118A7";
    private static final String appKey = "BAILUN9BB992ED";
    private OkHttpClient client = OkHttpUtil.getInstance();
    private PropertiesUtil constPropertiesUtil = PropertiesUtil.getInstance("const");



    @Test
    public void executeJob() {
        HashMap<String, String> map = new HashMap<>(8);
        map.put("appKey", appKey);
        map.put("beginTime", "2019-01-18 00:00:00");
        map.put("pageSize", "2000");
        handleRealtimeInventory(map);
    }

    public void handleRealtimeInventory(HashMap<String, String> map) {
        for (int j = 0; j < 31; j++) {
            Integer code = null;
            Integer pageNo = 1;
            List<StockInfoPOJO> list = null;
            map.put("dbId", String.valueOf(j));
            Response response = null;
            do {
                map.put("LocalDateTime", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()));
                map.put("pageNo", pageNo.toString());
                map.put("stockCodes", "GZBLYS");
                map.put("sign", createSign(map));
                boolean forbbid = false;
                list = null;
                Request request = new Request.Builder()
                        .url(OkHttpUtil.attachHttpGetParams(constPropertiesUtil.getPropertyAsString("IIS_URL"), map))
                        .get()
                        .build();
                System.out.println(request.url());
                try {
                    response = client.newCall(request).execute();
                } catch (Exception e) {
                    throw new RuntimeException("调用环球IIS库存数据接口失败,响应404, 参数" + map);
                }
                if (response != null && response.isSuccessful() && response.body() != null) {
                    JSONObject jsonObject1 = null;
                    try {
                        jsonObject1 = JSON.parseObject(response.body().string());
                    } catch (IOException e) {
                        throw new RuntimeException("解析环球IIS库存JSON数据失败" + map, e);
                    } finally {
                        if (response != null) {
                            response.close();
                        }
                    }
                    code = jsonObject1.getIntValue("code");
                    if (code != null && code == 0) {
                        StockInfoData stockInfoData = jsonObject1.getObject("data", new TypeReference<StockInfoData>() {
                        });
                        list = stockInfoData.getList();
                        if (list != null && list.size() > 0) {
                            DcBaseStock dcBaseStock;
                            for (StockInfoPOJO stockInfoPOJO : list) {
                                dcBaseStock = new DcBaseStock();
                                try {
                                    BeanUtils.copyProperties(dcBaseStock, stockInfoPOJO);
                                } catch (IllegalAccessException e) {
                                    throw new RuntimeException("BeanUtils.copyProperties失败", e);
                                } catch (InvocationTargetException e) {
                                    throw new RuntimeException("BeanUtils.copyProperties失败", e);
                                }
                                if (stockInfoPOJO.getCreatedTime() != null) {
                                    dcBaseStock.setCreateTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(stockInfoPOJO.getCreatedTime().longValue()), ZoneId.systemDefault()));
                                }
                                if (stockInfoPOJO.getUpdatedTime() != null) {
                                    dcBaseStock.setUpdateTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(stockInfoPOJO.getUpdatedTime().longValue()), ZoneId.systemDefault()));
                                }
//                                try {
//                                    DcBaseStockMapper baseStockMapper = SessionUtil.getSession().getMapper(DcBaseStockMapper.class);
//                                    baseStockMapper.upsertSelective(dcBaseStock);
//                                    SessionUtil.getSession().commit();
//                                } catch (Exception e) {
//                                    e.printStackTrace();
//                                    throw new RuntimeException("Mybatis操作DB失败", e);
//                                } finally {
//                                    SessionUtil.closeSession();
//                                }
                            }
                        }
                    } else {//限流
                        forbbid = true;
                        try {
                            Thread.sleep(334);
                        } catch (InterruptedException e) {
                            throw new RuntimeException("线程休眠异常", e);
                        }
                    }
                }
                map.remove("sign");
                if (list != null && list.size() == 2000) {
                    pageNo++;
                } else if (forbbid) {
                    list = new ArrayList<>(1);
                    list.add(new StockInfoPOJO(0));
                    code = 0;
                    forbbid = false;
                } else {
                    list = null;
                }
            } while (code != null && code == 0 && list != null && list.size() > 0);
        }
    }
    /**
     * @Description :根据签名算法得出签名---参数按照参数名ASCII码从小到大排序（字典序）
     **/
    public String createSign(Map<String, String> parameters) {
        StringBuffer keyS = new StringBuffer();
        List<Map.Entry<String, String>> infoIds = new ArrayList<>(parameters.entrySet());
        // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
        Collections.sort(infoIds, new Comparator<Map.Entry<String, String>>() {
            public int compare(Map.Entry<String, String> o1, Map.Entry<String, String> o2) {
                return (o1.getKey()).compareTo(o2.getKey());
            }
        });
        // 构造签名键值对的格式
        for (Map.Entry<String, String> item : infoIds) {
            if (item.getKey() != null || item.getKey() != "") {
                String key = item.getKey();
                String val = item.getValue();
                if (!(val == "" || val == null)) {
                    keyS.append(key + val);
                }
            }
        }
        String md5Str = getMD5Str(keyS.toString() + secret);
        return md5Str;

    }

    public String getMD5Str(String str) {
        try {
            // 生成一个MD5加密计算摘要
            MessageDigest md = MessageDigest.getInstance("MD5");
            // 计算md5函数
            md.update(str.getBytes());
            // digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符
            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值
            return new BigInteger(1, md.digest()).toString(16);
        } catch (Exception e) {
            throw new RuntimeException("MD5加密出现错误，" + e.toString());
        }
    }
}
