package com.bailuntec.job;

import com.alibaba.fastjson.JSON;
import com.bailuntec.domain.constant.EbaySkuMappingRoot;
import com.bailuntec.domain.dto.DcBaseEbaySkuMappingDto;
import com.bailuntec.domain.dto.DcBaseFinanceEbayItemDto;
import com.bailuntec.domain.entity.DcBaseEbaySkuMapping;
import com.bailuntec.domain.entity.DcBaseEbaySkuRatio;
import com.bailuntec.domain.entity.JobPointLog;
import com.bailuntec.mapper.DcBaseEbaySkuMappingMapper;
import com.bailuntec.mapper.DcBaseEbaySkuRatioMapper;
import com.bailuntec.mapper.DcBaseFinanceEbayMapper;
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 lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class CalculateEbaySkuRatioJob extends PointJob {

    private OkHttpClient okHttpClient = OkHttpUtil.getInstance();
    private PropertiesUtil propertiesUtil = PropertiesUtil.getInstance("const");

    @Override
    public void executeJob(ShardingContext shardingContext, JobPointLog jobPointLog) {
        long countEbayFee;
        try{
            DcBaseFinanceEbayMapper dcBaseFinanceEbayMapper = SessionUtil.getSession().getMapper(DcBaseFinanceEbayMapper.class);
            countEbayFee = dcBaseFinanceEbayMapper.countByGroup(jobPointLog);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("MYBATIS操作DB失败", e);
        }finally {
            SessionUtil.closeSession();
        }

        long totalPage = getEbayPage(countEbayFee, jobPointLog);

        do{
            List<DcBaseFinanceEbayItemDto> dcBaseFinanceEbayItemDtoList;
            try{
                DcBaseFinanceEbayMapper dcBaseFinanceEbayMapper = SessionUtil.getSession().getMapper(DcBaseFinanceEbayMapper.class);
                dcBaseFinanceEbayItemDtoList = dcBaseFinanceEbayMapper.selectEbay(jobPointLog);
                if(dcBaseFinanceEbayItemDtoList != null && dcBaseFinanceEbayItemDtoList.size() > 0) {

                    for(DcBaseFinanceEbayItemDto dcBaseFinanceEbayItemDto : dcBaseFinanceEbayItemDtoList) {
                        if(dcBaseFinanceEbayItemDto.getDcBaseSkuMappingList() != null && dcBaseFinanceEbayItemDto.getDcBaseSkuMappingList().size() > 0) {
                            BigDecimal totalUnitPrice = getTotalUnitPrice0(dcBaseFinanceEbayItemDto.getDcBaseSkuMappingList());
                            for(DcBaseEbaySkuMappingDto dcBaseEbaySkuMappingDto : dcBaseFinanceEbayItemDto.getDcBaseSkuMappingList()) {
                                DcBaseEbaySkuRatio dcBaseEbaySkuRatio = new DcBaseEbaySkuRatio();
                                BigDecimal unitPrice = dcBaseEbaySkuMappingDto.getUnitPrice() == null ? BigDecimal.ZERO : dcBaseEbaySkuMappingDto.getUnitPrice();
                                BigDecimal unitPriceRadio;
                                if(totalUnitPrice.compareTo(BigDecimal.ZERO) == 0) {
                                    unitPriceRadio = BigDecimal.ONE.divide(BigDecimal.valueOf(dcBaseFinanceEbayItemDto.getDcBaseSkuMappingList().size()), 3, RoundingMode.HALF_EVEN);
                                }else {
                                    unitPriceRadio = unitPrice.multiply(BigDecimal.valueOf(dcBaseEbaySkuMappingDto.getSkuCount())).divide(totalUnitPrice, 3, RoundingMode.HALF_EVEN);
                                }
                                dcBaseEbaySkuRatio.setItemId(dcBaseFinanceEbayItemDto.getItemId());
                                dcBaseEbaySkuRatio.setSkuCode(dcBaseEbaySkuMappingDto.getSkuCode());
                                dcBaseEbaySkuRatio.setSkuCount(dcBaseEbaySkuMappingDto.getSkuCount());
                                dcBaseEbaySkuRatio.setSkuRatio(unitPriceRadio);
                                dcBaseEbaySkuRatio.setSkuPrice(dcBaseEbaySkuMappingDto.getUnitPrice());
                                if(dcBaseEbaySkuMappingDto.getSkuCode() == null) {
                                    dcBaseEbaySkuRatio.setSkuCode("无");
                                }
                                DcBaseEbaySkuRatioMapper dcBaseEbaySkuRatioMapper = SessionUtil.getSession().getMapper(DcBaseEbaySkuRatioMapper.class);
                                dcBaseEbaySkuRatioMapper.upsertSelective(dcBaseEbaySkuRatio);
                            }
                        }else {
                            List<String> list = new ArrayList<>();
                            list.add(dcBaseFinanceEbayItemDto.getItemId());

                            MediaType mediaType = MediaType.parse("application/json");
                            RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(list));
                            Request request = new Request.Builder()
                                    .url(propertiesUtil.getPropertyAsString("getSkuCodeInfoByItemId"))
                                    .post(body)
                                    .addHeader("Content-Type", "application/json")
                                    .build();
                            Response response = null;
                            String ebaySkuMappingStr = null;
                            try {
                                response = okHttpClient.newCall(request).execute();
                                ebaySkuMappingStr = response.body().string();
                            } catch (IOException e) {
                                throw new RuntimeException(dcBaseFinanceEbayItemDto.getItemId() + "请求ebay广告费映射失败" + response, e);
                            } finally {
                                if (response != null) {
                                    response.close();
                                }
                            }
                            if (StringUtils.isNoneBlank(ebaySkuMappingStr)) {
                                EbaySkuMappingRoot ebaySkuMappingRoot = JSON.parseObject(ebaySkuMappingStr, EbaySkuMappingRoot.class);
                                if (ebaySkuMappingRoot != null && ebaySkuMappingRoot.getIsSucceeded().booleanValue()) {
                                    List<DcBaseEbaySkuMapping> dcBaseEbaySkuMappingList = ebaySkuMappingRoot.getObjData();
                                    if (dcBaseEbaySkuMappingList != null && dcBaseEbaySkuMappingList.size() > 0) {
                                        Map<String, Integer> ebayMap = new HashMap<String, Integer>();
                                        for(DcBaseEbaySkuMapping ebaySkuMapping : dcBaseEbaySkuMappingList) {
                                            if(ebayMap.get(ebaySkuMapping.getSkuCode()) == null) {
                                                ebayMap.put(ebaySkuMapping.getSkuCode(), 1);
                                            }else {
                                                Integer number = ebayMap.get(ebaySkuMapping.getSkuCode()) + 1;
                                                ebayMap.put(ebaySkuMapping.getSkuCode(), number);
                                            }
                                            DcBaseEbaySkuMappingMapper dcBaseEbaySkuMappingMapper = SessionUtil.getSession().getMapper(DcBaseEbaySkuMappingMapper.class);
                                            dcBaseEbaySkuMappingMapper.upsertSelective(ebaySkuMapping);
                                        }
                                        calculateEbayByOnline(ebayMap, dcBaseFinanceEbayItemDto);

                                    }else {
                                        DcBaseEbaySkuRatio dcBaseEbaySkuRatio = new DcBaseEbaySkuRatio();
                                        dcBaseEbaySkuRatio.setItemId(dcBaseFinanceEbayItemDto.getItemId());
                                        DcBaseEbaySkuRatioMapper dcBaseEbaySkuRatioMapper = SessionUtil.getSession().getMapper(DcBaseEbaySkuRatioMapper.class);
                                        dcBaseEbaySkuRatioMapper.upsertSelective(dcBaseEbaySkuRatio);
                                    }
                                } else {
                                    DcBaseEbaySkuRatio dcBaseEbaySkuRatio = new DcBaseEbaySkuRatio();
                                    dcBaseEbaySkuRatio.setItemId(dcBaseFinanceEbayItemDto.getItemId());
                                    DcBaseEbaySkuRatioMapper dcBaseEbaySkuRatioMapper = SessionUtil.getSession().getMapper(DcBaseEbaySkuRatioMapper.class);
                                    dcBaseEbaySkuRatioMapper.upsertSelective(dcBaseEbaySkuRatio);
                                }
                            }
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
                throw new RuntimeException("MYBATIS操作DB失败", e);
            }finally {
                SessionUtil.closeSession();
            }
            jobPointLog.setPageIndex(jobPointLog.getPageIndex()+1);
        }while (jobPointLog.getPageIndex() <= totalPage);
        jobPointLog.setPageIndex(0);
        jobPointLog.setStartTime(jobPointLog.getEndTime());
        jobPointLog.setEndTime(jobPointLog.getStartTime().plusDays(jobPointLog.getIntervalTime().longValue()).isAfter(LocalDateTime.now()) ? LocalDateTime.now() : jobPointLog.getStartTime().plusDays(jobPointLog.getIntervalTime().longValue()));
    }


    public long getEbayPage(long countEbayFee, JobPointLog jobPointLog) {

        if (countEbayFee % jobPointLog.getPageSize() == 0) {
            return countEbayFee / jobPointLog.getPageSize();
        }
        return countEbayFee / jobPointLog.getPageSize() + 1;
    }

    BigDecimal getTotalUnitPrice0(List<DcBaseEbaySkuMappingDto> dcBaseSkuMappingList) {
        BigDecimal totalUnitPrice = BigDecimal.ZERO;
        for(DcBaseEbaySkuMappingDto dcBaseEbaySkuMappingDto : dcBaseSkuMappingList){
            BigDecimal unitPrice = dcBaseEbaySkuMappingDto.getUnitPrice() == null ? BigDecimal.ZERO : dcBaseEbaySkuMappingDto.getUnitPrice();
            totalUnitPrice = totalUnitPrice.add(unitPrice.multiply(BigDecimal.valueOf(dcBaseEbaySkuMappingDto.getSkuCount())));
        }
        return totalUnitPrice;
    }

    void calculateEbayByOnline(Map<String, Integer> ebayMap, DcBaseFinanceEbayItemDto dcBaseFinanceEbayItemDto) {
        BigDecimal totalUnitPrice = BigDecimal.ZERO;
        Integer totalNumber = 0;
        DcBaseFinanceEbayMapper dcBaseFinanceEbayMapper = SessionUtil.getSession().getMapper(DcBaseFinanceEbayMapper.class);
        for(Map.Entry<String, Integer> entry : ebayMap.entrySet()) {
            BigDecimal unitPrice = BigDecimal.ZERO;
            if(entry.getKey() != null) {
                unitPrice = dcBaseFinanceEbayMapper.selectSkuPrice(entry.getKey());
                unitPrice = unitPrice == null ? BigDecimal.ZERO : unitPrice;
            }
            totalUnitPrice = totalUnitPrice.add(unitPrice.multiply(BigDecimal.valueOf(entry.getValue())));
            totalNumber = totalNumber + entry.getValue();
        }



        for(Map.Entry<String, Integer> entry : ebayMap.entrySet()) {
            DcBaseEbaySkuRatio dcBaseEbaySkuRatio = new DcBaseEbaySkuRatio();

            BigDecimal unitPriceRadio;
            BigDecimal unitPrice = BigDecimal.ZERO;
            if(entry.getKey() != null) {
                unitPrice = dcBaseFinanceEbayMapper.selectSkuPrice(entry.getKey());
                unitPrice = unitPrice == null ? BigDecimal.ZERO : unitPrice;
            }
            if(totalUnitPrice.compareTo(BigDecimal.ZERO) == 0) {
                unitPriceRadio = BigDecimal.valueOf(entry.getValue()).divide(BigDecimal.valueOf(totalNumber), 3, RoundingMode.HALF_EVEN);
            }else {
                unitPriceRadio = unitPrice.multiply(BigDecimal.valueOf(entry.getValue())).divide(totalUnitPrice, 3, RoundingMode.HALF_EVEN);
            }
            dcBaseEbaySkuRatio.setItemId(dcBaseFinanceEbayItemDto.getItemId());
            dcBaseEbaySkuRatio.setSkuCode(entry.getKey());
            dcBaseEbaySkuRatio.setSkuCount(entry.getValue());
            dcBaseEbaySkuRatio.setSkuRatio(unitPriceRadio);
            dcBaseEbaySkuRatio.setSkuPrice(unitPrice);
            if(dcBaseEbaySkuRatio.getSkuCode() == null) {
                dcBaseEbaySkuRatio.setSkuCode("无");
            }
            DcBaseEbaySkuRatioMapper dcBaseEbaySkuRatioMapper = SessionUtil.getSession().getMapper(DcBaseEbaySkuRatioMapper.class);
            dcBaseEbaySkuRatioMapper.upsertSelective(dcBaseEbaySkuRatio);
        }
    }
}
