package com.zm.order.tool.server.handler;

import com.alibaba.fastjson.JSON;
import com.github.dozermapper.core.Mapper;
import com.zm.order.tool.server.constants.CommonConstants;
import com.zm.order.tool.server.dao.OrderNoIndexDao;
import com.zm.order.tool.server.dao.PerformanceSelfTakeDao;
import com.zm.order.tool.server.dto.*;
import com.zm.order.tool.server.enums.PerformanceTypeEnum;
import com.zm.order.tool.server.manager.SearchManager;
import com.zm.order.tool.server.model.*;
import com.zm.order.tool.server.query.SearchOrderQuery;
import com.zm.order.tool.server.service.ExceptionConstants;
import com.zm.util.dto.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 订单自提处理器
 * 
 * @Author chang.n
 * @ClassName PerformanceSelfTakeHandle
 * @Date 2020/4/14 2:49 PM
 */
@Component
public class PerformanceSelfTakeHandle implements RetailPerformanceHandler {

    private static final Logger logger = LoggerFactory.getLogger(PerformanceSelfTakeHandle.class);

    @Autowired
    private Mapper mapper;

    @Autowired
    private PerformanceSelfTakeDao selfTakeDao;

    @Autowired
    private SearchManager searchManager;

    @Autowired
    private OrderNoIndexDao orderNoIndexDao;

    @Override
    public String performanceType() {
        return PerformanceTypeEnum.SELF_TAKE.getType().toString();
    }

    /**
     * 预约配送开始时间
     */
    private static final String DELIVERY_START_AT = "reserve_delivery_start_at";

    /**
     * 预约配送结束时间
     */
    private static final String DELIVERY_END_AT = "reserve_delivery_end_at";

    private static final String ORDER_ADDRESS = "orderAddress";

    private static final String MOBILE = "mobile";

    /**
     * 避免发送两次同步订单消息
     * 同步订单消息写在上层
     * @param orderPerformanceDTO
     * @return: com.zm.util.dto.Result
     * @Date:   2020/7/23 9:29 AM
     */
    @Override
    public Result createPerformance(OrderPerformanceDTO orderPerformanceDTO) {
        Result result = new Result();
        return result;
    }

    @Override
    public Result operatePerformance(OrderPerformanceDTO operateDTO, Order order) {
        Result result = new Result();
        return result;
    }

    private PerformanceSelfTake getUpdateDo(Map<String, Object> operateInfo, PerformanceSelfTake take) {
        PerformanceSelfTake updateTake = new PerformanceSelfTake();
        return updateTake;
    }

    @Override
    public Result<List<BasePerformanceDTO>> queryPerformance(QueryPerformanceDTO performanceDTO) {
        Result<List<BasePerformanceDTO>> result = new Result();
        List<BasePerformanceDTO> dtoList = null;
        try {
            if (!StringUtils.isEmpty(performanceDTO.getUserId())) {
                // 直接走DB
                List<PerformanceSelfTake> performanceList = selfTakeDao.selectList(performanceDTO);
                dtoList = convertViewDto(performanceList);
            } else if (!CollectionUtils.isEmpty(performanceDTO.getOrderNoList())) {
                // 1.订单号索引查询
                List<OrderNoIndex> orderIndexList = orderNoIndexDao.selectList(performanceDTO.getOrderNoList());
                if (CollectionUtils.isEmpty(orderIndexList)) {
                    result.setException(ExceptionConstants.ORDER_NO_INDEX_NOT_EXISTS);
                    return result;
                }
                List<PerformanceSelfTakeDTO> performanceDTOList = converter(orderIndexList);
                // 2.查询履约信息
                List<PerformanceSelfTake> selfTakeDTOList = new ArrayList<>();
                if (!CollectionUtils.isEmpty(performanceDTOList)) {
                    performanceDTOList.forEach(takeDTO -> {
                        String orderNo = takeDTO.getOrderNo();
                        Long userId = takeDTO.getUserId();
                        PerformanceSelfTake performance = selfTakeDao.selectOne(orderNo, userId);
                        if (performance != null) {
                            selfTakeDTOList.add(performance);
                        }
                    });
                    dtoList = convertViewDto(selfTakeDTOList);
                }
            } else {
                SearchOrderQuery searchOrderQuery = buildSearchQuery(performanceDTO);
                SearchOrderDTO searchOrderDTO = searchManager.searchOrder(searchOrderQuery);
                // 防止DB查询数量过载
                if (searchOrderDTO.getTotal() >= CommonConstants.MAX_QUERY_COUNT) {
                    result.setException(ExceptionConstants.QUERY_COUNT_OVERLOAD);
                    return result;
                }
                List<BaseIndexOrder> orderList = searchOrderDTO.getOrderList();
                if (CollectionUtils.isEmpty(orderList)) {
                    result.setData(Collections.EMPTY_LIST);
                    result.setStatus(true);
                    return result;
                }
                dtoList = queryPerformanceData(orderList);
            }
            result.setData(dtoList);
            result.setStatus(true);
        } catch (Exception e) {
            logger.error("PerformanceSelfTakeHandle[queryPerformance]query performance failed,request:{},cause by:{}",
                    performanceDTO, e);
            result.setMessage("查询履约信息异常");
        }
        return result;
    }

