package com.xxfc.platform.order.biz;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.xxfc.platform.order.Utils.OrderDateUtils;
import com.xxfc.platform.order.biz.inner.OrderCalculateBiz;
import com.xxfc.platform.order.contant.enumerate.CrosstownTypeEnum;
import com.xxfc.platform.order.contant.enumerate.OrderStatusEnum;
import com.xxfc.platform.order.entity.OrderVehicleServiceStatistics;
import com.xxfc.platform.order.mapper.OrderVehicleServiceStatisticsMapper;
import com.xxfc.platform.order.pojo.CountVehicleServiceNumVo;
import com.xxfc.platform.order.pojo.order.OrderPageVO;
import com.xxfc.platform.order.pojo.order.OrderVehicleCrosstownDto;
import com.xxfc.platform.universal.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class OrderVehicleServiceStatisticsBiz extends BaseBiz<OrderVehicleServiceStatisticsMapper, OrderVehicleServiceStatistics> {

	@Autowired
	BaseOrderBiz baseOrderBiz;
	@Autowired
	OrderVehicleCrosstownBiz orderVehicleCrosstownBiz;
	@Autowired
	OrderCalculateBiz orderCalculateBiz;
	Map<Integer, Map<String, Integer>> mapMap = new HashMap<>();

	//获取订单，解析租车天数
	//根据订单状态，待出行的添加一天，出行中的加一天，已完成的判断订单时间和实际结束时间如果实际结束天数大于订单天数，则需要加一天
	public void getAllOrder(DateTime dateTime) {
		Date nowTime = DateTime.now().minusDays(1).toDate();
		if (dateTime != null) {
			nowTime = dateTime.minusDays(1).toDate();
		}
		String timeStr = DateUtil.dateToStr(nowTime, "yyyy-MM-dd");
		//以公司ID为key, 日期+次数为value组成map
		Map<String, Object> param = new HashMap<>();
		param.put("startTime", OrderDateUtils.getStartOfDay(nowTime));
		param.put("endTime", OrderDateUtils.getEndOfDay(nowTime));
		param.put("status", 1);
		List<OrderPageVO> orderPageVOS = baseOrderBiz.selectAllRentVehicleOrder(param);
		if (orderPageVOS != null && orderPageVOS.size() > 0) {
			orderPageVOS.parallelStream().forEach(result -> {
				if (result.getOrderRentVehicleDetail() != null) {
					Map<String, Integer> dateNumMap = mapMap.getOrDefault(result.getOrderRentVehicleDetail().getStartCompanyId(), new HashMap<>());
					if (result.getStatus() == OrderStatusEnum.ORDER_TOSTART.getCode() || result.getStatus() == OrderStatusEnum.ORDER_WAIT.getCode()) {//待出行或者出行中
						dateNumMap.put(timeStr, dateNumMap.getOrDefault(timeStr, 0) + 1);
					}
					if (result.getStatus() == OrderStatusEnum.ORDER_TOSTART.getCode() || result.getStatus() == OrderStatusEnum.ORDER_FIXED_LOSS.getCode()) {//已完成或者定损中
						//判断租车时间是否小于实际用车时间
						//实际预定天数
						Integer bookDays = result.getOrderRentVehicleDetail().getDayNum();
						//实际使用天数
						Integer actualUsedDays = result.getOrderRentVehicleDetail().getUsedDay();
						Long startTime = result.getOrderRentVehicleDetail().getStartTime();
						if (actualUsedDays == null) {//字段为空，重新计算天数
							//查询还车时间
							OrderVehicleCrosstownDto orderVehicleCrosstownDto = new OrderVehicleCrosstownDto();
							orderVehicleCrosstownDto.setOrderId(result.getId());
							List<OrderVehicleCrosstownDto> list = orderVehicleCrosstownBiz.selectByOrderId(orderVehicleCrosstownDto);
							if(list != null && list.size() > 0) {
								list.parallelStream().forEach(order -> {
									//获取还车时间
									if (order.getType() == CrosstownTypeEnum.ARRIVE.getCode() || order.getType() == CrosstownTypeEnum.FIXED_LOSS.getCode() || order.getType() == CrosstownTypeEnum.FIXED_LOSS_NOW.getCode()) {
										Long endTime = order.getCrtTime();
										int userUsedDay = orderCalculateBiz.getIncludeDays(startTime, endTime);
										if (bookDays < userUsedDay) { //实际使用天数>预定天数，还车当天+1
											dateNumMap.put(timeStr, dateNumMap.getOrDefault(timeStr, 0) + 1);
										}
									}
								});
							} else { //还车记录不存在，异常数据
								log.info("还车记录不存在，异常数据, {}", result.toString());
							}
						}
					}
					mapMap.put(result.getOrderRentVehicleDetail().getStartCompanyId(), dateNumMap);
				}
			});
		}
		log.info("统计数据，Map = {}", mapMap);
	}


	public void countVehicleServiceNum(DateTime dateTime) {
		Date nowTime = DateTime.now().minusDays(1).toDate();
		if (dateTime != null) {
			nowTime = dateTime.minusDays(1).toDate();
		}
		Map<String, Object> map = new HashMap<>();
		map.put("startTime", OrderDateUtils.getStartOfDay(nowTime));
		map.put("endTime", OrderDateUtils.getEndOfDay(nowTime));
		List<CountVehicleServiceNumVo> list = mapper.countVehicleServiceNum(map);
		if (list != null && list.size() > 0) {
			list.parallelStream().forEach(result -> {
				OrderVehicleServiceStatistics orderVehicleServiceStatistics = new OrderVehicleServiceStatistics();
				log.info(result.toString());
				BeanUtil.copyProperties(result, orderVehicleServiceStatistics, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
				String dateStr = result.getCountYear() +"-"+ result.getCountMonth() +"-"+ result.getCountDay();
				DateTime date = DateTime.parse(dateStr);
				orderVehicleServiceStatistics.setCountDate(date.toDate());
				orderVehicleServiceStatistics.setCountMonth(result.getCountYear() + result.getCountMonth());
				orderVehicleServiceStatistics.setCountWeek(result.getCountYear() + result.getCountWeek());
				add(orderVehicleServiceStatistics);
			});
		}
	}

	public void add(OrderVehicleServiceStatistics orderVehicleServiceStatistics) {
		if(orderVehicleServiceStatistics != null) {
			OrderVehicleServiceStatistics oldValue = mapper.selectByCompanyIdAndDate(orderVehicleServiceStatistics);
			if (oldValue == null) {
				insertSelectiveRe(orderVehicleServiceStatistics);
			} else {
				if (orderVehicleServiceStatistics.getArrivalNum() != null) {
					orderVehicleServiceStatistics.setArrivalNum(orderVehicleServiceStatistics.getArrivalNum() + oldValue.getArrivalNum());
				}
				if (orderVehicleServiceStatistics.getDepartureNum() != null) {
					orderVehicleServiceStatistics.setDepartureNum(orderVehicleServiceStatistics.getDepartureNum() + oldValue.getDepartureNum());
				}
				if (orderVehicleServiceStatistics.getRentNum() != null) {
					orderVehicleServiceStatistics.setRentNum(orderVehicleServiceStatistics.getRentNum() + oldValue.getRentNum());
				}
				BeanUtil.copyProperties(orderVehicleServiceStatistics, oldValue, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
				updateSelectiveByIdRe(oldValue);
			}
		}
	}

	//添加记录
	public void addAll() {
		DateTime dateTime = DateTime.parse("2019-08-01");
		for(DateTime curDate = dateTime.plusDays(1); curDate.compareTo(DateTime.now()) < 0; curDate = curDate.plusDays(1)) {
			countVehicleServiceNum(curDate);
			getAllOrder(curDate);
		}
		if (MapUtils.isNotEmpty(mapMap)) {
			for (Map.Entry<Integer, Map<String, Integer>> entry : mapMap.entrySet()) {
				if (MapUtils.isNotEmpty(entry.getValue())) {
					OrderVehicleServiceStatistics orderVehicleServiceStatistics = new OrderVehicleServiceStatistics();
					orderVehicleServiceStatistics.setCompanyId(entry.getKey());
					for (Map.Entry<String, Integer> values : entry.getValue().entrySet()) {
						if (StringUtils.isNotBlank(values.getKey()) && StringUtils.isNotBlank(values.getValue() + "")) {
							DateTime dateTime1 = DateTime.parse(values.getKey());
							orderVehicleServiceStatistics.setCountDate(dateTime1.toDate());
							orderVehicleServiceStatistics.setRentNum(values.getValue());
							orderVehicleServiceStatistics.setCountYear(dateTime1.getYear() + "");
							orderVehicleServiceStatistics.setCountMonth(dateTime1.getYear() + "" + dateTime1.getMonthOfYear() + "");
							orderVehicleServiceStatistics.setCountWeek(dateTime1.getYear() + "" + dateTime1.getWeekOfWeekyear() + "");
							add(orderVehicleServiceStatistics);
						}
					}
				}
			}
		}
		mapMap.clear();
	}

	//添加记录
	@Scheduled(cron = "0 0 2 * * *")
	public void add() {
		countVehicleServiceNum(DateTime.now());
		getAllOrder(DateTime.now());
		if (MapUtils.isNotEmpty(mapMap)) {
			for (Map.Entry<Integer, Map<String, Integer>> entry : mapMap.entrySet()) {
				if (MapUtils.isNotEmpty(entry.getValue())) {
					OrderVehicleServiceStatistics orderVehicleServiceStatistics = new OrderVehicleServiceStatistics();
					orderVehicleServiceStatistics.setCompanyId(entry.getKey());
					for (Map.Entry<String, Integer> values : entry.getValue().entrySet()) {
						if (StringUtils.isNotBlank(values.getKey()) && StringUtils.isNotBlank(values.getValue() + "")) {
							DateTime dateTime1 = DateTime.parse(values.getKey());
							orderVehicleServiceStatistics.setCountDate(dateTime1.toDate());
							orderVehicleServiceStatistics.setRentNum(values.getValue());
							orderVehicleServiceStatistics.setCountYear(dateTime1.getYear() + "");
							orderVehicleServiceStatistics.setCountMonth(dateTime1.getYear() + "" + dateTime1.getMonthOfYear() + "");
							orderVehicleServiceStatistics.setCountWeek(dateTime1.getYear() + "" + dateTime1.getWeekOfWeekyear() + "");
							add(orderVehicleServiceStatistics);
						}
					}
				}
			}
		}
		mapMap.clear();
	}

}
