package com.ruoyi.fbs.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.bgt.bo.BgtProjectRecruitQueryBo;
import com.ruoyi.bgt.domain.BgtProjectRecruit;
import com.ruoyi.bgt.domain.dto.BgtProjectRecruitApplyQueryDTO;
import com.ruoyi.bgt.domain.dto.BgtWageApplicationQueryDTO;
import com.ruoyi.bgt.domain.vo.BgtAttendanceCountVO;
import com.ruoyi.bgt.domain.vo.BgtWageApplicationListVO;
import com.ruoyi.bgt.service.IBgtProjectRecruitApplyService;
import com.ruoyi.bgt.service.IBgtProjectRecruitService;
import com.ruoyi.bgt.service.IBgtProjectTaskProgressService;
import com.ruoyi.bgt.service.IBgtWageApplicationService;
import com.ruoyi.common.core.mybatisplus.core.ServicePlusImpl;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.AuditStatus;
import com.ruoyi.common.enums.ProjectTaskStatus;
import com.ruoyi.common.enums.RecruitApplyStatus;
import com.ruoyi.common.util.DataUtil;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.fbs.bo.FbsProjectTaskQueryBo;
import com.ruoyi.fbs.domain.FbsProjectTask;
import com.ruoyi.fbs.domain.dto.AppTaskDTO;
import com.ruoyi.fbs.domain.vo.AppTaskDetailVO;
import com.ruoyi.fbs.domain.vo.AppTaskVO;
import com.ruoyi.fbs.mapper.FbsProjectTaskMapper;
import com.ruoyi.fbs.service.IFbsProjectTaskApplyService;
import com.ruoyi.fbs.service.IFbsProjectTaskService;
import com.ruoyi.wgz.service.IWgzAttendanceService;
import com.ruoyi.zbf.domain.ZbfProject;
import com.ruoyi.zbf.service.IZbfProjectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

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

/**
 * 分包商项目任务Service业务层处理
 *
 * @author ruoyi
 * @date 2025-02-17
 */
@Service
public class FbsProjectTaskServiceImpl extends ServicePlusImpl<FbsProjectTaskMapper, FbsProjectTask> implements IFbsProjectTaskService {

	@Autowired
	private IZbfProjectService zbfProjectService;
	@Autowired
	private IFbsProjectTaskApplyService taskApplyService;
	@Autowired
	@Lazy
	private IBgtProjectRecruitService recruitService;
	@Autowired
	private IBgtProjectRecruitApplyService recruitApplyService;
	@Autowired
	private IBgtProjectTaskProgressService progressService;
	@Autowired
	private IBgtWageApplicationService wageApplicationService;
	@Autowired
	private IWgzAttendanceService attendanceService;

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

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

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

