package com.bailuntec.job;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.bailuntec.domain.constant.CommonConstant;
import com.bailuntec.domain.entity.DcBaseSku;
import com.bailuntec.domain.entity.JobPointLog;
import com.bailuntec.domain.example.DcBaseSkuExample;
import com.bailuntec.domain.pojo.CommonSkuCondition;
import com.bailuntec.domain.pojo.CommonSkuProductInfo;
import com.bailuntec.domain.pojo.SkuData;
import com.bailuntec.mapper.DcBaseSkuMapper;
import com.bailuntec.mapper.DcBaseWarehouseMapper;
import com.bailuntec.mapper.JobPointLogMapper;
import com.bailuntec.utils.DigestUtils;
import com.bailuntec.utils.OkHttpUtil;
import com.bailuntec.utils.PropertiesUtil;
import com.bailuntec.utils.SessionUtil;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.util.LinkedHashMap;
import java.util.List;

@Slf4j
public class SkuJsonHandle {

    private static PropertiesUtil propertiesUtil = PropertiesUtil.getInstance("const");

    /**
     * 给SKUMS发请求, 请求需加密
     *
     * @param skuConditionDto
     * @return
     * @throws Exception
     */
    static void skuMSRequest(CommonSkuCondition skuConditionDto, JobPointLog jobPointLog) {
        OkHttpClient client = OkHttpUtil.getInstance();
        do {
            skuConditionDto.setPage(jobPointLog.getPageIndex() > 0 ? jobPointLog.getPageIndex() : 1);
            SkuData skuDataDto = new SkuData();
            skuDataDto.setCode(CommonConstant.OBJPRO_CODE);
            skuDataDto.setKey(CommonConstant.ALL_OBJPRO_KEY);
            String data = null;
            try {
                skuDataDto.setData(URLEncoder.encode(JSON.toJSONString(skuConditionDto), "utf8"));//将请求参数转为JSON 再Url编码
                data = URLEncoder.encode(JSON.toJSONString(skuDataDto), "utf8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                throw new RuntimeException("同步SKU信息JSON解析失败", e);
            }
            //第一次MD5加密
            String str = DigestUtils.md5DigestAsHex((CommonConstant.ALL_OBJPRO_KEY + skuDataDto.getData()).getBytes());
            //第二次MD5加密
            String sign = DigestUtils.md5DigestAsHex((CommonConstant.SKU_APPKEY + CommonConstant.OBJPRO_CODE + str).getBytes());
            //真正请求的参数
            LinkedHashMap<String, String> map = new LinkedHashMap<>(3);
            map.put("data", data);
            map.put("appId", CommonConstant.SKU_APPID);
            map.put("sign", sign);
            MediaType mediaType = MediaType.parse("application/json");
            RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(map));
            Response response = null;
            String skuStr = null;
            try {
                Request request = new Request.Builder()
                        .url(propertiesUtil.getPropertyAsString("SKU_URL"))
                        .post(body)
                        .addHeader("Content-Type", "application/json")
                        .build();
                response = client.newCall(request).execute();
                skuStr = response.body().string();
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException("调用同步SKU信息接口失败", e);
            } finally {
                if (response != null) {
                    response.close();
                }
            }
            if (StringUtils.isNotBlank(skuStr)) {
                JSONObject jsonNode = JSON.parseObject(skuStr);
                Integer resultCode = jsonNode.getIntValue("result_code");
                if (resultCode != null && resultCode == 1) {
                    String resultUrlSku = jsonNode.getString("data");
                    JSONObject jsonObject1 = null;
                    try {
                        jsonObject1 = JSON.parseObject(URLDecoder.decode(resultUrlSku, "utf8"));
                    } catch (UnsupportedEncodingException e) {
                        throw new RuntimeException("同步SKU信息JSON解URL编码失败", e);
                    }
                    //如果是0, 则保存总页数, 降序查
                    if (jobPointLog.getPageIndex().equals(0)) {
                        jobPointLog.setPageIndex(jsonObject1.getIntValue("TotalPages") + 1);
                    }
                    /*
                     * 转化JSON,
                     * 去处理SKU信息
                     */
                    List<CommonSkuProductInfo> allSkuProductInfoList = jsonObject1.getObject("Items", new TypeReference<List<CommonSkuProductInfo>>() {
                    });
                    if (allSkuProductInfoList != null && allSkuProductInfoList.size() > 0) {
                        handleSkuResultJSON(allSkuProductInfoList);
                    }
                } else {
                    throw new RuntimeException("调用同步SKU信息接口失败" + skuStr);
                }
            } else {
                throw new RuntimeException("调用同步SKU信息接口失败");
            }
            jobPointLog.setPageIndex(jobPointLog.getPageIndex() - 1);
            if (jobPointLog.getPageIndex() % 5 == 0) {
                try {
                    JobPointLogMapper jobPointLogMapper = SessionUtil.getSession().getMapper(JobPointLogMapper.class);
                    jobPointLogMapper.upsertSelective(jobPointLog);
                } catch (Exception e) {
                    throw new RuntimeException("MYBATIS操作DB失败", e);
                } finally {
                    SessionUtil.closeSession();
                }
            }
        } while (jobPointLog.getPageIndex() > 0);
        jobPointLog.setPageIndex(0);
        jobPointLog.setStartTime(jobPointLog.getEndTime());
        jobPointLog.setEndTime(jobPointLog.getEndTime().plusDays(jobPointLog.getIntervalTime()).isAfter(LocalDateTime.now()) ? LocalDateTime.now() : jobPointLog.getEndTime().plusDays(jobPointLog.getIntervalTime()));
    }

