package com.ruoyi.wgz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.bgt.domain.BgtProjectRecruit;
import com.ruoyi.bgt.domain.BgtProjectRecruitApply;
import com.ruoyi.bgt.domain.dto.BgtProjectTaskProgressQueryDTO;
import com.ruoyi.bgt.service.IBgtProjectRecruitApplyService;
import com.ruoyi.bgt.service.IBgtProjectRecruitService;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.wgz.bo.req.WgzAppCancelLeaveReq;
import com.ruoyi.wgz.bo.req.WgzAppLeaveHistoryListPageReq;
import com.ruoyi.wgz.bo.req.WgzAppSubmitLeaveReq;
import com.ruoyi.wgz.bo.res.WgzAppLeaveHistoryListPageRes;
import com.ruoyi.wgz.domain.WgzDailyClock;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.wgz.bo.WgzLeaveQueryBo;
import com.ruoyi.wgz.domain.WgzLeave;
import com.ruoyi.wgz.mapper.WgzLeaveMapper;
import com.ruoyi.wgz.service.IWgzLeaveService;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 请假Service业务层处理
 *
 * @author ruoyi
 * @date 2025-02-19
 */
@Service
public class WgzLeaveServiceImpl extends ServicePlusImpl<WgzLeaveMapper, WgzLeave> implements IWgzLeaveService {
	@Autowired
	private IBgtProjectRecruitApplyService iBgtProjectRecruitApplyService;

	@Autowired
	private IBgtProjectRecruitService iBgtProjectRecruitService;

    @Override
    public WgzLeave queryById(Long id){
        return getById(id);
    }

    @Override
    public TableDataInfo<WgzLeave> queryPageList(WgzLeaveQueryBo bo) {
        Page<WgzLeave> result = page(PageUtils.buildPage(), buildQueryWrapper(bo));
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<WgzLeave> queryList(WgzLeaveQueryBo bo) {
        return list(buildQueryWrapper(bo));
    }

    private LambdaQueryWrapper<WgzLeave> buildQueryWrapper(WgzLeaveQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<WgzLeave> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getRecruitId() != null, WgzLeave::getRecruitId, bo.getRecruitId());
        lqw.eq(StrUtil.isNotBlank(bo.getSubject()), WgzLeave::getSubject, bo.getSubject());
        lqw.eq(StrUtil.isNotBlank(bo.getLeaveType()), WgzLeave::getLeaveType, bo.getLeaveType());
        lqw.eq(bo.getStartTime() != null, WgzLeave::getStartTime, bo.getStartTime());
        lqw.eq(bo.getEndTime() != null, WgzLeave::getEndTime, bo.getEndTime());
        lqw.eq(StrUtil.isNotBlank(bo.getReason()), WgzLeave::getReason, bo.getReason());
        lqw.eq(bo.getAuditorUserId() != null, WgzLeave::getAuditorUserId, bo.getAuditorUserId());
        lqw.eq(StrUtil.isNotBlank(bo.getAuditorType()), WgzLeave::getAuditorType, bo.getAuditorType());
        lqw.eq(StrUtil.isNotBlank(bo.getAuditorOpinion()), WgzLeave::getAuditorOpinion, bo.getAuditorOpinion());
        lqw.eq(bo.getAuditorTime() != null, WgzLeave::getAuditorTime, bo.getAuditorTime());
        lqw.eq(bo.getWorkingTime() != null, WgzLeave::getWorkingTime, bo.getWorkingTime());
        lqw.eq(bo.getClosingTime() != null, WgzLeave::getClosingTime, bo.getClosingTime());
        return lqw;
    }

    @Override
    public Boolean insert(WgzLeave bo) {
        WgzLeave add = BeanUtil.toBean(bo, WgzLeave.class);
        validEntityBeforeSave(add);
        return save(add);
    }

    @Override
    public Boolean update(WgzLeave bo) {
        WgzLeave update = BeanUtil.toBean(bo, WgzLeave.class);
        validEntityBeforeSave(update);
        return updateById(update);
    }

