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.dto.PurchaseDetailDTO;
import com.bailuntec.domain.dto.TransferDetailsPOJO;
import com.bailuntec.domain.dto.TransferStreamPOJO;
import com.bailuntec.domain.entity.*;
import com.bailuntec.domain.example.DcBaseStockOutExample;
import com.bailuntec.domain.example.DcBaseStockRecordExample;
import com.bailuntec.mapper.*;
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.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.LinkedHashMap;
import java.util.List;

@Slf4j
public class SyncWarehouseStockJob extends PointJob {

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

    @Override
    public void executeJob(ShardingContext shardingContext, JobPointLog jobPointLog) {
        jobPointLog.setType(5);
        syncPurchaseDetail(shardingContext, jobPointLog);
        jobPointLog.setPageIndex(1);
        syncTransferInbound(shardingContext, jobPointLog);
        jobPointLog.setPageIndex(1);
        syncOrderPick(shardingContext, jobPointLog);
        jobPointLog.setStartTime(jobPointLog.getEndTime());
        jobPointLog.setEndTime(jobPointLog.getStartTime().plusDays(jobPointLog.getIntervalTime().longValue()).isAfter(LocalDateTime.now()) ? LocalDateTime.now() : jobPointLog.getStartTime().plusDays(jobPointLog.getIntervalTime().longValue()));
    }

