package com.xxfc.platform.vehicle.biz;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.github.wxiaoqi.security.admin.entity.BaseUserMember;
import com.github.wxiaoqi.security.admin.feign.UserFeign;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.xxfc.platform.vehicle.entity.Vehicle;
import com.xxfc.platform.vehicle.entity.VehicleCommonPriceInfo;
import com.xxfc.platform.vehicle.entity.VehicleHolidayPriceInfo;
import com.xxfc.platform.vehicle.mapper.VehicleHolidayPriceInfoMapper;
import com.xxfc.platform.vehicle.pojo.dto.VehicleModelCalendarPriceDTO;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.util.*;

/**
 * 车辆节假日价格信息表
 *
 * @author libin
 * @email 18178966185@163.com
 * @date 2020-05-11 09:16:23
 */
@Service
@Slf4j
public class VehicleHolidayPriceInfoBiz extends BaseBiz<VehicleHolidayPriceInfoMapper, VehicleHolidayPriceInfo> {
	private static final Integer DEFAULT_DISCOUNT = 100;
	private static final Integer DEFAULT_FREE_DAYS = 1;
	private static final Integer DEFAULT_MEMBER_LEVEL = 0;
	private static final Integer DEFAULT_MEMBER_TYPE = 0;

	private static final Integer MEMBER_TYPE_ALL = 1;
	private static final Integer MEMBER_TYPE_REGISTER = 2;
	private static final Integer MEMBER_TYPE_EXCHANGE = 3;
	private static final Integer MEMBER_TYPE_FORBID = 4;

	public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");

	@Autowired
	VehicleBiz vehicleBiz;

	@Autowired
	UserFeign userFeign;


	@Autowired
	VehicleCommonPriceInfoBiz vehicleCommonPriceInfoBiz;

