package com.ruoyi.fbs.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
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.BgtProjectRecruitApplyVO;
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.DateUtils;
import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.SecurityUtils;
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.*;
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.wgz.service.IWgzPayCalculationService;
import com.ruoyi.zbf.domain.ZbfProject;
import com.ruoyi.zbf.service.IZbfProjectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
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
	private IBgtProjectRecruitService recruitService;
	@Autowired
	private IBgtProjectRecruitApplyService recruitApplyService;
	@Autowired
	private IBgtProjectTaskProgressService progressService;
	@Autowired
	private IBgtWageApplicationService wageApplicationService;
	@Autowired
	private IWgzAttendanceService attendanceService;
	@Autowired
	private IWgzPayCalculationService payCalculationService;

    @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());
		List<Long> taskIds = new ArrayList<>();
		if(ProjectTaskStatus.APPLY.getCode().equals(dto.getStatus())){
			taskIds = taskApplyService.getTaskIdsByUserId(SecurityUtils.getAppUserId());
			dto.setTaskIds(taskIds);
		}
		if(dto.getMyTask() && !ProjectTaskStatus.APPLY.getCode().equals(dto.getStatus())){
			dto.setUserId(SecurityUtils.getAppUserId());
		}

		Page<AppTaskVO> appTaskVOPage = baseMapper.appQueryPageList(appTaskDTOPage, dto);
		if(dto.getMyTask() && ProjectTaskStatus.APPLY.getCode().equals(dto.getStatus())
			&&CollectionUtil.isEmpty(taskIds)){
			appTaskVOPage.setRecords(new ArrayList<AppTaskVO>());
			appTaskVOPage.setTotal(0);
		}
		return PageUtils.buildDataInfo(appTaskVOPage);
	}

	@Override
	public List<AppTaskVO> appQueryList() {
		LambdaQueryWrapper<FbsProjectTask> wrapper = new LambdaQueryWrapper<>();
		System.out.println(SecurityUtils.getAppUserId());
		wrapper.eq(FbsProjectTask::getUserId,SecurityUtils.getAppUserId());
		wrapper.eq(FbsProjectTask::getStatus,ProjectTaskStatus.PROGRESS.getCode());
		List<FbsProjectTask> fbsProjectTasks = baseMapper.selectList(wrapper);
		return BeanUtil.copyToList(fbsProjectTasks,AppTaskVO.class);
	}

	@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());

		if(ProjectTaskStatus.PROGRESS.getCode().equals(byId.getStatus())
			|| ProjectTaskStatus.COMPLETE.getCode().equals(byId.getStatus())){
			//任务进度
			appTaskDetailVO.setProgress(progressService.getLastProgress(id));

			//结算情况
			//收款申请列表
			BgtWageApplicationQueryDTO wageDTO = new BgtWageApplicationQueryDTO();
			wageDTO.setTaskId(id);
			List<BgtWageApplicationListVO> wageList = wageApplicationService.appQueryList(wageDTO);
			appTaskDetailVO.setWageApplication(CollectionUtil.isEmpty(wageList)?null:wageList.get(0));
			//收款金额
			Integer taskReceiveAmount = wageList.stream().filter(wage -> AuditStatus.PASS.getCode().equals(wage.getAuditStatus()))
				.mapToInt(BgtWageApplicationListVO::getApplicantAmount)
				.sum();
			appTaskDetailVO.setTaskReceiveAmount(taskReceiveAmount);
			//付款金额
			BigDecimal payByTaskAndBgt = payCalculationService.getPayByTaskAndBgt(byId.getId(), byId.getUserId());
			appTaskDetailVO.setTaskPaymentAmount(payByTaskAndBgt);

		}
		return appTaskDetailVO;
	}

	@Override
	public AppTaskDetailAttendanceVO attendance(Long id) {
		FbsProjectTask task = getById(id);
		LocalDate taskBeginTime = DateUtils.str2Localdate(task.getTaskBeginTime(), DateUtils.YYYY_MM_DD);
		LocalDate taskEndTime = DateUtils.str2Localdate(task.getTaskEndTime(), DateUtils.YYYY_MM_DD);
		//考勤情况
		AppTaskDetailAttendanceVO appTaskDetailVO = new AppTaskDetailAttendanceVO();
		appTaskDetailVO.setId(id);
		LocalDate date = LocalDate.now();
		if(taskEndTime!=null &&taskEndTime.isBefore(date)){
			date = taskEndTime;
		}
		LocalDate startTime = date.minusDays(7);
		if (taskBeginTime!=null &&taskBeginTime.isAfter(startTime)){
			startTime = taskBeginTime;
		}
		List<BgtAttendanceCountVO>
			countVOS = attendanceService.countByTaskId(id, startTime, date);
		if(CollectionUtil.isNotEmpty(countVOS)){
			BgtAttendanceCountVO vo = countVOS.get(0);
			appTaskDetailVO.setCountVOS(DataUtil.fillMissingDates(countVOS, startTime, date));
			appTaskDetailVO.setTotalNum(vo.getTotalNum());
			appTaskDetailVO.setReportToDutyNum(vo.getReportToDutyNum());
			if(vo.getTotalNum()!=0){
				int rate = new BigDecimal(vo.getReportToDutyNum()).divide(new BigDecimal(vo.getTotalNum()), 2, RoundingMode.HALF_UP)
					.multiply(new BigDecimal(100)).intValue();
				appTaskDetailVO.setReportToDutyRate(rate);
			}

		}
		return appTaskDetailVO;
	}

	@Override
	public AppTaskDetailProgressVO progress(Long id) {
		AppTaskDetailProgressVO appTaskDetailVO = new AppTaskDetailProgressVO();
		appTaskDetailVO.setId(id);
		//任务进度
		appTaskDetailVO.setProgress(progressService.getLastProgress(id));
		return appTaskDetailVO;
	}

	@Override
	public AppTaskDetailWageVO wage(Long id) {
		AppTaskDetailWageVO appTaskDetailVO = new AppTaskDetailWageVO();
		appTaskDetailVO.setId(id);
		//结算情况
		//收款申请列表
		BgtWageApplicationQueryDTO wageDTO = new BgtWageApplicationQueryDTO();
		wageDTO.setTaskId(id);
		List<BgtWageApplicationListVO> wageList = wageApplicationService.appQueryList(wageDTO);
		appTaskDetailVO.setWageApplication(CollectionUtil.isEmpty(wageList)?null:wageList.get(0));
		//收款金额
		Integer taskReceiveAmount = wageList.stream().filter(wage -> AuditStatus.PASS.getCode().equals(wage.getAuditStatus()))
			.mapToInt(BgtWageApplicationListVO::getApplicantAmount)
			.sum();
		appTaskDetailVO.setTaskReceiveAmount(taskReceiveAmount);
		//付款金额
		BigDecimal payByTaskAndBgt = payCalculationService.getPayByTaskAndBgt(id, SecurityUtils.getAppUserId());
		appTaskDetailVO.setTaskPaymentAmount(payByTaskAndBgt);
		return appTaskDetailVO;
	}

	@Override
	public AppTaskDetailRecruitVO recruit(Long id) {
		AppTaskDetailRecruitVO appTaskDetailVO = new AppTaskDetailRecruitVO();
		appTaskDetailVO.setId(id);
		//务工者数量列表
		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()));
		List<BgtProjectRecruitApplyVO> vos = recruitApplyService.appQueryList(bgtProjectRecruitApplyQueryDTO);
		appTaskDetailVO.setTotal(vos.size());
		appTaskDetailVO.setApplyList(vos.subList(0, Math.min(vos.size(), 3)));
		return appTaskDetailVO;
	}
}
