package org.dromara.system.service.impl;

import cn.hutool.core.util.StrUtil;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.redis.utils.RedisUtils;
import org.springframework.stereotype.Service;
import org.dromara.system.domain.bo.TblCarScheduleBo;
import org.dromara.system.domain.vo.TblCarScheduleVo;
import org.dromara.system.domain.TblCarSchedule;
import org.dromara.system.mapper.TblCarScheduleMapper;
import org.dromara.system.service.ITblCarScheduleService;

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

import static jt809.handle.JT809Packet0x1202Handle.convertToPinyin;

/**
 * 车及人员排班Service业务层处理
 *
 * @author Lion Li
 * @date 2024-02-22
 */
@RequiredArgsConstructor
@Service
public class TblCarScheduleServiceImpl implements ITblCarScheduleService {

    private final TblCarScheduleMapper baseMapper;

    /**
     * 查询车及人员排班
     */
    @Override
    public TblCarScheduleVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询车及人员排班列表
     */
    @Override
    public TableDataInfo<TblCarScheduleVo> queryPageList(TblCarScheduleBo bo, PageQuery pageQuery) {
        if(bo.getParams()!=null && bo.getParams().get("getallday")!=null){
           List<String> data =  baseMapper.getScheduleDay();
           List<TblCarScheduleVo> dr =  data.stream().map(e -> {
               TblCarScheduleVo tblCarSchedule = new TblCarScheduleVo();
               tblCarSchedule.setScheduleDate(DateUtils.parseDate(e));
               return tblCarSchedule;
           }).toList();
            return TableDataInfo.build(dr);
        }
        LambdaQueryWrapper<TblCarSchedule> lqw = buildQueryWrapper(bo);
        Page<TblCarScheduleVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        result.getRecords().forEach(e -> {
            try{
                e.setCarlocation(RedisUtils.getCacheObject(StringUtils.format("gps_{}", convertToPinyin(e.getCarNum().trim()))));
            }catch (Exception e1){}

            String stations = RedisUtils.getCacheObject(StringUtils.format("car_{}_{}_current_station",e.getCarNum(), DateFormatUtils.format( e.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS)));
            String stationName =  RedisUtils.getCacheObject(StringUtils.format("car_{}_{}_tip",e.getCarNum(),DateFormatUtils.format( e.getScheduleDate(),DateUtils.YYYYMMDDHHMMSS) ));
//            String gpsinfo = RedisUtils.getCacheObject(StringUtils.format("gps_{}", id));
            e.setStationInfo(StringUtils.format("{\"currentStation\":\"{}\",\"passStations\":\"{}\"}",stations,stationName));
        });


        return TableDataInfo.build(result);
    }




    /**
     * 查询车及人员排班列表
     */
    @Override
    public List<TblCarScheduleVo> queryList(TblCarScheduleBo bo) {
        LambdaQueryWrapper<TblCarSchedule> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TblCarSchedule> buildQueryWrapper(TblCarScheduleBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TblCarSchedule> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getPathInfo()), TblCarSchedule::getPathInfo, bo.getPathInfo());
        lqw.like(StringUtils.isNotBlank(bo.getCarNum()), TblCarSchedule::getCarNum, bo.getCarNum());
        lqw.eq(bo.getScheduleDate() != null, TblCarSchedule::getScheduleDate, bo.getScheduleDate());
        if(bo.getParams()!=null && bo.getParams().keySet().size()>0){



            try{
                if(bo.getParams().get("cars")!=null&& StrUtil.isNotEmpty(bo.getParams().get("cars").toString())){
                    String cars = Arrays.stream(bo.getParams().get("cars").toString().split(",")).map(deptId->{return StrUtil.format("'{}'",deptId); }).collect(Collectors.joining(","));
                    lqw.apply(StringUtils.format("car_num in ({})",cars));
                }
            }catch (Exception e){}




            if(bo.getParams().get("station")!=null){
                lqw.like(bo.getParams().get("station")!=null, TblCarSchedule::getPathInfo, bo.getParams().get("station"));
            }
            if(bo.getParams().get("station")!=null){
                lqw.like(bo.getParams().get("station")!=null, TblCarSchedule::getPathInfo, bo.getParams().get("station"));
            }
            if(bo.getParams().get("scheduleDate")!=null){
                try{
                    String start= bo.getParams().get("scheduleDate").toString();
                    String end= bo.getParams().get("scheduleDate").toString();
                    if(bo.getParams().get("scheduleDate").toString().contains(" ")){

                    }else{
                        start+=" 00:00:00";
                        end+=" 23:59:59";
                    }
                    lqw.ge(bo.getParams().get("scheduleDate")!=null, TblCarSchedule::getScheduleDate, start);
                    lqw.le(bo.getParams().get("scheduleDate")!=null, TblCarSchedule::getScheduleDate, end);

                }catch (Exception e){}
            }
            if(bo.getParams().get("starttime")!=null && bo.getParams().get("endtime")!=null){
                lqw.gt(bo.getParams().get("starttime")!=null, TblCarSchedule::getScheduleDate, bo.getParams().get("starttime"));
                lqw.lt(bo.getParams().get("endtime")!=null, TblCarSchedule::getScheduleDate, bo.getParams().get("endtime"));
            }
            if(bo.getParams().get("driverInfo")!=null){


                lqw.apply(StringUtils.format("path_info->'$.driverInfo'={}",bo.getParams().get("driverInfo")));

            }




        }
        lqw.orderBy(true,true,TblCarSchedule::getScheduleDate);
        return lqw;
    }

    /**
     * 新增车及人员排班
     */
    @Override
    public Boolean insertByBo(TblCarScheduleBo bo) {
        TblCarSchedule add = MapstructUtils.convert(bo, TblCarSchedule.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改车及人员排班
     */
    @Override
    public Boolean updateByBo(TblCarScheduleBo bo) {
        TblCarSchedule update = MapstructUtils.convert(bo, TblCarSchedule.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TblCarSchedule entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除车及人员排班
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