    private LambdaQueryWrapper<FbsProjectTask> buildQueryWrapper(FbsProjectTaskQueryBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<FbsProjectTask> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getProjectId() != null, FbsProjectTask::getProjectId, bo.getProjectId());
        lqw.eq(bo.getSectionId() != null, FbsProjectTask::getSectionId, bo.getSectionId());
        lqw.eq(bo.getSubId() != null, FbsProjectTask::getSubId, bo.getSubId());
        lqw.like(StrUtil.isNotBlank(bo.getTaskName()), FbsProjectTask::getTaskName, bo.getTaskName());
        lqw.eq(StrUtil.isNotBlank(bo.getTaskAddress()), FbsProjectTask::getTaskAddress, bo.getTaskAddress());
        lqw.eq(bo.getTaskAmount() != null, FbsProjectTask::getTaskAmount, bo.getTaskAmount());
        lqw.eq(bo.getTaskStaffNum() != null, FbsProjectTask::getTaskStaffNum, bo.getTaskStaffNum());
        lqw.eq(StrUtil.isNotBlank(bo.getTaskBeginTime()), FbsProjectTask::getTaskBeginTime, bo.getTaskBeginTime());
        lqw.eq(StrUtil.isNotBlank(bo.getTaskContactPerson()), FbsProjectTask::getTaskContactPerson, bo.getTaskContactPerson());
        lqw.eq(StrUtil.isNotBlank(bo.getTaskContactPhone()), FbsProjectTask::getTaskContactPhone, bo.getTaskContactPhone());
        lqw.eq(StrUtil.isNotBlank(bo.getTaskDescribe()), FbsProjectTask::getTaskDescribe, bo.getTaskDescribe());
        lqw.eq(StrUtil.isNotBlank(bo.getTaskImg()), FbsProjectTask::getTaskImg, bo.getTaskImg());
        lqw.eq(StrUtil.isNotBlank(bo.getQualification()), FbsProjectTask::getQualification, bo.getQualification());
        lqw.eq(bo.getUserId() != null, FbsProjectTask::getUserId, bo.getUserId());
        return lqw;
    }

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

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

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

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

	@Override
	public TableDataInfo<AppTaskVO> appQueryPageList(AppTaskDTO dto) {
		Page<AppTaskDTO> appTaskDTOPage = new Page<>();
		appTaskDTOPage.setCurrent(dto.getPageNum());
		appTaskDTOPage.setSize(dto.getPageSize());
		if(dto.getMyTask() && ObjectUtil.equals(ProjectTaskStatus.APPLY.getCode(),dto.getStatus())){
			List<Long> taskIds = taskApplyService.getTaskIdsByUserId(dto.getUserId());
			dto.setTaskIds(taskIds);
		}
		Page<AppTaskVO> appTaskVOPage = baseMapper.appQueryPageList(appTaskDTOPage, dto);
		return PageUtils.buildDataInfo(appTaskVOPage);
	}

	@Override
	public AppTaskDetailVO appQueryById(Long id) {
		FbsProjectTask byId = getById(id);
		AppTaskDetailVO appTaskDetailVO = BeanUtil.copyProperties(byId, AppTaskDetailVO.class);
		//项目信息
		ZbfProject project = zbfProjectService.getById(byId.getProjectId());
		appTaskDetailVO.setProjectName(project.getProjectName());
		//务工者数量列表
		BgtProjectRecruitQueryBo bgtProjectRecruitQueryBo = new BgtProjectRecruitQueryBo();
		bgtProjectRecruitQueryBo.setTaskId(id);
		List<Long> recruitIds = recruitService.queryList(bgtProjectRecruitQueryBo).stream().map(BgtProjectRecruit::getId).collect(Collectors.toList());

		BgtProjectRecruitApplyQueryDTO bgtProjectRecruitApplyQueryDTO = new BgtProjectRecruitApplyQueryDTO();
		bgtProjectRecruitApplyQueryDTO.setRecruitIds(recruitIds);
		bgtProjectRecruitApplyQueryDTO.setStatus(Collections.singletonList(RecruitApplyStatus.WORKING.getCode()));
		appTaskDetailVO.setApplyList(recruitApplyService.appQueryList(bgtProjectRecruitApplyQueryDTO));
		//任务进度
		appTaskDetailVO.setProgress(progressService.getLastProgress(id));

		//结算情况
		//收款申请列表
		BgtWageApplicationQueryDTO wageDTO = new BgtWageApplicationQueryDTO();
		wageDTO.setTaskId(id);
		List<BgtWageApplicationListVO> wageList = wageApplicationService.appQueryList(wageDTO);
		appTaskDetailVO.setWageApplicationList(wageList);
		//收款金额
		Integer taskReceiveAmount = wageList.stream().filter(wage -> AuditStatus.PASS.getCode().equals(wage.getAuditStatus()))
			.mapToInt(BgtWageApplicationListVO::getApplicantAmount)
			.sum();
		appTaskDetailVO.setTaskReceiveAmount(taskReceiveAmount);
		//付款金额

		//考勤情况
		LocalDate date = LocalDate.now();
		LocalDate startOfMonth = date.withDayOfMonth(1);
		List<BgtAttendanceCountVO> countVOS = attendanceService.countByTaskId(id, startOfMonth, date);
		if(CollectionUtil.isNotEmpty(countVOS)){
			BgtAttendanceCountVO vo = countVOS.get(0);
			appTaskDetailVO.setCountVOS(DataUtil.fillMissingDates(countVOS, startOfMonth, date));
			appTaskDetailVO.setTotalNum(vo.getTotalNum());
			appTaskDetailVO.setReportToDutyNum(vo.getReportToDutyNum());
			appTaskDetailVO.setReportToDutyRate(vo.getReportToDutyNum()/vo.getTotalNum()*100);
		}

		return appTaskDetailVO;
	}


}