    static void handleSkuResultJSON(List<CommonSkuProductInfo> allSkuProductInfoList) {
        try {
            DcBaseSkuMapper dcBaseSkuMapper = SessionUtil.getSession().getMapper(DcBaseSkuMapper.class);
            for (CommonSkuProductInfo skuProductInfo : allSkuProductInfoList) {
                DcBaseSku dcBaseSku = new DcBaseSku();
                try {
                    BeanUtils.copyProperties(dcBaseSku, skuProductInfo);
                } catch (Exception e) {
                    throw new RuntimeException("BeanUtils.copyProperties失败");
                }
                if (StringUtils.isNotBlank(dcBaseSku.getWarehouseCode())) {
                    DcBaseWarehouseMapper dcBaseWarehouseMapper = SessionUtil.getSession().getMapper(DcBaseWarehouseMapper.class);
                    dcBaseSku.setWarehouseName(dcBaseWarehouseMapper.getWarehouseName(dcBaseSku.getWarehouseCode()));
                }
                String[] split = null;
                if (skuProductInfo.getPackingSize() != null) {
                    split = skuProductInfo.getPackingSize().split(",");
                }
                dcBaseSku.setBussinessId(dcBaseSku.getSellerId());
                dcBaseSku.setBussinessName(dcBaseSku.getSellerName());
                dcBaseSku.setLength((split != null && split.length > 0 && CommonConstant.NUMBER_AND_DECIMAL.matcher(split[0]).matches()) ? new BigDecimal(split[0]) : BigDecimal.ZERO);
                dcBaseSku.setWidth((split != null && split.length > 1 && CommonConstant.NUMBER_AND_DECIMAL.matcher(split[1]).matches()) ? new BigDecimal(split[1]) : BigDecimal.ZERO);
                dcBaseSku.setHeight((split != null && split.length > 2 && CommonConstant.NUMBER_AND_DECIMAL.matcher(split[2]).matches()) ? new BigDecimal(split[2]) : BigDecimal.ZERO);
                dcBaseSku.setWeight(skuProductInfo.getWeight() != null ? skuProductInfo.getWeight() : BigDecimal.ZERO.add(skuProductInfo.getPackingWeight() != null ? skuProductInfo.getPackingWeight() : BigDecimal.ZERO));
                dcBaseSku.setGmtModified(LocalDateTime.now());
                int i = dcBaseSkuMapper.updateByExampleSelective(dcBaseSku, DcBaseSkuExample.newAndCreateCriteria().andBailunSkuEqualTo(dcBaseSku.getBailunSku()).example());
                if (i == 0) {
                    dcBaseSkuMapper.insertSelective(dcBaseSku);
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("MYBATIS操作DB失败", e);
        } finally {
            SessionUtil.closeSession();
        }
    }


}
