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.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.bgt.domain.BgtProjectRecruit;
import com.ruoyi.bgt.domain.dto.BgtDailyClockListDTO;
import com.ruoyi.bgt.domain.dto.BgtDailyClockUpdateDTO;
import com.ruoyi.bgt.domain.vo.BgtDailyClockDetailVO;
import com.ruoyi.bgt.domain.vo.BgtDailyClockListVO;
import com.ruoyi.bgt.service.IBgtProjectRecruitService;
import com.ruoyi.bgt.service.IBgtUserService;
import com.ruoyi.common.core.domain.entity.BgtUser;
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.wgz.bo.WgzDailyClockQueryBo;
import com.ruoyi.wgz.bo.req.WgzAppDailyCalendarReq;
import com.ruoyi.wgz.bo.req.WgzAppDailyRecordReq;
import com.ruoyi.wgz.bo.res.WgzAppUserDailyRecordRes;
import com.ruoyi.wgz.bo.res.WgzUserDailyCalendarRes;
import com.ruoyi.wgz.bo.rests.WgzAppAttachmentAcquisitionTwo;
import com.ruoyi.wgz.domain.WgzDailyClock;
import com.ruoyi.wgz.mapper.WgzDailyClockMapper;
import com.ruoyi.wgz.service.IWgzDailyClockService;
import com.ruoyi.wgz.service.IWgzLeaveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * 日报打卡Service业务层处理
 *
 * @author ruoyi
 * @date 2025-02-18
 */
@Service
public class WgzDailyClockServiceImpl extends ServicePlusImpl<WgzDailyClockMapper, WgzDailyClock> implements IWgzDailyClockService {
    @Autowired
    private  IWgzLeaveService iWgzLeaveService;

	@Autowired
	private IBgtUserService userService;

	@Autowired
	private IBgtProjectRecruitService recruitService;

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

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

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