    private List<BasePerformanceDTO> convertViewDto(List<PerformanceSelfTake> performanceSelfTakes) {
        List<BasePerformanceDTO> basePerformanceDTOList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(performanceSelfTakes)) {
            performanceSelfTakes.forEach(selfTake -> {
                PerformanceSelfTakeDTO selfTakeDTO = mapper.map(selfTake, PerformanceSelfTakeDTO.class);
                basePerformanceDTOList.add(selfTakeDTO);
            });
        }
        return basePerformanceDTOList;
    }

    private List<BasePerformanceDTO> queryPerformanceData(List<BaseIndexOrder> orderList) {
        List<BasePerformanceDTO> performanceList = new ArrayList<>(orderList.size());
        orderList.forEach(baseModel -> {
            PerformanceSelfTake take = selfTakeDao.selectOne(baseModel.getOrderNo(), baseModel.getUserId());
            if (take != null) {
                performanceList.add(mapper.map(take, PerformanceSelfTakeDTO.class));
            }
        });
        return performanceList;
    }

    private SearchOrderQuery buildSearchQuery(QueryPerformanceDTO performanceDTO) {
        performanceDTO.setPageNo(1);
        // 防止es查询数量过载
        performanceDTO.setPageSize(1000);
        SearchOrderQuery searchOrderQuery = mapper.map(performanceDTO, SearchOrderQuery.class);
        return searchOrderQuery;
    }

    private List<PerformanceSelfTakeDTO> converter(List<OrderNoIndex> orderIndexList) {
        List<PerformanceSelfTakeDTO> performanceDTOList = null;
        if (!CollectionUtils.isEmpty(orderIndexList)) {
            performanceDTOList = new ArrayList<>(orderIndexList.size());
            for (OrderNoIndex index : orderIndexList) {
                PerformanceSelfTakeDTO takeDTO = new PerformanceSelfTakeDTO();
                takeDTO.setOrderNo(index.getOrderNo());
                takeDTO.setUserId(index.getUserId());
                performanceDTOList.add(takeDTO);
            }
        }
        return performanceDTOList;
    }


    @Override
    public void buildPerformanceInfo(RetailIndexOrder indexOrder, Order order) {
        PerformanceSelfTake selfTake = selfTakeDao.selectOne(order.getOrderNo(), order.getUserId());
        if (selfTake != null) {
            setPerformanceByTake(indexOrder, selfTake);
        } else {
            // 尝试从peroformanceInfo获取数据 巴黎甜甜可能存在没有自提单场景
            if (!StringUtils.isEmpty(order.getPerformanceInfo())) {
                String performanceInfo = order.getPerformanceInfo();
                Map<String, Object> performanceMap = JSON.parseObject(performanceInfo);
                if (Objects.nonNull(performanceMap.get(ORDER_ADDRESS))) {
                    Map<String, Object> orderAddressMap = JSON.parseObject(performanceMap.get(ORDER_ADDRESS).toString());
                    if (!StringUtils.isEmpty(orderAddressMap.get(MOBILE))) {
                        Object mobile = orderAddressMap.get(MOBILE);
                        indexOrder.setDeliveryMobile(mobile.toString());
                    }
                }
                try {
                    if (!StringUtils.isEmpty(performanceMap.get(DELIVERY_START_AT))
                        && !StringUtils.isEmpty(performanceMap.get(DELIVERY_END_AT))) {
                        Object deliveryStartAt = performanceMap.get(DELIVERY_START_AT);
                        Object deliveryEndAt = performanceMap.get(DELIVERY_END_AT);
                        if (deliveryStartAt instanceof String && deliveryEndAt instanceof String) {
                            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                            indexOrder.setReserveDeliveryAtStart(sdf.parse(deliveryStartAt.toString()));
                            indexOrder.setReserveDeliveryAtEnd(sdf.parse(deliveryEndAt.toString()));
                        } else {
                            Long deliveryStart = Long.valueOf(deliveryStartAt.toString());
                            Long deliveryEnd = Long.valueOf(deliveryEndAt.toString());
                            indexOrder.setReserveDeliveryAtStart(new Date(deliveryStart));
                            indexOrder.setReserveDeliveryAtEnd(new Date(deliveryEnd));
                        }
                    }
                } catch (ParseException e) {
                    logger.error(
                            "PerformanceExpressHandle[buildPerformanceInfo]reserveDeliveryAt convert failed!,request:{},cause by:{}",
                            order, e);
                    throw new RuntimeException("查询履约信息异常");
                }
            }
        }
    }

    @Override
    public void buildPerformanceIndex(BakingIndexOrder indexOrder, Order order) {
        PerformanceSelfTake selfTake = selfTakeDao.selectOne(order.getOrderNo(), order.getUserId());
        if (selfTake != null) {
            if (!StringUtils.isEmpty(selfTake.getSelfTakeCode())) {
                indexOrder.setSelfTakeCode(selfTake.getSelfTakeCode());
            }
            if (!StringUtils.isEmpty(selfTake.getSelfTakeStartAt())) {
                indexOrder.setReserveDeliveryAtStart(selfTake.getSelfTakeStartAt());
            }
            if (!StringUtils.isEmpty(selfTake.getSelfTakeEndAt())) {
                indexOrder.setReserveDeliveryAtEnd(selfTake.getSelfTakeEndAt());
            }
        }
    }

    private void setPerformanceByTake(RetailIndexOrder indexOrder, PerformanceSelfTake selfTake) {
        if (!StringUtils.isEmpty(selfTake.getSelfTakeCode())) {
            indexOrder.setSelfTakeCode(selfTake.getSelfTakeCode());
        }
        if (!StringUtils.isEmpty(selfTake.getSelfTakeMobile())) {
            String mobile = selfTake.getSelfTakeMobile();
            if (mobile.length() > 3) {
                String tail = mobile.substring(mobile.length() - 4, mobile.length());
                indexOrder.setDeliveryMobile(mobile + ";" + tail);
            }
        }
        if (!StringUtils.isEmpty(selfTake.getSelfTakeStartAt())
            && !StringUtils.isEmpty(selfTake.getSelfTakeEndAt())) {
            indexOrder.setReserveDeliveryAtStart(selfTake.getSelfTakeStartAt());
            indexOrder.setReserveDeliveryAtEnd(selfTake.getSelfTakeEndAt());
        }
        if (!StringUtils.isEmpty(selfTake.getVerifyType())) {
            indexOrder.setVerifyType(selfTake.getVerifyType());
        }
        if (!StringUtils.isEmpty(selfTake.getAppointedDateType())) {
            indexOrder.setAppointedDateType(selfTake.getAppointedDateType());
        }
        if (Objects.nonNull(selfTake.getSelfTakeStatus())) {
            indexOrder.setSelfTakeStatus(selfTake.getSelfTakeStatus());
        }
    }
}
