package com.yc.ship.module.resource.service.guidecheckin;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.yc.ship.framework.common.pojo.CommonResult;
import com.yc.ship.framework.common.pojo.PageParam;
import com.yc.ship.framework.common.pojo.PageResult;
import com.yc.ship.framework.common.util.date.DateUtils;
import com.yc.ship.framework.common.util.object.BeanUtils;
import com.yc.ship.framework.dict.core.DictFrameworkUtils;
import com.yc.ship.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.yc.ship.framework.mybatis.core.util.MyBatisUtils;
import com.yc.ship.module.resource.controller.admin.guide.vo.GuidePageReqVO;
import com.yc.ship.module.resource.controller.admin.guidecheckin.vo.GuideCheckInPageReqVO;
import com.yc.ship.module.resource.controller.admin.guidecheckin.vo.GuideCheckInRespVO;
import com.yc.ship.module.resource.controller.admin.guidecheckin.vo.GuideCheckInSaveReqVO;
import com.yc.ship.module.resource.dal.dataobject.guide.GuideDO;
import com.yc.ship.module.resource.dal.dataobject.guidecheckin.GuideCheckInDO;
import com.yc.ship.module.resource.dal.mysql.guidecheckin.GuideCheckInMapper;
import com.yc.ship.module.resource.enums.DeleteStatusEnum;
import com.yc.ship.module.resource.enums.DictTypeConstants;
import com.yc.ship.module.resource.enums.UseStatusEnum;
import com.yc.ship.module.resource.enums.guide.GuideCheckInTypeEnum;
import com.yc.ship.module.resource.helper.DateHelper;
import com.yc.ship.module.resource.service.guide.GuideService;
import com.yc.ship.module.system.api.dict.DictDataApi;
import com.yc.ship.module.system.api.dict.dto.DictDataRespDTO;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import static com.yc.ship.framework.common.pojo.PageParam.PAGE_SIZE_NONE;