    private LambdaQueryWrapper<WgzDailyClock> buildQueryWrapper(WgzDailyClockQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<WgzDailyClock> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getRecruitId() != null, WgzDailyClock::getRecruitId, bo.getRecruitId());
        lqw.eq(bo.getUserId() != null, WgzDailyClock::getUserId, bo.getUserId());
        lqw.eq(bo.getDilyTime() != null, WgzDailyClock::getDilyTime, bo.getDilyTime());
        lqw.eq(bo.getDailyMark() != null, WgzDailyClock::getDailyMark, bo.getDailyMark());
        lqw.eq(StrUtil.isNotBlank(bo.getPnchOsition()), WgzDailyClock::getPnchOsition, bo.getPnchOsition());
        lqw.eq(StrUtil.isNotBlank(bo.getFinishToday()), WgzDailyClock::getFinishToday, bo.getFinishToday());
        lqw.eq(StrUtil.isNotBlank(bo.getUnfinished()), WgzDailyClock::getUnfinished, bo.getUnfinished());
        lqw.eq(StrUtil.isNotBlank(bo.getWorkTomorrow()), WgzDailyClock::getWorkTomorrow, bo.getWorkTomorrow());
        lqw.eq(StrUtil.isNotBlank(bo.getCoordinate()), WgzDailyClock::getCoordinate, bo.getCoordinate());
        lqw.eq(StrUtil.isNotBlank(bo.getAttachment()), WgzDailyClock::getAttachment, bo.getAttachment());
        lqw.eq(bo.getAuditorUserId() != null, WgzDailyClock::getAuditorUserId, bo.getAuditorUserId());
        lqw.eq(StrUtil.isNotBlank(bo.getAuditorType()), WgzDailyClock::getAuditorType, bo.getAuditorType());
        lqw.eq(StrUtil.isNotBlank(bo.getAuditorOpinion()), WgzDailyClock::getAuditorOpinion, bo.getAuditorOpinion());
        lqw.eq(bo.getAuditorTime() != null, WgzDailyClock::getAuditorTime, bo.getAuditorTime());
        return lqw;
    }

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

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

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

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

	/**
	 * 务工者APP相关
	 * =================================================================================================================
	 * =================================================================================================================
	 * =================================================================================================================
	 */

	@Override
	public WgzUserDailyCalendarRes userDailyCalendar(WgzAppDailyCalendarReq req) {
		//1、获取当月的所有日期
		LocalDate currentDate = LocalDate.now();
		LocalDate firstDayOfMonth = currentDate.with(TemporalAdjusters.firstDayOfMonth());
		LocalDate lastDayOfMonth = currentDate.with(TemporalAdjusters.lastDayOfMonth());
		List<LocalDate> dates = new ArrayList<>();
		LocalDate tempDate = firstDayOfMonth;
		while (!tempDate.isAfter(lastDayOfMonth)) {
			dates.add(tempDate);
			tempDate = tempDate.plusDays(1);
		}
		//2、查询当前人员指定日期的所有日报情况
		QueryWrapper<WgzDailyClock> queryWrapper = new QueryWrapper<>();
		queryWrapper.apply("DATE_FORMAT(dily_time, '%Y-%m') = {0}", req.getYearMonth());		// 使用 apply 方法添加自定义 SQL 条件
		List<WgzDailyClock> wgzDailyClocks = baseMapper.selectList(queryWrapper);
		//3、查看当前人、当前项目、当前月是否有请假
        Map<LocalDate, LocalDate> ll = iWgzLeaveService.selectByUserCancelLeave(req.getYearMonth());
        //4、将获取的年月与数据库中的日期进行比对，然后填充数据
		Map<String, WgzAppAttachmentAcquisitionTwo> fh = new HashMap<>();
		dates.forEach(date -> {
			wgzDailyClocks.forEach(wgzDailyClock -> {
				LocalDate clockDate = wgzDailyClock.getDilyTime().toLocalDate();
				//两个时间一致就填充数据；如若有请假的日期需要将状态改为请假
				if (clockDate.equals(date)) {
					WgzAppAttachmentAcquisitionTwo wgzAppAttachmentAcquisitionTwo = new WgzAppAttachmentAcquisitionTwo().
						setStatus("0").//正常上传日志
						setId(wgzDailyClock.getId()).
						setDilyTime(wgzDailyClock.getDilyTime()).
						setPnchOsition(wgzDailyClock.getPnchOsition());
					if (ll.get(clockDate).equals(clockDate)) {
						wgzAppAttachmentAcquisitionTwo.setStatus("2"); //全天请假
					}
					fh.put(date.toString(),wgzAppAttachmentAcquisitionTwo);
				}
			});
		});
		return new WgzUserDailyCalendarRes().setDailyCalendar(fh);
	}

    @Override
    public TableDataInfo<WgzAppUserDailyRecordRes> userDailyRecord(WgzAppDailyRecordReq req) {
        Page<WgzAppDailyRecordReq> pe = new Page<>();
        pe.setCurrent(req.getPageNum());
        pe.setSize(req.getPageSize());
        return PageUtils.buildDataInfo(baseMapper.userDailyRecordListPage(pe));
    }

	@Override
	public WgzDailyClock userCheckDailyNewspaper(Long id) {
		return getById(id);
	}

	@Override
	public TableDataInfo<BgtDailyClockListVO> appQueryPageList(BgtDailyClockListDTO dto) {
		dto.setAuditorUserId(SecurityUtils.getAppUserId());
		Page<BgtDailyClockListDTO> queryDTOPage = new Page<>();
		queryDTOPage.setCurrent(dto.getPageNum());
		queryDTOPage.setSize(dto.getPageSize());
		Page<BgtDailyClockListVO> queryVOPage = baseMapper.appQueryPageList(queryDTOPage, dto);
		return PageUtils.buildDataInfo(queryVOPage);
	}

	@Override
	public BgtDailyClockDetailVO appQueryById(Long id) {
		WgzDailyClock dailyClock = getById(id);
		BgtDailyClockDetailVO detailVO = BeanUtil.copyProperties(dailyClock, BgtDailyClockDetailVO.class);
		BgtUser bgtUser = userService.getById(dailyClock.getUserId());
		detailVO.setUsername(bgtUser.getUsername());
		detailVO.setAvatarName(bgtUser.getAvatarName());
		BgtProjectRecruit recruit = recruitService.getById(dailyClock.getRecruitId());
		detailVO.setRecruitName(recruit.getRecruitName());
		return detailVO;
	}

	@Override
	public Boolean appUpdate(BgtDailyClockUpdateDTO dto) {
		WgzDailyClock dailyClock = BeanUtil.copyProperties(dto, WgzDailyClock.class);
		dailyClock.setAuditorTime(LocalDateTime.now());
		return updateById(dailyClock);
	}
}