    /**
     * 得到采购入库数量
     * @param shardingContext
     * @param jobPointLog
     */
    public void syncPurchaseDetail(ShardingContext shardingContext, JobPointLog jobPointLog) {
        MediaType mediaType = MediaType.parse("application/json");
        LinkedHashMap<String, Object> map = new LinkedHashMap<>(5);
        map.put("start", DateTimeFormatter.ofPattern(CommonConstant.TIME_FORMAT).format(jobPointLog.getStartTime().minusMinutes(1L)));
        map.put("end", DateTimeFormatter.ofPattern(CommonConstant.TIME_FORMAT).format(jobPointLog.getEndTime()));
        map.put("type", jobPointLog.getType());
        map.put("pagesize", jobPointLog.getPageSize());
        List<PurchaseDetailDTO> purchaseDetailDTOList = null;
        do {
            map.put("page", jobPointLog.getPageIndex() > 0? jobPointLog.getPageIndex() : 1);
            RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(map));
            String purchaseStr = null;
            Response response = null;
            if (purchaseDetailDTOList != null) purchaseDetailDTOList = null;
            try {
                Request request = new Request.Builder()
                        .url(propertiesUtil.getPropertyAsString("PURCHASE_DETAILS_URL"))
                        .post(body)
                        .addHeader("Content-Type", "application/json")
                        .build();
                response = client.newCall(request).execute();
                purchaseStr = response.body().string();
            } catch (IOException e) {
                log.error("调用采购单sku详细信息接口失败", e);
                throw new RuntimeException("调用采购单sku详细信息接口失败", e);
            } finally {
                if (response != null) {
                    response.close();
                }
            }
            if (StringUtils.isNotBlank(purchaseStr)) {
                JSONObject jsonObject = JSON.parseObject(purchaseStr);
                if (jsonObject != null) {
                    if (jobPointLog.getPageIndex() == 0) {
                        jobPointLog.setPageIndex(jsonObject.getInteger("pagetotal") + 1);
                    }
                    purchaseDetailDTOList = jsonObject.getObject("data", new TypeReference<List<PurchaseDetailDTO>>() {
                    });
                    if (purchaseDetailDTOList != null && purchaseDetailDTOList.size() > 0) {
                        for (PurchaseDetailDTO purchaseDetailDTO : purchaseDetailDTOList) {
                            if("1".equals(purchaseDetailDTO.getStatus())) {
                            DcBaseStockRecord dcBaseStockRecord = new DcBaseStockRecord();
                            try {
                                dcBaseStockRecord.setQuantityStock(purchaseDetailDTO.getCount());
                                dcBaseStockRecord.setStockTime(purchaseDetailDTO.getUpdatedTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime());
                                dcBaseStockRecord.setWarehouseCode(purchaseDetailDTO.getWarehouseCode());
                                dcBaseStockRecord.setWarehouseName(purchaseDetailDTO.getWarehouseName());
                                dcBaseStockRecord.setBailunSku(purchaseDetailDTO.getBailunSku());
                            } catch (Exception e) {
                                throw new RuntimeException("解析采购单sku流水BeanUtils.copyProperties失败", e);
                            }
                            try {
                                DcBaseStockRecordMapper mapper = SessionUtil.getSession().getMapper(DcBaseStockRecordMapper.class);
                                int i = mapper.updateByExampleSelective(dcBaseStockRecord, DcBaseStockRecordExample.newAndCreateCriteria().andBailunSkuEqualTo(dcBaseStockRecord.getBailunSku()).andWarehouseCodeEqualTo(dcBaseStockRecord.getWarehouseCode()).andStockTimeEqualTo(dcBaseStockRecord.getStockTime()).example());
                                if (i == 0) {
                                    mapper.insertSelective(dcBaseStockRecord);
                                }
                            } catch (Exception e) {
                                e.printStackTrace();
                                throw new RuntimeException("MYbatis操作DB失败", e);
                            } finally {
                                SessionUtil.closeSession();
                            }
                            }
                        }
                    }
                } else {
                    throw new RuntimeException("调用采购单sku详细信息接口失败");
                }
            } else {
                throw new RuntimeException("调用采购单sku详细信息接口失败");
            }
            jobPointLog.setPageIndex(jobPointLog.getPageIndex() - 1);
        } while (jobPointLog.getPageIndex() > 0);
    }

    /**
     * 得到调拨入库、出库数量
     * @param shardingContext
     * @param jobPointLog
     */
    public void syncTransferInbound(ShardingContext shardingContext, JobPointLog jobPointLog) {

        OkHttpClient client = OkHttpUtil.getInstance();
        MediaType mediaType = MediaType.parse("application/json");
        LinkedHashMap<String, Object> map = new LinkedHashMap<>(5);
        map.put("StartDate", DateTimeFormatter.ofPattern(CommonConstant.TIME_FORMAT).format(jobPointLog.getStartTime().minusHours(9)));
        map.put("EndDate", DateTimeFormatter.ofPattern(CommonConstant.TIME_FORMAT).format(jobPointLog.getEndTime()));
        map.put("State", jobPointLog.getType());
        String url = propertiesUtil.getPropertyAsString("TRANSFER_DETAILS_URL");
        map.put("PageRow", jobPointLog.getPageSize());
        do {
            map.put("CurrentPage", jobPointLog.getPageIndex() > 0?jobPointLog.getPageIndex() : 1);
            Response response = null;
            String responseStr = null;
            try {
                RequestBody body = RequestBody.create(mediaType, JSON.toJSONString(map));
                Request request = new Request.Builder()
                        .url(url)
                        .post(body)
                        .addHeader("Content-Type", "application/json")
                        .build();
                response = client.newCall(request).execute();
                responseStr = response.body().string();
            } catch (IOException e) {
                throw new RuntimeException("调用调拨单sku流水接口失败", e);
            } finally {
                if (response != null) {
                    response.close();
                }
            }
            if (response != null && response.isSuccessful()) {
                JSONObject jsonObject = JSON.parseObject(responseStr);
                if (jsonObject.get("isSuccess") != null && jsonObject.getBooleanValue("isSuccess")) {
                    TransferDetailsPOJO transferDetailsPOJO = jsonObject.getObject("data", TransferDetailsPOJO.class);
                    if (jobPointLog.getPageIndex().equals(0)) {
                        jobPointLog.setPageIndex(transferDetailsPOJO.getPageCount() + 1);
                    }
                    if (transferDetailsPOJO  != null && transferDetailsPOJO.getData()  != null && transferDetailsPOJO.getData().size() > 0) {
                                for (TransferStreamPOJO transferStreamPOJO : transferDetailsPOJO.getData()) {
                                    int round = Math.round(transferStreamPOJO.getCreateTime().getNano() / 1000000000.0F);
                                    DcBaseStockRecord dcBaseStockRecord = new DcBaseStockRecord();
                                    dcBaseStockRecord.setWarehouseCode(transferStreamPOJO.getWarehouseCode());
                                   // dcBaseStockDuration.setWarehouseName(transferStreamPOJO.getWarehouseName());
                                    dcBaseStockRecord.setStockTime(transferStreamPOJO.getCreateTime().withNano(0).plusSeconds(round));
                                    dcBaseStockRecord.setBailunSku(transferStreamPOJO.getBailunSku());
                                    dcBaseStockRecord.setQuantityStock(transferStreamPOJO.getCount());
                                    dcBaseStockRecord.setHasTransfer(1);
                                    try {
                                        DcBaseStockRecordMapper mapper = SessionUtil.getSession().getMapper(DcBaseStockRecordMapper.class);
                                        int i = mapper.updateByExampleSelective(dcBaseStockRecord, DcBaseStockRecordExample.newAndCreateCriteria()
                                                .andBailunSkuEqualTo(dcBaseStockRecord.getBailunSku())
                                                .andWarehouseCodeEqualTo(dcBaseStockRecord.getWarehouseCode())
                                                .andStockTimeEqualTo(dcBaseStockRecord.getStockTime())
                                                .example());
                                        if (i == 0) {
                                            mapper.insertSelective(dcBaseStockRecord);
                                        }
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                        throw new RuntimeException("MYbatis操作DB失败", e);
                                    } finally {
                                        SessionUtil.closeSession();
                                    }


                                    DcBaseStockOut dcBaseStockOut = new DcBaseStockOut();
                                    if(transferStreamPOJO.getFromWarehouseCode() != null) {
                                        dcBaseStockOut.setWarehouseCode(transferStreamPOJO.getFromWarehouseCode());
                                        dcBaseStockOut.setStockTime(transferStreamPOJO.getCreateTime().withNano(0).plusSeconds(round));
                                        dcBaseStockOut.setBailunSku(transferStreamPOJO.getBailunSku());
                                        dcBaseStockOut.setQuantityStock(transferStreamPOJO.getCount());
                                        dcBaseStockOut.setHasTransfer(1);
                                        try {
                                            DcBaseStockOutMapper mapper = SessionUtil.getSession().getMapper(DcBaseStockOutMapper.class);
                                            int i = mapper.updateByExampleSelective(dcBaseStockOut, DcBaseStockOutExample.newAndCreateCriteria()
                                                    .andBailunSkuEqualTo(dcBaseStockOut.getBailunSku())
                                                    .andWarehouseCodeEqualTo(dcBaseStockOut.getWarehouseCode())
                                                    .andStockTimeEqualTo(dcBaseStockOut.getStockTime())
                                                    .example());
                                            if (i == 0) {
                                                mapper.insertSelective(dcBaseStockOut);
                                            }
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                            throw new RuntimeException("MYbatis操作DB失败", e);
                                        } finally {
                                            SessionUtil.closeSession();
                                        }
                                    }

                                }
                    }
                } else {
                    throw new RuntimeException("调用调拨流水接口返回200但是失败");
                }
            } else {
                throw new RuntimeException("调用调拨流水接口失败");
            }
            if (jobPointLog.getPageIndex() % 5 == 0) {
                try {
                    JobPointLogMapper mapper = SessionUtil.getSession().getMapper(JobPointLogMapper.class);
                    mapper.upsertSelective(jobPointLog);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException("Mybatis操作DB插入任务记录失败", e);
                } finally {
                    SessionUtil.closeSession();
                }
            }
            jobPointLog.setPageIndex(jobPointLog.getPageIndex() - 1);
        } while (jobPointLog.getPageIndex() > 0);
        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 void syncOrderPick(ShardingContext shardingContext, JobPointLog jobPointLog) {
        jobPointLog.setPageIndex(jobPointLog.getPageIndex() == 0 ? 1 : jobPointLog.getPageIndex());
        Integer pickSize = 0;
        try {
            DcBaseStockRecordMapper dcBaseStockRecordMapper = SessionUtil.getSession().getMapper(DcBaseStockRecordMapper.class);
            pickSize = dcBaseStockRecordMapper.selectOrderPickCount(jobPointLog);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("MYbatis操作DB失败", e);
        } finally {
            SessionUtil.closeSession();
        }
        Integer pageSize = pickSize % jobPointLog.getPageSize() == 0 ? pickSize/jobPointLog.getPageSize() : pickSize/jobPointLog.getPageSize() + 1;
        do{
            DcBaseStockRecordMapper dcBaseStockRecordMapper1 = SessionUtil.getSession().getMapper(DcBaseStockRecordMapper.class);
            List<DcBaseOmsPick> dcBaseOmsPickList = null;
            try {
                dcBaseOmsPickList = dcBaseStockRecordMapper1.selectListByPage(jobPointLog);
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("MYbatis操作DB失败", e);
            } finally {
                SessionUtil.closeSession();
            }
            for(DcBaseOmsPick dcBaseOmsPick : dcBaseOmsPickList) {
                DcBaseStockOut dcBaseStockOut = new DcBaseStockOut();
                dcBaseStockOut.setWarehouseCode(dcBaseOmsPick.getWarehouseCode());
                dcBaseStockOut.setWarehouseName(dcBaseOmsPick.getWarehouseName());
                dcBaseStockOut.setStockTime(dcBaseOmsPick.getShippingTime());
                dcBaseStockOut.setBailunSku(dcBaseOmsPick.getBailunSku());
                dcBaseStockOut.setQuantityStock(dcBaseOmsPick.getQuantityShipped());
                dcBaseStockOut.setHasTransfer(0);
                try {
                    DcBaseStockOutMapper mapper = SessionUtil.getSession().getMapper(DcBaseStockOutMapper.class);
                    int i = mapper.updateByExampleSelective(dcBaseStockOut, DcBaseStockOutExample.newAndCreateCriteria()
                            .andBailunSkuEqualTo(dcBaseStockOut.getBailunSku())
                            .andWarehouseCodeEqualTo(dcBaseStockOut.getWarehouseCode())
                            .andStockTimeEqualTo(dcBaseStockOut.getStockTime())
                            .example());
                    if (i == 0) {
                        mapper.insertSelective(dcBaseStockOut);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new RuntimeException("MYbatis操作DB失败", e);
                } finally {
                    SessionUtil.closeSession();
                }
            }
            jobPointLog.setPageIndex(jobPointLog.getPageIndex() + 1);
        }while(jobPointLog.getPageIndex() <= pageSize);

    }
}
