package com.bailuntec.job;

import com.alibaba.fastjson.JSON;
import com.bailuntec.domain.entity.DcBaseCostFirst;
import com.bailuntec.domain.entity.DcBaseSku;
import com.bailuntec.domain.entity.JobPointLog;
import com.bailuntec.domain.example.DcBaseCostFirstExample;
import com.bailuntec.domain.example.DcBaseSkuExample;
import com.bailuntec.domain.pojo.CostFirstData;
import com.bailuntec.domain.pojo.CostFirstResult;
import com.bailuntec.domain.pojo.CostFirstSku;
import com.bailuntec.mapper.DcBaseCostFirstMapper;
import com.bailuntec.mapper.DcBaseSkuMapper;
import com.bailuntec.mapper.JobPointLogMapper;
import com.bailuntec.support.PointJob;
import com.bailuntec.utils.OkHttpUtil;
import com.bailuntec.utils.PropertiesUtil;
import com.bailuntec.utils.SessionUtil;
import com.dangdang.ddframe.job.api.ShardingContext;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;

public class SyncCostFirstJob extends PointJob {
    private PropertiesUtil propertiesUtil = PropertiesUtil.getInstance("const");

    @Override
    public void executeJob(ShardingContext shardingContext, JobPointLog jobPointLog) {
        OkHttpClient client = OkHttpUtil.getInstance();
        HashMap<String, String> map = new HashMap<>();
        map.put("startTime",jobPointLog.getStartTime().minusMinutes(3).format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        map.put("endTime",jobPointLog.getEndTime().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        Integer totalPage = 0;
         do {
             map.put("currentPage",jobPointLog.getPageIndex().toString());
             Request request = new Request.Builder()
                     .url(OkHttpUtil.attachHttpGetParams(propertiesUtil.getPropertyAsString("COST_FIRST_URL"),map))
                     .get()
                     .addHeader("Content-Type", "application/json")
                     .addHeader("cache-control", "no-cache")
                     .build();
             Response response = null;
             String result;
             try {
                 response = client.newCall(request).execute();
                 result = response.body().string();
             } catch (IOException e) {
                 e.printStackTrace();
                 throw new RuntimeException("调用头程费接口失败", e);
             } finally {
                 if (response != null) {
                    response.close();
                 }
             }
            if (StringUtils.isNotBlank(result)) {
                CostFirstResult costFirstResult = JSON.parseObject(result, CostFirstResult.class);
                totalPage = costFirstResult.getPageCount();
                if (costFirstResult.getData() !=null && costFirstResult.getData().size() > 0) {
                    handleCostFirstData(costFirstResult.getData());
                }
            } else {
                throw new RuntimeException("调用头程费接口失败,返回200");
            }
            jobPointLog.setPageIndex(jobPointLog.getPageIndex() + 1);
            if (jobPointLog.getPageIndex() % 8 == 0) {
                JobPointLogMapper mapper = SessionUtil.getSession().getMapper(JobPointLogMapper.class);
                mapper.upsertSelective(jobPointLog);
            }
         } while (jobPointLog.getPageIndex() <= totalPage);
        jobPointLog.setPageIndex(1);
        jobPointLog.setStartTime(jobPointLog.getEndTime());
        jobPointLog.setEndTime(jobPointLog.getStartTime().plusDays(jobPointLog.getIntervalTime().longValue()).isAfter(LocalDateTime.now()) ? LocalDateTime.now() : jobPointLog.getStartTime().plusDays(jobPointLog.getIntervalTime().longValue()));
    }

    private void handleCostFirstData(List<CostFirstData> costFirstDataList) {
        for (CostFirstData costFirstData : costFirstDataList) {
            DcBaseCostFirst dcBaseCostFirst = new DcBaseCostFirst();
            dcBaseCostFirst.setBoxId(costFirstData.getBoxId());
            dcBaseCostFirst.setChannelId(costFirstData.getChannelId());
            dcBaseCostFirst.setChannelOrderId(costFirstData.getChannelOrderId());
            dcBaseCostFirst.setWarehouseCode(costFirstData.getWarehouseCode());
            if (costFirstData.getSkus() != null && costFirstData.getSkus().size() > 0) {
                HashMap<String, BigDecimal> map = new HashMap<>();
                /*
                 * 先算出总重量, 再按重量占总重量平摊
                 */
                BigDecimal totalWeight = null;
                try {
                    DcBaseSkuMapper dcBaseSkuMapper = SessionUtil.getSession().getMapper(DcBaseSkuMapper.class);
                    totalWeight = BigDecimal.ZERO;
                    for (CostFirstSku sku : costFirstData.getSkus()) {
                        DcBaseSku dcBaseSku = dcBaseSkuMapper.selectOneByExample(DcBaseSkuExample.newAndCreateCriteria().andBailunSkuEqualTo(sku.getBailunSku()).example());
                        BigDecimal weight = dcBaseSku.getWeight().multiply(BigDecimal.valueOf(sku.getQuantity()));
                        map.put(sku.getBailunSku(), weight);
                        totalWeight = totalWeight.add(weight);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException("MYBATIS操作DB查询SKU信息失败");
                } finally {
                    SessionUtil.closeSession();
                }
                BigDecimal totalRatioCostFrist = BigDecimal.ZERO;
                try {
                    DcBaseCostFirstMapper baseCostFirstMapper = SessionUtil.getSession().getMapper(DcBaseCostFirstMapper.class);
                    for (int i = 0; i < costFirstData.getSkus().size(); i++) {
                        dcBaseCostFirst.setBailunSku(costFirstData.getSkus().get(i).getBailunSku());
                        dcBaseCostFirst.setQuantity(costFirstData.getSkus().get(i).getQuantity());
                        BigDecimal weight = map.get(costFirstData.getSkus().get(i).getBailunSku());
                        if (totalWeight.compareTo(BigDecimal.ZERO) == 1) {
                            BigDecimal weightRatio = weight.divide(totalWeight, 4, RoundingMode.HALF_EVEN);
                            dcBaseCostFirst.setRatioWeight(weightRatio);
                            BigDecimal skuCostFirst = costFirstData.getCostFirst().multiply(weightRatio).setScale(3, BigDecimal.ROUND_HALF_EVEN);
                            dcBaseCostFirst.setCostFirst(skuCostFirst);
                            if (i ==  costFirstData.getSkus().size() - 1) {
                                dcBaseCostFirst.setCostFirst(costFirstData.getCostFirst().subtract(totalRatioCostFrist));
                            }
                            totalRatioCostFrist = totalRatioCostFrist.add(skuCostFirst);
                            int i1 = baseCostFirstMapper.updateByExampleSelective(dcBaseCostFirst, DcBaseCostFirstExample.newAndCreateCriteria().andBailunSkuEqualTo(dcBaseCostFirst.getBailunSku()).andChannelIdEqualTo(dcBaseCostFirst.getChannelId()).example());
                            if (i1 == 0) {
                                baseCostFirstMapper.insertSelective(dcBaseCostFirst);
                            }
                        } else {
                            throw new RuntimeException("算头程费占比时SKU总重量为0, ChannelId是" + costFirstData.getChannelId());
                        }
                    }
                } catch (RuntimeException e) {
                    throw new RuntimeException("MYBATIS操作DB更新插入数据失败, ChannelId是" + costFirstData.getChannelId(),e);
                } finally {
                }
            }
        }
    }


}
