
package com.tmerclub.cloud.order.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.tmerclub.cloud.api.order.dto.CustomerRetainedDTO;
import com.tmerclub.cloud.api.order.vo.CustomerRetainVO;
import com.tmerclub.cloud.common.cache.constant.OrderCacheNames;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.order.manager.MongoOrderManager;
import com.tmerclub.cloud.order.service.OrderAnalysisService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 订单数据分析
 * @author cl
 * @date 2021-05-25 09:13:38
 */
@Service
public class OrderAnalysisServiceImpl implements OrderAnalysisService {

    private static final Logger log = LoggerFactory.getLogger(OrderAnalysisServiceImpl.class);

    @Autowired
    private MongoOrderManager mongoOrderManager;


    @Override
    public List<CustomerRetainVO> getTradeRetained(CustomerRetainedDTO customerRetainedDTO) {
        List<CustomerRetainVO> list = mongoOrderManager.getTradeRetained(customerRetainedDTO);

        // 按月份进行分组
        Map<String, List<CustomerRetainVO>> map = new HashMap<>(8);
        if (CollUtil.isNotEmpty(list)) {
            map = list.stream()
                    .filter(customerRetainVO -> Objects.nonNull(customerRetainVO.getCurrentMonth()) && Objects.nonNull(customerRetainVO.getDealMonth()))
                    .collect(Collectors.groupingBy(CustomerRetainVO::getCurrentMonth));
        }
        List<CustomerRetainVO> customerRetainList = new ArrayList<>(Constant.INITIAL_CAPACITY);

        Date startTime = customerRetainedDTO.getStartTime();
        long endTime = customerRetainedDTO.getEndTime().getTime();
        while (startTime.getTime() < endTime) {
            String startTimeFormat = DateUtil.format(startTime, "yyyyMM");
            CustomerRetainVO customerRetainVO = initCustomerRetainVO(startTimeFormat);
            customerRetainList.add(customerRetainVO);

            // 时间更新为下一月
            startTime = DateUtil.beginOfMonth(DateUtil.offsetMonth(startTime, 1));

            // 没有交易数据
            if (!map.containsKey(startTimeFormat)) {
                continue;
            }

            // 用户的交易数据处理
            Map<String, CustomerRetainVO> dealMap = map.get(startTimeFormat).stream().collect(Collectors.toMap(CustomerRetainVO::getDealMonth, c -> c));
            if (!dealMap.containsKey(startTimeFormat)) {
                continue;
            }
            CustomerRetainVO dealCustomerRetain = dealMap.get(startTimeFormat);
            customerRetainVO.setNewCustomers(dealCustomerRetain.getNewCustomers());

            // 从第二个月开始获取用户留存数量
            customerRetainVO.setFirstMonthRemain(getNewCustomers(startTime, dealMap, 0));
            customerRetainVO.setSecondMonthRemain(getNewCustomers(startTime, dealMap, 1));
            customerRetainVO.setThirdMonthRemain(getNewCustomers(startTime, dealMap, 2));
            customerRetainVO.setFourthMonthRemain(getNewCustomers(startTime, dealMap, 3));
            customerRetainVO.setFifthMonthRemain(getNewCustomers(startTime, dealMap, 4));
            customerRetainVO.setSixthMonthRemain(getNewCustomers(startTime, dealMap, 5));
        }
        return customerRetainList;
    }

    private Integer getNewCustomers(Date dealTime, Map<String, CustomerRetainVO> dealMap, int month) {
        String dealTimeFarmat = DateUtil.format(DateUtil.offsetMonth(dealTime, month), "yyyyMM");
        Integer newCustomers = 0;
        if (dealMap.containsKey(dealTimeFarmat)) {
            CustomerRetainVO customerRetainVO = dealMap.get(dealTimeFarmat);
            newCustomers = customerRetainVO.getNewCustomers();
        }
        return newCustomers;
    }


    private CustomerRetainVO initCustomerRetainVO(String startTimeFormat) {
        CustomerRetainVO customerRetainVO = new CustomerRetainVO();
        customerRetainVO.setCurrentMonth(startTimeFormat);
        customerRetainVO.setNewCustomers(0);
        customerRetainVO.setFifthMonthRemain(0);
        customerRetainVO.setSecondMonthRemain(0);
        customerRetainVO.setThirdMonthRemain(0);
        customerRetainVO.setFourthMonthRemain(0);
        customerRetainVO.setFirstMonthRemain(0);
        customerRetainVO.setSixthMonthRemain(0);
        return customerRetainVO;
    }

    @Override
    @CacheEvict(cacheNames = OrderCacheNames.ORDER_TRADE_RETAINED_KEY, key = "#customerRetainedDTO.retainType +':'+ #customerRetainedDTO.dateType")
    public void removeCacheTradeRetained(CustomerRetainedDTO customerRetainedDTO) {
    }

}
