package com.xxfc.platform.vehicle.biz;

import com.ace.cache.annotation.Cache;
import com.ace.cache.annotation.CacheClear;
import com.github.wxiaoqi.security.common.biz.BaseBiz;
import com.github.wxiaoqi.security.common.exception.BaseException;
import com.github.wxiaoqi.security.common.msg.ObjectRestResponse;
import com.github.wxiaoqi.security.common.util.process.ResultCode;
import com.google.common.collect.Maps;
import com.xxfc.platform.vehicle.constant.ResCode.ResCode;
import com.xxfc.platform.vehicle.entity.VehicleBookHourInfo;
import com.xxfc.platform.vehicle.entity.VehicleBookRecord;
import com.xxfc.platform.vehicle.mapper.VehicleBookHourInfoMapper;
import com.xxfc.platform.vehicle.pojo.VehicleBookHourInfoDto;
import com.xxfc.platform.vehicle.pojo.VehicleDepartureLogVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
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 org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class VehicleBookHourInfoBiz extends BaseBiz<VehicleBookHourInfoMapper, VehicleBookHourInfo> {

    @Autowired
    private VehicleBookRecordBiz vehicleBookRecordBiz;
    @Autowired
    VehicleDepartureService vehicleDepartureService;

    public static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss");
    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");

    public Map<String, Integer> getPredictableHours(String bookStartDate, String bookEndDate, Boolean notCheckTimeLegal) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startDate = null;
        Date endDate = null;
        try {
            startDate = simpleDateFormat.parse(bookStartDate);
            endDate = simpleDateFormat.parse(bookEndDate);
        } catch (Exception e) {
            log.error(e.getMessage(), e);;
        }

        //判定时间是否合法
        if (!Boolean.TRUE.equals(notCheckTimeLegal)) {
            if (bookStartDate.compareTo(DateTime.now().toString(DEFAULT_DATE_TIME_FORMATTER)) < 0) {
                throw new BaseException(ResultCode.ONLY_BOOK_FROM_TODAY);
            }
        }
//        if (bookStartDate.compareTo(bookEndDate) >= 0) {
//            throw new BaseException(ResultCode.END_TIME_FROM_TODAY);
//        }
        Map<String, Integer> predictableHours = Maps.newHashMap();
        //预定开始小时
        int hour = new DateTime(startDate).hourOfDay().get();
        int endHour = new DateTime(endDate).hourOfDay().get();
        //获取开始天的预定小时
        int startPredictableHour = 0;
        for (int curentHour = hour; curentHour <= 23; curentHour++) {
            startPredictableHour |= 1 << (curentHour);
        }

        //获取结束天的预定小时
        int endPredictableHour = 0;
        for (int curentHour = 0; curentHour <= endHour; curentHour++) {
            endPredictableHour |= 1 << (curentHour);
        }
        DateTime startDay = DateTime.parse(DateTime.parse(bookStartDate, DEFAULT_DATE_TIME_FORMATTER).toString(DATE_TIME_FORMATTER), DATE_TIME_FORMATTER);
        DateTime endDay = DateTime.parse(DateTime.parse(bookEndDate, DEFAULT_DATE_TIME_FORMATTER).toString(DATE_TIME_FORMATTER), DATE_TIME_FORMATTER);
        if (startPredictableHour == 0) { //如果是0点就直接预订全天
            startPredictableHour = 16777215;
        }
        if (DateTime.parse(bookStartDate, DEFAULT_DATE_TIME_FORMATTER).toString(DATE_TIME_FORMATTER).equals(DateTime.parse(bookEndDate, DEFAULT_DATE_TIME_FORMATTER).toString(DATE_TIME_FORMATTER))) {//同一天预定
            //如果开始时间是0点开始
            predictableHours.put(DateTime.parse(bookStartDate, DEFAULT_DATE_TIME_FORMATTER).toString(DATE_TIME_FORMATTER), startPredictableHour & endPredictableHour);
        } else { //非同一天开始
            predictableHours.put(DateTime.parse(bookStartDate, DEFAULT_DATE_TIME_FORMATTER).toString(DATE_TIME_FORMATTER), startPredictableHour);
            predictableHours.put(DateTime.parse(bookEndDate, DEFAULT_DATE_TIME_FORMATTER).toString(DATE_TIME_FORMATTER), endPredictableHour);
        }
        if (endDay.getMillis() - startDay.getMillis() > 24 * 3600 * 1000) { //
            for (DateTime curDate = startDay.plusDays(1); curDate.compareTo(endDay) < 0; curDate = curDate.plusDays(1)) {
                String curDateStr = curDate.toString(DATE_TIME_FORMATTER);
                //全天预定
                predictableHours.put(curDateStr, 16777215);
            }
        }
        return predictableHours;
    }

    public List<VehicleBookHourInfo> selectByVehicleAndDate(VehicleBookHourInfoDto vehicleBookHourInfoDto) {
        return mapper.selectByVehicleAndDate(vehicleBookHourInfoDto);
    }

    @Cache(key = "vehicle.hourInfo")
    public VehicleBookHourInfo selectByVehicleAndId(VehicleBookHourInfoDto vehicleBookHourInfoDto) {
        return mapper.selectByVehicleAndId(vehicleBookHourInfoDto);
    }

    @Cache(key = "vehicle.hourInfo")
    public List<VehicleBookHourInfo> getAll() {
        return mapper.selectAll();
    }

    @Transactional
    @CacheClear(key = "vehicle.hourInfo")
    public ObjectRestResponse save(VehicleBookHourInfoDto vehicleBookHourInfoDto) {
        if (vehicleBookHourInfoDto == null) {
            return ObjectRestResponse.paramIsEmpty();
        }
        List<VehicleBookHourInfo> vehicleBookHourInfos = mapper.selectByVehicleAndDate(vehicleBookHourInfoDto);
        //有数据直接更新
        if (vehicleBookHourInfos.size() >= 1) {
            for (VehicleBookHourInfo vehicleBookHourInfo : vehicleBookHourInfos) {
                if (vehicleBookHourInfo.getBookedHour().equals(vehicleBookHourInfoDto.getBookedHour())) {
                    return ObjectRestResponse.createFailedResult(ResCode.VEHICLE_IS_BOOKED_TODAY.getCode(), ResCode.VEHICLE_IS_BOOKED_TODAY.getDesc());
                } else {
                    vehicleBookHourInfo.setBookedHour(vehicleBookHourInfo.getBookedHour() | vehicleBookHourInfoDto.getBookedHour());
                    updateSelectiveByIdRe(vehicleBookHourInfo);
                }
            }
            return ObjectRestResponse.succ();
        }
        //没有数据直接添加
        insertSelectiveRe(vehicleBookHourInfoDto);
        return ObjectRestResponse.succ();
    }

    /**
     * 删除预定车辆小时记录信息
     *
     * @param vehicleId 车辆Id
     * @param dateList  日期列表
     * @return
     */
    @Transactional
    @CacheClear(key = "vehicle.hourInfo")
    public ObjectRestResponse delete(String vehicleId, List<String> dateList) {
        if (StringUtils.isBlank(vehicleId) || dateList.size() <= 0) {
            return ObjectRestResponse.paramIsEmpty();
        }
        Map<String, Object> param = Maps.newHashMap();
        param.put("vehicleId", vehicleId);
        param.put("list", dateList);
        List<VehicleBookHourInfo> list = mapper.selectByVehicleAndDateList(param);
        list.forEach((a) -> mapper.delete(a));
        return ObjectRestResponse.succ();
    }

    public ObjectRestResponse checkBookHourInfo() {
        List<VehicleBookHourInfoDto> vehicleBookHourInfos = new ArrayList<>();
        List<VehicleBookRecord> list = vehicleBookRecordBiz.selectListAll();
        if (CollectionUtils.isNotEmpty(list)) {
            for (VehicleBookRecord vehicleBookRecord : list) {
                VehicleDepartureLogVo vehicleDepartureLog = vehicleDepartureService.getByRecordId(vehicleBookRecord.getId());
                if ((vehicleDepartureLog == null || vehicleDepartureLog.getState() != 1) && (vehicleBookRecord.getStatus() == 2 || vehicleBookRecord.getStatus() == 1)) { //未出车或未还车
                    Map<String, Integer> map = getPredictableHours(new DateTime(vehicleBookRecord.getBookStartDate()).toString(DEFAULT_DATE_TIME_FORMATTER), new DateTime(vehicleBookRecord.getBookEndDate()).toString(DEFAULT_DATE_TIME_FORMATTER), Boolean.TRUE);
                    for (Map.Entry<String, Integer> entry : map.entrySet()) {
                        VehicleBookHourInfoDto vehicleBookHourInfoDto = new VehicleBookHourInfoDto();
                        vehicleBookHourInfoDto.setVehicleId(vehicleBookRecord.getVehicleId());
                        vehicleBookHourInfoDto.setYearMonthDay(entry.getKey());
                        vehicleBookHourInfoDto.setBookedHour(entry.getValue());
                        save(vehicleBookHourInfoDto);
                        vehicleBookHourInfos.add(vehicleBookHourInfoDto);
//                        vehicleBookHourInfoDto.setVehicleId(vehicleBookRecord.getVehicleId());
//                        vehicleBookHourInfoDto.setYearMonthDay(entry.getKey());
//                        List<VehicleBookHourInfo> vehicleBookHourInfoList = mapper.selectByVehicleAndDate(vehicleBookHourInfoDto);
//                        log.info("获取到的小时信息： vehicleBookHourInfoList = {}", vehicleBookHourInfoList);
//                        if(CollectionUtils.isNotEmpty(vehicleBookHourInfoList)) {
//                            if(entry.getValue() == 0){ //0点
//                                vehicleBookHourInfoList.get(0).setBookedHour(vehicleBookHourInfoList.get(0).getBookedHour() | 1);
//                                updateSelectiveByIdRe(vehicleBookHourInfoList.get(0));
//                            } else {
//                                if((vehicleBookHourInfoList.get(0).getBookedHour() & entry.getValue()) == entry.getValue()) {
//                                    log.info("已经预订时间正确，右移一位，原数据为：{}， 修改后的数据为： {}", vehicleBookHourInfoList.get(0).getBookedHour(), vehicleBookHourInfoList.get(0).getBookedHour() >> 1);
//                                    vehicleBookHourInfoList.get(0).setBookedHour(vehicleBookHourInfoList.get(0).getBookedHour() >> 1);
//                                    updateSelectiveByIdRe(vehicleBookHourInfoList.get(0));
//                                } else {
//                                    vehicleBookHourInfos.add(vehicleBookRecord);
//                                }
//                            }
//                        } else { //如果数据不存在就补充进去
//                            VehicleBookHourInfoDto vehicleBookHourInfoDto1 = new VehicleBookHourInfoDto();
//                            vehicleBookHourInfoDto1.setVehicleId(vehicleBookRecord.getVehicleId());
//                            vehicleBookHourInfoDto1.setYearMonthDay(entry.getKey());
//                            vehicleBookHourInfoDto1.setBookedHour(entry.getValue());
//                            vehicleBookHourInfoDto1.setBookRecordId(vehicleBookRecord.getId());
//                            save(vehicleBookHourInfoDto1);
//                        }
                    }
                }
            }
        }
        return ObjectRestResponse.succ(vehicleBookHourInfos);
    }


    public static void main(String[] args) throws Exception {
        VehicleBookHourInfoBiz vehicleBookHourInfoBiz = new VehicleBookHourInfoBiz();
        Map<String, Integer> map = vehicleBookHourInfoBiz.getPredictableHours("2019-08-26 10:00:00", "2019-08-27 10:00:00", Boolean.TRUE);
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
        }
        Integer a = 215712192 & 33554432;
        System.out.println(a);
    }

}
