package com.clx.performance.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.clx.performance.dao.IntegralRecordDao;
import com.clx.performance.dao.IntegralStatisticsDao;
import com.clx.performance.dao.IntegralTruckDao;
import com.clx.performance.enums.integral.IntegralRecordEnum;
import com.clx.performance.extranal.user.DriverService;
import com.clx.performance.extranal.user.UserService;
import com.clx.performance.model.IntegralRecord;
import com.clx.performance.model.IntegralStatistics;
import com.clx.performance.model.IntegralTruck;
import com.clx.performance.param.app.integral.DriverPageIntegralTruckRankParam;
import com.clx.performance.param.pc.IntegralTruckAddParam;
import com.clx.performance.param.pc.PageIntegralTruckParam;
import com.clx.performance.param.pc.PageIntegralTruckRankParam;
import com.clx.performance.service.*;
import com.clx.performance.utils.LocalDateTimeUtils;
import com.clx.performance.vo.pc.IntegralTruckVO;
import com.clx.user.vo.app.driver.truck.DriverTruckAppVo;
import com.clx.user.vo.feign.DriverInfoFeignVo;
import com.msl.user.data.UserSessionData;
import com.msl.user.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class IntegralTruckServiceImpl implements IntegralTruckService {

    @Autowired
    private IntegralTruckDao integralTruckDao;
    @Autowired
    private IntegralStatisticsDao integralStatisticsDao;
    @Autowired
    private IntegralRecordDao integralRecordDao;

    @Autowired
    private IntegralRecordService integralRecordService;
    @Autowired
    private IntegralStatisticsService integralStatisticsService;

    @Autowired
    private DriverService driverService;

    @Autowired
    private IntegralMqService integralMqService;

    @Autowired
    private IntegralMqHandlerService integralMqHandlerService;

    @Autowired
    private UserService userService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveTruck(IntegralTruckAddParam param) {
        String truckNo = param.getTruckNo();

        boolean existFlag = integralTruckDao.existByTruckNo(truckNo);
        if (existFlag) {return;}

        IntegralTruck truck = new IntegralTruck();
        truck.setTruckNo(truckNo);
        truck.setDriverName(param.getDriverName());
        truck.setDriverMobile(param.getDriverMobile());
        truck.setEchelon(1);

        LocalDateTime statisticsDate = LocalDateTimeUtils.getStartWeek();
        int protectionIntegral = integralStatisticsService.protectionIntegralCalc(statisticsDate);
        int baseIntegral = 100;

        // 初始化统计
        IntegralStatistics statistics = new IntegralStatistics();
        statistics.setTruckNo(truckNo);
        statistics.setStatisticsDate(statisticsDate);
        statistics.setIntegralBase(0);
        statistics.setIntegral(protectionIntegral+baseIntegral);   //保护分+基础分
        statistics.setRank(1);
        integralStatisticsDao.saveEntity(statistics);

        IntegralStatistics statisticsNext = new IntegralStatistics();
        statisticsNext.setTruckNo(truckNo);
        statisticsNext.setStatisticsDate(statistics.getStatisticsDate().plusDays(7));
        statisticsNext.setIntegralBase(0);
        statisticsNext.setIntegral(0);
        statisticsNext.setRank(1);
        integralStatisticsDao.saveEntity(statisticsNext);

        // 新增车辆
        truck.setIntegral(statistics.getIntegral());
        integralTruckDao.saveEntity(truck);

        // 新增积分记录
        integralRecordService.save(statistics.getId(), statistics.getStatisticsDate(), statistics.getTruckNo(), IntegralRecord.type.PROTECTION.getValue(), protectionIntegral, "新用户");
        integralRecordService.save(statistics.getId(), statistics.getStatisticsDate(), statistics.getTruckNo(), IntegralRecord.type.BASE.getValue(), baseIntegral, "基础分");

        // 实时积分统计
        integralMqHandlerService.integralRealTimeStatistics(statistics.getId());

    }

    @Override
    public IPage<IntegralTruckVO> pageTruckList(PageIntegralTruckParam param) {
        return integralTruckDao.pageByParam(param);
    }

    @Override
    public IntegralTruckVO getTruckDriverInfo(String truckNo) {
        IntegralTruckVO truck = null;

        // 查询车辆信息
        DriverInfoFeignVo driverTruckInfoFeignVo = driverService.getTruckOwnInfo(truckNo).get();

        if (null != driverTruckInfoFeignVo) {
            truck = new IntegralTruckVO();
            truck.setTruckNo(truckNo);
            truck.setDriverName(driverTruckInfoFeignVo.getName());
            truck.setDriverMobile(driverTruckInfoFeignVo.getMobile());
        }

        return truck;
    }

    @Override
    public Integer getTruckCount(Integer truckEchelon) {
        int count = (int)integralTruckDao.countByTruckEchelon(truckEchelon);

        return count;
    }

    @Override
    public IPage<IntegralTruckVO> pageTruckRank(PageIntegralTruckRankParam param) {

        IPage<IntegralTruckVO> page = integralTruckDao.pageTruckRank(param);

        List<String> truckNoList = page.getRecords().stream().map(item -> item.getTruckNo()).collect(Collectors.toList());
        if (!truckNoList.isEmpty()) {
            List<IntegralStatistics> statisticsList = integralStatisticsDao.selectListByStatisticsDateAndTruckNoList(LocalDateTimeUtils.getWeekStart(), truckNoList);
            Map<String, Integer> rankMap = statisticsList.stream().collect(Collectors.toMap(item -> item.getTruckNo(), item -> item.getRank()));

            for (IntegralTruckVO item : page.getRecords()) {
                item.setRank(rankMap.get(item.getTruckNo()));
            }
        }

        return page;

    }

    @Override
    public IPage<IntegralTruckVO> driverPageTruckRank(DriverPageIntegralTruckRankParam param) {
        String time = LocalDateTimeUtils.formatTime(LocalDateTimeUtils.getStartWeek().minusDays(7));

        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();
        Long userNo = loginUserInfo.getUserNo();

        // 查找司机车辆
        List<DriverTruckAppVo> driverTruckList = userService.driverTruckList(userNo).orNull();
        if (driverTruckList == null || driverTruckList.isEmpty()) {return new Page<>();}

        List<String> truckNoList = driverTruckList.stream().map(item -> item.getTruckNo()).collect(Collectors.toList());
        param.setTruckNoList(truckNoList);

        IPage<IntegralTruckVO> page = integralTruckDao.driverPageTruckRank(param);

        truckNoList = page.getRecords().stream().map(item -> item.getTruckNo()).collect(Collectors.toList());
        if (!truckNoList.isEmpty()) {
            List<IntegralStatistics> statisticsList = integralStatisticsDao.selectListByStatisticsDateAndTruckNoList(time, truckNoList);
            Map<String, Integer> rankMap = statisticsList.stream().collect(Collectors.toMap(item -> item.getTruckNo(), item -> item.getRank()));
            Map<String, Integer> integralMap = statisticsList.stream().collect(Collectors.toMap(item -> item.getTruckNo(), item -> item.getIntegral()));

            for (IntegralTruckVO item : page.getRecords()) {
                item.setRank(rankMap.get(item.getTruckNo()));
                item.setIntegral(integralMap.get(item.getTruckNo()));
            }

            Map<String, IntegralTruckVO> truckMap = page.getRecords().stream().collect(Collectors.toMap(item -> item.getTruckNo(), item -> item));

            List<IntegralRecord> recordList = integralRecordDao.listByStatisticsDateAndTruckNoList(time, truckNoList);
            Map<String, List<IntegralRecord>> map = recordList.stream().collect(Collectors.groupingBy(item -> item.getTruckNo()));


            List<Integer> orderChildCompleteTypeList = Arrays.asList(
                    IntegralRecordEnum.Type.ORDER_CHILD_COMPLETE.getValue(),
                    IntegralRecordEnum.Type.ORDER_CHILD_COMPLETE_NUM.getValue(),
                    IntegralRecordEnum.Type.ORDER_CHILD_COMPLETE_WATER.getValue(),
                    IntegralRecordEnum.Type.ORDER_CHILD_COMPLETE_SUPPORT.getValue()
            );
            List<Integer> platformCompensationTypeList = Arrays.asList(
                    IntegralRecordEnum.Type.SYSTEM.getValue(),
                    IntegralRecordEnum.Type.PROTECTION.getValue(),
                    IntegralRecordEnum.Type.PROTECTION_CANCEL.getValue(),
                    IntegralRecordEnum.Type.SETTLEMENT.getValue(),
                    IntegralRecordEnum.Type.BASE.getValue(),

                    IntegralRecordEnum.Type.ORDER_CHILD_PLATFORM_CANCEL.getValue(),
                    IntegralRecordEnum.Type.ORDER_CHILD_PLATFORM_COMPENSATION.getValue()

            );
            List<Integer> orderChildCancelTypeList = Arrays.asList(
                    IntegralRecordEnum.Type.ORDER_CHILD_CANCEL.getValue()
            );
            List<Integer> orderChildTimeoutTypeList = Arrays.asList(
                    IntegralRecordEnum.Type.ORDER_CHILD_ARRIVE_RECEIVE_ADDRESS_TIMEOUT.getValue(),
                    IntegralRecordEnum.Type.ORDER_CHILD_ARRIVE_SEND_ADDRESS_TIMEOUT_CANCEL.getValue()
            );
            List<Integer> reportTypeList = Arrays.asList(

                    IntegralRecordEnum.Type.REPORT_REFUEL.getValue(),
                    IntegralRecordEnum.Type.REPORT_TRAFFIC.getValue(),
                    IntegralRecordEnum.Type.REPORT_SEND_ADDRESS_WAIT.getValue(),
                    IntegralRecordEnum.Type.REPORT_SEND_ADDRESS_NO_WAIT.getValue(),
                    IntegralRecordEnum.Type.REPORT_RECEIVE_ADDRESS_WAIT.getValue(),
                    IntegralRecordEnum.Type.REPORT_RECEIVE_ADDRESS_NO_WAIT.getValue(),
                    IntegralRecordEnum.Type.REPORT_QUALITY.getValue(),
                    IntegralRecordEnum.Type.REPORT_ABNORMAL.getValue(),
                    IntegralRecordEnum.Type.REPORT_SEND_ADDRESS_INFO.getValue(),

                    IntegralRecordEnum.Type.REPORT_TRUCK_INFO_OF_UNLOAD_TYPE.getValue(),
                    IntegralRecordEnum.Type.REPORT_TRUCK_INFO_OF_AUTO_LOAN.getValue(),
                    IntegralRecordEnum.Type.REPORT_TRUCK_INFO_OF_PARK_ADDRESS.getValue()
            );
            for (Map.Entry<String, List<IntegralRecord>> entry : map.entrySet()) {
                Integer orderChildCompleteIntegral = 0;
                Integer platformCompensationIntegral = 0;
                Integer orderChildCancelIntegral = 0;
                Integer orderChildTimeoutIntegral = 0;
                Integer reportIntegral = 0;

                for (IntegralRecord item : entry.getValue()) {
                    if (orderChildCompleteTypeList.contains(item.getType())){orderChildCompleteIntegral += item.getIntegral();}
                    if (platformCompensationTypeList.contains(item.getType())){platformCompensationIntegral += item.getIntegral();}
                    if (orderChildCancelTypeList.contains(item.getType())){orderChildCancelIntegral += item.getIntegral();}
                    if (orderChildTimeoutTypeList.contains(item.getType())){orderChildTimeoutIntegral += item.getIntegral();}
                    if (reportTypeList.contains(item.getType())){reportIntegral += item.getIntegral();}

                }

                IntegralTruckVO truck = truckMap.get(entry.getKey());
                truck.setOrderChildCompleteIntegral(orderChildCompleteIntegral);
                truck.setPlatformCompensationIntegral(platformCompensationIntegral);
                truck.setOrderChildCancelIntegral(orderChildCancelIntegral);
                truck.setOrderChildTimeoutIntegral(orderChildTimeoutIntegral);
                truck.setReportIntegral(reportIntegral);
            }

        }

        return page;
    }

}