    /**
     * 保存前的数据校验
     *
     * @param entity 实体类数据
     */
    private void validEntityBeforeSave(WgzLeave entity){
        //TODO 做一些数据校验,如唯一约束
    }

    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }

	/**
	 * APP相关
	 * =================================================================================================================
	 * =================================================================================================================
	 * =================================================================================================================
	 */

	@Override
	@Transactional
	public Boolean userSubmitLeave(WgzAppSubmitLeaveReq req) {
		//1、现获取用户的唯一标识
		Long appUserId = SecurityUtils.getAppUserId();
		//2、根据唯一标识获取到当前用户的招工
		BgtProjectRecruitApply by = iBgtProjectRecruitApplyService.selectByUserIdProjectRecruitApplyId(appUserId);
		//3、根据招工id获取到具体招工信息
		BgtProjectRecruit appById = iBgtProjectRecruitService.getAppById(by.getId());
		//6、组装请假对象数据 并插入
		WgzLeave wgzLeave = new WgzLeave().
			setRecruitId(by.getId()).
			setSubject(appById.getRecruitName()).
			setUserId(appUserId).
			setLeaveType(req.getLeaveType()).
			setStartTime(req.getStartTime()).
			setEndTime(req.getEndTime()).
			setReason(req.getReason()).
			setAuditorUserId(appById.getUserId()).
			setWorkingTime(appById.getBeginWorkTime()).
			setClosingTime(appById.getEndWorkTime());
		return baseMapper.insert(wgzLeave)>0;
	}

	@Override
	public TableDataInfo<WgzAppLeaveHistoryListPageRes> userLeaveHistoryListPage(WgzAppLeaveHistoryListPageReq req) {
		Page<WgzAppLeaveHistoryListPageReq> queryDTOPage = new Page<>();
		queryDTOPage.setCurrent(req.getPageNum());
		queryDTOPage.setSize(req.getPageSize());
		return PageUtils.buildDataInfo(baseMapper.userLeaveHistoryListPage(queryDTOPage));
	}

	@Override
	@Transactional
	public Boolean userCancelLeave(WgzAppCancelLeaveReq req) {
		WgzLeave wgzLeave = new WgzLeave().
			setId(req.getId()).
			setAuditorType("4").
			setCancelLeave(LocalDateTime.now());
		return  baseMapper.updateById(wgzLeave)>0;
	}

	@Override
	public Map<LocalDate, LocalDate> selectByUserCancelLeave(String yearMonth) {
		Map<LocalDate, LocalDate> ld = new HashMap<>();
		//1、现获取用户的唯一标识
		Long appUserId = SecurityUtils.getAppUserId();
		//2、根据唯一标识获取到当前用户的招工
		BgtProjectRecruitApply by = iBgtProjectRecruitApplyService.selectByUserIdProjectRecruitApplyId(appUserId);
		//2、查询请假表
		LambdaQueryWrapper<WgzLeave> apply = new LambdaQueryWrapper<WgzLeave>().
			eq(WgzLeave::getUserId, appUserId).
			eq(WgzLeave::getRecruitId, by.getId()).
			eq(WgzLeave::getAuditorType, "2")
			.apply("date_format(start_time,'%Y-%m') = {0}", yearMonth);
		List<WgzLeave> wgzLeaves = baseMapper.selectList(apply);
		wgzLeaves.forEach( leave -> {
			LocalDateTime startTime = leave.getStartTime();
			LocalDate localDate = startTime.toLocalDate();
			ld.put(localDate,localDate);
		});
		return ld;
	}

	@Override
	public WgzLeave FindAskForLeaveOrNotInfo(Long appUserId, Long recruitId, String date) {
		LambdaQueryWrapper<WgzLeave> apply = new LambdaQueryWrapper<WgzLeave>().
			eq(WgzLeave::getUserId, appUserId).
			eq(WgzLeave::getRecruitId, recruitId).
			eq(WgzLeave::getAuditorType, "2")
			.apply("date_format(start_time,'%Y-%m-%d') = {0}", date);
		return baseMapper.selectOne(apply);
	}
}