/**
 * 导游出勤 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
public class GuideCheckInServiceImpl implements GuideCheckInService {

    @Resource
    private GuideCheckInMapper guideCheckInMapper;
    @Resource
    private GuideService guideService;
//    @Resource
//    private DriverService driverService;

//    @Resource
//    private CarDispatchCarMapper carDispatchCarMapper;
//    @Resource
//    private DriverShiftMapper driverShiftMapper;
//    @Resource
//    private CarService carService;

//    @Resource
//    private LeaveApplyMapper leaveApplyMapper;
//    @Resource
//    private CarDispatchMapper carDispatchMapper;
//    @Resource
//    private GuideDispatchMapper guideDispatchMapper;
//    @Resource
//    private WarnMsgService warnMsgService;
    @Resource
    private DictDataApi dictDataApi;

    @Override
    public String createGuideCheckIn(GuideCheckInSaveReqVO createReqVO) {
        // 插入
        GuideCheckInDO guideCheckIn = BeanUtils.toBean(createReqVO, GuideCheckInDO.class);
        String[] checkTimes = createReqVO.getCheckTimeStr().split(",");
        List<LocalDate> dateList = DateUtils.getDatesBetween(LocalDate.parse(checkTimes[0]), LocalDate.parse(checkTimes[1]));
        for (LocalDate date : dateList) {
            guideCheckIn.setCheckTime(date);
            //查询该日期是否有考勤记录
            GuideCheckInDO checkInDO = guideCheckInMapper.selectOne(new LambdaQueryWrapperX<GuideCheckInDO>()
                    .eqIfPresent(GuideCheckInDO::getCheckTime, date)
                    .eqIfPresent(GuideCheckInDO::getGuideId, guideCheckIn.getGuideId())
            );
            if (null == checkInDO) {
                guideCheckIn.setId(IdWorker.getIdStr());
                guideCheckIn.setDeleted(false);
                //考勤设置-全天
                guideCheckIn.setCheckTimeType(GuideCheckInTypeEnum.CHECK_TYPE_2.getCode());
                guideCheckInMapper.insert(guideCheckIn);
                pushWarnMsg(guideCheckIn);
            } else {
                checkInDO.setCheckTime(guideCheckIn.getCheckTime());
                checkInDO.setStatus(guideCheckIn.getStatus());
                checkInDO.setType(guideCheckIn.getType());
                //考勤设置-全天
                guideCheckIn.setCheckTimeType(GuideCheckInTypeEnum.CHECK_TYPE_2.getCode());
                checkInDO.setRemark(guideCheckIn.getRemark());
                guideCheckInMapper.updateById(checkInDO);
                pushWarnMsg(checkInDO);
            }
        }
        // 返回
        return guideCheckIn.getId();
    }

    @Override
    public void updateGuideCheckIn(GuideCheckInSaveReqVO updateReqVO) {
        // 更新
        GuideCheckInDO updateObj = BeanUtils.toBean(updateReqVO, GuideCheckInDO.class);
        guideCheckInMapper.updateById(updateObj);
        pushWarnMsg(updateObj);
    }

    @Override
    public void deleteGuideCheckIn(String id) {
        // 删除
        guideCheckInMapper.deleteById(id);
    }

    public void pushWarnMsg(GuideCheckInDO guideCheckInDO) {
        guideCheckInDO = getGuideCheckIn(guideCheckInDO.getId());
        LocalDate startTime = guideCheckInDO.getCheckTime();
        LocalDate endTime = guideCheckInDO.getCheckTime();
        List<LocalDate> dateList = DateUtils.getDatesBetween(startTime, endTime);
//        for (LocalDate date : dateList) {
//            CarDispatchProgressPageReqVO carDispatchProgressPageReqVO = new CarDispatchProgressPageReqVO();
//            carDispatchProgressPageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
//            carDispatchProgressPageReqVO.setStartDate(LocalDateTime.parse(date + " 00:00:00", DateTimeFormatter
//                    .ofPattern("yyyy-MM-dd HH:mm:ss")));
//            IPage<CarDispatchDO> iPage = MyBatisUtils.buildPage(carDispatchProgressPageReqVO);
//            IPage<CarDispatchDO> page = null;
//            if (1 == guideCheckInDO.getType()) {
//                carDispatchProgressPageReqVO.setGuideId(guideCheckInDO.getGuideId());
//                page = carDispatchMapper.selectProgressGuidePage(iPage, carDispatchProgressPageReqVO);
//            } else if (2 == guideCheckInDO.getType()) {
//                carDispatchProgressPageReqVO.setDriverId(guideCheckInDO.getGuideId());
//                page = carDispatchMapper.selectProgressDriverPage(iPage, carDispatchProgressPageReqVO);
//            }
//            if (page != null && !page.getRecords().isEmpty()) {
//                //有调度信息，则发送告警信息
//                StringBuilder content = new StringBuilder();
//                WarnMsgSaveReqVO warnMsgSaveReqVO = new WarnMsgSaveReqVO();
//                warnMsgSaveReqVO.setSourceId(guideCheckInDO.getId());
//                warnMsgSaveReqVO.setObjId(page.getRecords().get(0).getId());
//                warnMsgSaveReqVO.setObjType(DispatchWarnMsgObjTypeEnum.CAR_DISPATCH.getCode());
//                if (1 == guideCheckInDO.getType()) {
//                    warnMsgSaveReqVO.setSourceType(DispatchWarnMsgSourceTypeEnum.GUIDE_CHECK_IN.getCode());
//                    GuideDO guide = guideService.getGuide(guideCheckInDO.getGuideId());
//                    content.append("导游【").append(guide.getName()).append("】");
//                } else if (2 == guideCheckInDO.getType()) {
//                    warnMsgSaveReqVO.setSourceType(DispatchWarnMsgSourceTypeEnum.DRIVER_CHECK_IN.getCode());
//                    DriverDO driver = driverService.getDriver(guideCheckInDO.getGuideId());
//                    CarDispatchCarDO dispatchCarDO = carDispatchCarMapper.selectOne(new LambdaQueryWrapperX<CarDispatchCarDO>().eq(CarDispatchCarDO::getCarDispatchId, warnMsgSaveReqVO.getObjId()).eq(CarDispatchCarDO::getStatus, 0));
//                    if (null != dispatchCarDO) {
//                        DriverShiftDO driverShiftDO = driverShiftMapper.selectById(dispatchCarDO.getCarShiftId());
//                        if (null != driverShiftDO) {
//                            CarDO carDO = carService.getCar(driverShiftDO.getCarInfor());
//                            if (null != carDO) {
//                                content.append("车辆【").append(carDO.getCarNo()).append("】,");
//                            }
//                        }
//                    }
//                    content.append("驾驶员【").append(driver.getName()).append("】");
//                }
//                content.append("在日期[").append(date).append("]已请假（")
//                        .append(DictFrameworkUtils.getDictDataLabel(DictTypeConstants.CHECK_IN_STATUS, guideCheckInDO.getStatus())).append("），请重新进行调度！");
//                warnMsgSaveReqVO.setContent(content.toString());
//                warnMsgService.createWarnMsg(warnMsgSaveReqVO);
//            }
//        }
    }

    @Override
    public GuideCheckInDO getGuideCheckIn(String id) {
        return guideCheckInMapper.selectById(id);
    }

    @Override
    public PageResult<GuideCheckInRespVO> getGuideCheckInPage(GuideCheckInPageReqVO pageReqVO) {
        if (GuideCheckInTypeEnum.CHECK_IN_USER_TYPE_1.getCode().toString().equals(pageReqVO.getType())) {
            return getGuideCheckInData(pageReqVO);
        }
        if (GuideCheckInTypeEnum.CHECK_IN_USER_TYPE_2.getCode().toString().equals(pageReqVO.getType())) {
            return getDriverCheckInData(pageReqVO);
        }
        return new PageResult<>(new ArrayList<>(0), 0L);
    }

    /**
     * @return java.util.List<com.zshl.dispatch.ops.store.controller.admin.guidecheckin.vo.GuideCheckInRespVO>
     * &#064;Description //TODO 获取导游考勤数据
     * &#064;Author liuxlh
     * &#064;Date 2025/8/2 16:08
     * @Param [pageReqVO]
     **/
    public PageResult<GuideCheckInRespVO> getGuideCheckInData(GuideCheckInPageReqVO pageReqVO) {
        List<GuideCheckInRespVO> checkInRespVOList = new ArrayList<>();
        GuidePageReqVO pageReq = new GuidePageReqVO();
        pageReq.setPageNo(pageReqVO.getPageNo());
        pageReq.setPageSize(pageReqVO.getPageSize());
        pageReq.setUseStatus(UseStatusEnum.ENABLE.getStatus());
        pageReq.setName(pageReqVO.getGuideName());
        pageReq.setId(pageReqVO.getGuideId());
        pageReq.setGuideType(pageReqVO.getGuideType());
        PageResult<GuideDO> guidePage = guideService.getGuidePage(pageReq);
        List<GuideDO> list = guidePage.getList();
        for (GuideDO guideDO : list) {
            //获取导游考勤状态
            GuideCheckInRespVO guideCheckIn = new GuideCheckInRespVO();
            guideCheckIn.setName(guideDO.getName());
            guideCheckIn.setUserType(guideDO.getGuideType());
            guideCheckIn.setSex(guideDO.getSex());
            guideCheckIn.setGuideId(guideDO.getId());
            LocalDate[] checkTime = pageReqVO.getCheckTime();
            List<GuideCheckInDO> checkInDOList = guideCheckInMapper.selectList(new LambdaQueryWrapperX<GuideCheckInDO>()
                    .eqIfPresent(GuideCheckInDO::getGuideId, guideDO.getId())
                    .betweenIfPresent(GuideCheckInDO::getCheckTime, checkTime)
                    .eqIfPresent(GuideCheckInDO::getDeleted, DeleteStatusEnum.ENABLE.getStatus())
            );
            Map<String, Integer> checkInMap = new HashMap<>(checkInDOList.size());
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            checkInDOList.forEach((item) -> {
                checkInMap.put(item.getCheckTime().format(formatter) + "=" + item.getCheckTimeType(), item.getStatus());
            });
            guideCheckIn.setGuideCheckInMap(checkInMap);
            //获取导游请假次数统计
            pageReqVO.setGuideId(guideDO.getId());
            pageReqVO.setStartCheckTime(checkTime[0]);
            pageReqVO.setEndCheckTime(checkTime[1]);
            List<Map> leaveDataList = guideCheckInMapper.queryLeaveData(pageReqVO);
            Map<String, Object> leaveDataMap = leaveDataList.stream().collect(Collectors
                    .toMap(each -> Objects.toString(each.get("type"), ""), each -> each.get("num"), (key1, key2) -> key1));
            guideCheckIn.setLeaveDataMap(leaveDataMap);
//            //获取导游出任务日期
//            GuideDispatchPageReqVO form = new GuideDispatchPageReqVO();
//            form.setGuideId(guideDO.getId());
//            if (pageReqVO.getCheckTime() != null && pageReqVO.getCheckTime().length > 1) {
//                form.setStartDate(pageReqVO.getCheckTime()[0].format(formatter));
//                form.setEndDate(pageReqVO.getCheckTime()[1].format(formatter));
//            }
//            List<GuideTaskDO> guideDispatchList = guideDispatchMapper.selectGuideTaskList(form);
//            List<String> dateList = guideDispatchList.stream().map(item -> item.getGoOutDate().format(formatter)).collect(Collectors.toList());
            guideCheckIn.setDispatchDateList(new ArrayList<>());

            checkInRespVOList.add(guideCheckIn);
        }
        return new PageResult<>(checkInRespVOList, guidePage.getTotal());
    }

    /**
     * @return java.util.List<com.zshl.dispatch.ops.store.controller.admin.guidecheckin.vo.GuideCheckInRespVO>
     * &#064;Description //TODO 获取驾驶员考勤数据
     * &#064;Author liuxlh
     * &#064;Date 2025/8/2 16:08
     * @Param [pageReqVO]
     **/
    public PageResult<GuideCheckInRespVO> getDriverCheckInData(GuideCheckInPageReqVO pageReqVO) {
//        List<GuideCheckInRespVO> checkInRespVOList = new ArrayList<>();
//        DriverPageReqVO pageReq = new DriverPageReqVO();
//        pageReq.setPageNo(pageReqVO.getPageNo());
//        pageReq.setPageSize(pageReqVO.getPageSize());
//        pageReq.setUseStatus(UseStatusEnum.ENABLE.getStatus());
//        pageReq.setName(pageReqVO.getGuideName());
//        pageReq.setId(pageReqVO.getGuideId());
//        PageResult<DriverDO> driverPage = driverService.getDriverPage(pageReq);
//        List<DriverDO> list = driverPage.getList();
//        for (DriverDO driverDO : list) {
//            //获取导游考勤状态
//            GuideCheckInRespVO driverCheckIn = new GuideCheckInRespVO();
//            driverCheckIn.setName(driverDO.getName());
//            driverCheckIn.setUserType(driverDO.getDriverType());
//            driverCheckIn.setSex(driverDO.getSex());
//            driverCheckIn.setGuideId(driverDO.getId());
//            LocalDate[] checkTime = pageReqVO.getCheckTime();
//            List<GuideCheckInDO> checkInDOList = guideCheckInMapper.selectList(new LambdaQueryWrapperX<GuideCheckInDO>()
//                    .eqIfPresent(GuideCheckInDO::getGuideId, driverDO.getId())
//                    .betweenIfPresent(GuideCheckInDO::getCheckTime, checkTime)
//                    .eqIfPresent(GuideCheckInDO::getDeleted, DeleteStatusEnum.ENABLE.getStatus())
//            );
//            Map<String, Integer> checkInMap = new HashMap<>(checkInDOList.size());
//            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
//            checkInDOList.forEach((item) -> {
//                checkInMap.put(item.getCheckTime().format(formatter) + "=" + item.getCheckTimeType(), item.getStatus());
//            });
//            driverCheckIn.setGuideCheckInMap(checkInMap);
//            //获取驾驶员请假次数统计
//            // TODO: 2025/7/31
//            pageReqVO.setGuideId(driverDO.getId());
//            pageReqVO.setStartCheckTime(checkTime[0]);
//            pageReqVO.setEndCheckTime(checkTime[1]);
//            List<Map> leaveDataList = guideCheckInMapper.queryLeaveData(pageReqVO);
//            Map<String, Object> leaveDataMap = leaveDataList.stream().collect(Collectors
//                    .toMap(each -> Objects.toString(each.get("type"), ""), each -> each.get("num"), (key1, key2) -> key1));
//            driverCheckIn.setLeaveDataMap(leaveDataMap);
//
//            checkInRespVOList.add(driverCheckIn);
//        }
//        return new PageResult<>(checkInRespVOList, driverPage.getTotal());
        return null;
    }

    @Override
    public List<GuideCheckInRespVO> getGuideCheckInList(GuideCheckInPageReqVO pageReqVO) {
        List<GuideCheckInRespVO> checkInRespVOList = new ArrayList<>();
        pageReqVO.setPageSize(PAGE_SIZE_NONE);
        if (GuideCheckInTypeEnum.CHECK_IN_USER_TYPE_1.getCode().toString().equals(pageReqVO.getType())) {
            checkInRespVOList = getGuideCheckInData(pageReqVO).getList();
        }
        if (GuideCheckInTypeEnum.CHECK_IN_USER_TYPE_2.getCode().toString().equals(pageReqVO.getType())) {
            checkInRespVOList = getDriverCheckInData(pageReqVO).getList();
        }
        return checkInRespVOList;
    }

    @Override
    public boolean validateGuideOrDriverCheckIn(GuideCheckInPageReqVO pageReqVO) {
        boolean flag1 = true;
        boolean flag2 = true;
        List<GuideCheckInDO> checkInDOs = guideCheckInMapper.selectList(new LambdaQueryWrapperX<GuideCheckInDO>()
                .eqIfPresent(GuideCheckInDO::getGuideId, pageReqVO.getGuideId())
                .betweenIfPresent(GuideCheckInDO::getCheckTime, pageReqVO.getCheckTime())
                .eqIfPresent(GuideCheckInDO::getDeleted, DeleteStatusEnum.ENABLE.getStatus())
        );
        //无考勤设置，为未请假，有考勤设置且为出勤，为未请假
        if (checkInDOs.size() <= 0) {
            flag1 = false;
        } else if (checkInDOs.get(0).getStatus().equals(GuideCheckInTypeEnum.CHECK_IN_TYPE_1.getCode())) {
            flag1 = false;
        } else {
            flag1 = true;
        }
//        LeaveApplyDO leaveApplyDO = leaveApplyMapper.selectOne(
//                new LambdaQueryWrapperX<LeaveApplyDO>()
//                        .eqIfPresent(LeaveApplyDO::getUserId, pageReqVO.getGuideId())
//                        .leIfPresent(LeaveApplyDO::getStartTime, pageReqVO.getCheckTime()[0])
//                        .geIfPresent(LeaveApplyDO::getEndTime, pageReqVO.getCheckTime()[0])
//                        .eqIfPresent(LeaveApplyDO::getStatus, AuditStatusEnum.AUDIT_STATUS_2.getStatus())
//        );
        //请假
//        if (leaveApplyDO != null) {
//            flag2 = true;
//        } else {
//            flag2 = false;
//        }
//        if (flag2) {
//            return true;
//        } else {
            if (flag1) {
                return true;
            } else {
                return false;
            }
//        }
    }

    @Override
    public List<Map> checkInData(String id, Date dateM) {
        List<Map> list = new ArrayList<>();
        Date firstDay = DateHelper.getAppointMonthStartDate(dateM);
        Date lastDay = DateHelper.getAppointMonthLastDate(dateM);
        List<String> dateList = DateHelper.findDay2List(firstDay, lastDay);
        dateList.forEach(date -> {
            Map resData = new HashMap();
            LocalDate workDate = LocalDate.parse(date);
            List<GuideCheckInDO> checkInDOList = guideCheckInMapper.selectList(new LambdaQueryWrapperX<GuideCheckInDO>()
                    .eqIfPresent(GuideCheckInDO::getGuideId, id)
                    .eqIfPresent(GuideCheckInDO::getCheckTime, workDate)
                    .eqIfPresent(GuideCheckInDO::getDeleted, DeleteStatusEnum.ENABLE.getStatus())
            );
            List<GuideCheckInRespVO> checkInRespVOList = BeanUtils.toBean(checkInDOList, GuideCheckInRespVO.class);
            Map<String, String> checkInMap = new HashMap<>(checkInRespVOList.size());
            checkInRespVOList.forEach((item) -> {
                String key = DictFrameworkUtils.getDictDataLabel(DictTypeConstants.CHECK_TIME_TYPE, item.getCheckTimeType());
                if (StringUtils.hasText(key)) {
                    checkInMap.put(key, DictFrameworkUtils.getDictDataLabel(DictTypeConstants.CHECK_IN_STATUS, item.getStatus()));
                }
            });
            resData.put("date", date);
            resData.put("checkInMap", checkInMap);
            resData.put("checkInData", checkInRespVOList);
            list.add(resData);
        });
        return list;
    }

    @Override
    public List<Map> checkInStatistics(String id, Date dateM) {
        List<Map> dataList = new ArrayList<>();
        GuideCheckInPageReqVO pageReqVO = new GuideCheckInPageReqVO();
        pageReqVO.setGuideId(id);
        Date firstDay = DateHelper.getAppointMonthStartDate(dateM);
        Date lastDay = DateHelper.getAppointMonthLastDate(dateM);
        pageReqVO.setStartCheckTime(LocalDate.parse(DateHelper.dateToString(DateHelper.DATE_PATTERN, firstDay)));
        pageReqVO.setEndCheckTime(LocalDate.parse(DateHelper.dateToString(DateHelper.DATE_PATTERN, lastDay)));
        List<Map> list = guideCheckInMapper.queryLeaveData(pageReqVO);
        List<DictDataRespDTO> dictDataRespDTOList = dictDataApi.getDictDataList(DictTypeConstants.CHECK_IN_STATUS);
        if (!(dictDataRespDTOList.isEmpty())) {
            dictDataRespDTOList.forEach(dictDataRespDTO -> {
                Map<String, Object> data = new HashMap<>();
                list.forEach(map -> {
                    String type = map.get("type").toString();
                    if (dictDataRespDTO.getValue().equals(type)) {
                        map.put("typeName", dictDataRespDTO.getLabel());
                        dataList.add(map);
                        data.put("typeName", dictDataRespDTO.getLabel());
                    }
                });
                if (data.isEmpty()) {
                    data.put("type", dictDataRespDTO.getValue());
                    data.put("typeName", dictDataRespDTO.getLabel());
                    data.put("num", 0);
                    dataList.add(data);
                }
            });
        }
        return dataList;
    }

}