	public ObjectRestResponse addOrUpdate(VehicleHolidayPriceInfo vehicleHolidayPriceInfo ) {
		if (vehicleHolidayPriceInfo == null) {
			return ObjectRestResponse.paramIsEmpty();
		}
		Vehicle vehicle = vehicleBiz.get(vehicleHolidayPriceInfo.getVehicleId());
		if (vehicle == null) {
			return ObjectRestResponse.createFailedResult(ResultCode.FAILED_CODE, "车辆不存在！");
		}
		vehicleHolidayPriceInfo.setCompanyId(vehicle.getSubordinateBranch());
		List<Vehicle> vehicleList = null;
		if (vehicleHolidayPriceInfo.getAllVehicleUse() != null && vehicleHolidayPriceInfo.getAllVehicleUse() == 1) {//所有车辆可用
			vehicleList = vehicleBiz.getAllVehicleByCompanyId(vehicle.getSubordinateBranch(), null);
		}
		if (vehicleHolidayPriceInfo.getAllModelUse() != null && vehicleHolidayPriceInfo.getAllModelUse() == 1) {//所有车型可用
			vehicleList = vehicleBiz.getAllVehicleByCompanyId(vehicle.getSubordinateBranch(), null);
		}
		if (vehicleList == null || vehicleList.size() <= 0) { //单个车辆可用
			for(String date : getAllDate(vehicleHolidayPriceInfo.getStartDate(), vehicleHolidayPriceInfo.getEndDate())) {
				vehicleHolidayPriceInfo.setFestivalDate(DateTime.parse(date, DATE_TIME_FORMATTER).toDate());
				VehicleHolidayPriceInfo oldValue = getByVehicleId(vehicleHolidayPriceInfo.getVehicleId(),  date);
				if (oldValue == null) {
					vehicleHolidayPriceInfo.setId(null);
					insertSelectiveRe(vehicleHolidayPriceInfo);
				} else {
					BeanUtil.copyProperties(vehicleHolidayPriceInfo, oldValue, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
					updateSelectiveByIdRe(oldValue);
				}
			}

		}  else {
			vehicleList.parallelStream().forEach(vehicleInfo -> {
				if (vehicleInfo != null) {
					for(String date : getAllDate(vehicleHolidayPriceInfo.getStartDate(), vehicleHolidayPriceInfo.getEndDate())) {
						VehicleHolidayPriceInfo oldValue = getByVehicleId(vehicleInfo.getId(),  date);
						vehicleHolidayPriceInfo.setFestivalDate(DateTime.parse(date, DATE_TIME_FORMATTER).toDate());
						vehicleHolidayPriceInfo.setVehicleId(vehicleInfo.getId());
						vehicleHolidayPriceInfo.setCompanyId(vehicleInfo.getSubordinateBranch());
						vehicleHolidayPriceInfo.setModelId(vehicleInfo.getModelId());
						vehicleHolidayPriceInfo.setId(null);
						if (oldValue == null ) {
							insertSelectiveRe(vehicleHolidayPriceInfo);
						} else {
							BeanUtil.copyProperties(vehicleHolidayPriceInfo, oldValue, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
							updateSelectiveByIdRe(oldValue);
						}
					}
				}

			});
		}
		return ObjectRestResponse.succ();
	}

	public VehicleHolidayPriceInfo getByVehicleId(String vehicleId, String date) {
		Example example = new Example(VehicleHolidayPriceInfo.class);
		example.createCriteria().andEqualTo("vehicleId", vehicleId).andEqualTo("festivalDate", date);
		return mapper.selectOneByExample(example);
	}


	//获取所有车的价格
	public ObjectRestResponse<List<VehicleHolidayPriceInfo>> getAllByVehicleIds(List<VehicleHolidayPriceInfo> list) {
		if (list == null) {
			return ObjectRestResponse.paramIsEmpty();
		}
		List<VehicleHolidayPriceInfo> vehicleHolidayPriceInfoList = new ArrayList<>();
		if (list.size() > 0) {
			for (VehicleHolidayPriceInfo vehicleHolidayPriceInfo : list) {
				vehicleHolidayPriceInfoList.addAll(getByVehicleIdAndDate(vehicleHolidayPriceInfo.getVehicleId(), vehicleHolidayPriceInfo.getStartDate(), vehicleHolidayPriceInfo.getEndDate()));
			}
		}
		return ObjectRestResponse.succ(vehicleHolidayPriceInfoList);
	}


	public List<VehicleHolidayPriceInfo> getByVehicleIdAndDate (String vehicleId, String startDate, String endDate) {
		Example example = new Example(VehicleHolidayPriceInfo.class);
		example.createCriteria().andEqualTo("vehicleId", vehicleId).andBetween("festivalDate", startDate, endDate);
		return mapper.selectByExample(example);
	}

	public List<VehicleModelCalendarPriceDTO> getSynthesizePrice (String vehicleId, String startDate, String endDate, Integer userId, Integer companyId) {
		List<VehicleModelCalendarPriceDTO> priceDTOS = CollUtil.newArrayList();
		cn.hutool.core.date.DateTime beginOfStartDate = DateUtil.beginOfDay(DateUtil.parse(startDate));
		cn.hutool.core.date.DateTime endOfStartDate = DateUtil.endOfDay(DateUtil.parse(endDate));
		//获取基本和周末价格
		VehicleCommonPriceInfo vehicleCommonPriceInfo = vehicleCommonPriceInfoBiz.selectOne(new VehicleCommonPriceInfo(){{
			setCompanyId(companyId);
			setVehicleId(vehicleId);
		}});

		//Date currentDate = DateUtil.beginOfDay(DateUtil.parse(startDate));
		for(cn.hutool.core.date.DateTime currentDate = DateUtil.beginOfDay(DateUtil.parse(startDate));
			(currentDate.isAfterOrEquals(beginOfStartDate) || currentDate.isBeforeOrEquals(endOfStartDate));
			currentDate = DateUtil.offsetDay(currentDate, 1)) {
			cn.hutool.core.date.DateTime finalCurrentDate = currentDate;
			VehicleModelCalendarPriceDTO dto = new VehicleModelCalendarPriceDTO(){{
				setDate(DateUtil.beginOfDay(finalCurrentDate));
			}};
			if(currentDate.isWeekend()) {
				dto.setNo_discount_price(vehicleCommonPriceInfo.getRentWeekendPrice());
				dto.setPrice(vehicleCommonPriceInfo.getRentWeekendPrice());
				dto.setFreeDays(vehicleCommonPriceInfo.getRentWeekendDay());
			}else {
				dto.setNo_discount_price(vehicleCommonPriceInfo.getRentPrice());
				dto.setPrice(vehicleCommonPriceInfo.getRentPrice());
				dto.setFreeDays(vehicleCommonPriceInfo.getRentFreeDay());
			}

			priceDTOS.add(dto);
		}

		//获取节假日价格
		List<VehicleHolidayPriceInfo> vehicleHolidayPriceInfoList = getByVehicleIdAndDate(vehicleId, startDate, endDate);

		if(CollUtil.isNotEmpty(vehicleHolidayPriceInfoList)) {
			vehicleHolidayPriceInfoList.forEach(info -> {
				priceDTOS.forEach(tmpDto -> {
					if(DateUtil.isSameDay(info.getFestivalDate(), tmpDto.getDate())) {
						tmpDto.setNo_discount_price(info.getRentPrice());
						tmpDto.setPrice(info.getRentPrice());
						tmpDto.setFreeDays(info.getRentFreeDay());
					}
				});
			});
		}


		//获取会员折扣
			//查询车辆信息
		Vehicle vehicle = vehicleBiz.selectById(vehicleId);
			//查询会员信息
		//默认折扣
		Integer discount = DEFAULT_DISCOUNT;
		//会员默认等级
		Integer memberLevel = DEFAULT_MEMBER_LEVEL;
		Integer memberType = DEFAULT_MEMBER_TYPE;
		if (Objects.nonNull(userId)) {
			BaseUserMember baseUserMember = userFeign.findBaseUserMemberByUserId(userId.intValue());
			log.info("用户会员信息:【{}】",baseUserMember);
			discount = baseUserMember == null ? discount : baseUserMember.getDiscount();
			memberLevel = baseUserMember == null ? memberLevel : baseUserMember.getMemberLevel();
			memberType = baseUserMember == null ? memberType : baseUserMember.getMemberType();
		}

		//非会员禁用 非无会员
		if(vehicle.getMemberUse() != MEMBER_TYPE_FORBID && DEFAULT_MEMBER_TYPE != memberType) {
			//判断 允许所有会员，或者 memberType 和 车辆memberUse 相等
			if(vehicle.getMemberUse().equals(MEMBER_TYPE_ALL) || (vehicle.getMemberUse().equals(memberType))) {
				//设置会员价格
				Integer finalDiscount = discount;
				priceDTOS.forEach(dto -> {
					dto.setPrice(dto.getNo_discount_price()
							.multiply(new BigDecimal(""+ finalDiscount)
									.divide(new BigDecimal("100"))));
				});
			}
		}

		return priceDTOS;
	}


	//获取当前车辆所有的节日价格
	public ObjectRestResponse<List<VehicleHolidayPriceInfo>> getByVehicleId (String vehicleId) {
		Example example = new Example(VehicleHolidayPriceInfo.class);
		example.createCriteria().andEqualTo("vehicleId", vehicleId);
		return ObjectRestResponse.succ(mapper.selectByExample(example));
	}


	public ObjectRestResponse getAll(Integer festivalId) {
		return ObjectRestResponse.succ(mapper.getAll(festivalId));
	}



	public static Set<String> getAllDate(String startDate, String endDate) {
		Set<String> list = new HashSet<>();
		DateTime startTime = DateTime.parse(startDate, DATE_TIME_FORMATTER);
		DateTime endTime = DateTime.parse(endDate, DATE_TIME_FORMATTER);
		list.add(startDate);
		list.add(endDate);
		if (endTime.getMillis() - startTime.getMillis() > 24 * 3600 * 1000) { //
			for (DateTime curDate = startTime.plusDays(1); curDate.compareTo(endTime) < 0; curDate = curDate.plusDays(1)) {
				list.add(curDate.toString(DATE_TIME_FORMATTER));
			}
		} else {
			list.add(startDate);
		}
		return list;
	}
}