package cn.iocoder.yudao.module.pms.dal.mysql.iotrddailyreport;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.IotRdDailyReportPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotrddailyreport.vo.IotRdDailyReportTaskPeriodVO;
import cn.iocoder.yudao.module.pms.controller.admin.maintain.vo.IotMaintainPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.stat.vo.AllOrderResp;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotrddailyreport.IotRdDailyReportDO;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.Collection;
import java.util.List;

/**
 * 瑞都日报 Mapper
 *
 * @author ruiqi
 */
@Mapper
public interface IotRdDailyReportMapper extends BaseMapperX<IotRdDailyReportDO> {

    default PageResult<IotRdDailyReportDO> selectPage(IotRdDailyReportPageReqVO reqVO) {
        LambdaQueryWrapperX<IotRdDailyReportDO> wrapper = buildBaseQuery(reqVO);

        // 关键：移动端搜索（searchKey 非空） -> projectIds 与 taskIds 使用 OR
        if (StrUtil.isNotBlank(reqVO.getSearchKey())) {
            Collection<Long> projectIds = reqVO.getProjectIds();
            Collection<Long> taskIds = reqVO.getTaskIds();
            boolean hasProject = CollUtil.isNotEmpty(projectIds);
            boolean hasTask = CollUtil.isNotEmpty(taskIds);

            if (hasProject || hasTask) {
                wrapper.and(wq -> {
                    if (hasProject) wq.in(IotRdDailyReportDO::getProjectId, projectIds);
                    if (hasProject && hasTask) wq.or();
                    if (hasTask) wq.in(IotRdDailyReportDO::getTaskId, taskIds);
                });
            }
        } else {
            // PC 端多条件：维持 AND
            wrapper.inIfPresent(IotRdDailyReportDO::getProjectId, reqVO.getProjectIds())
                    .inIfPresent(IotRdDailyReportDO::getTaskId, reqVO.getTaskIds());
        }

        wrapper.and(wq -> wq.eq(IotRdDailyReportDO::getPlatformWell, 0)
                .or()
                .eq(IotRdDailyReportDO::getPlatformWell, 1));
        return selectPage(reqVO, wrapper);
    }

    default List<IotRdDailyReportDO> dailyReports(IotRdDailyReportPageReqVO reqVO) {
        return selectList(new LambdaQueryWrapperX<IotRdDailyReportDO>()
                .inIfPresent(IotRdDailyReportDO::getDeptId, reqVO.getDeptIds())
                .eqIfPresent(IotRdDailyReportDO::getProjectId, reqVO.getProjectId())
                .inIfPresent(IotRdDailyReportDO::getProjectId, reqVO.getProjectIds())
                .eqIfPresent(IotRdDailyReportDO::getPlatformWell, reqVO.getPlatformWell())
                .eqIfPresent(IotRdDailyReportDO::getPlatformGroup, reqVO.getPlatformGroup())
                .inIfPresent(IotRdDailyReportDO::getPlatformGroup, reqVO.getPlatformGroups())
                .eqIfPresent(IotRdDailyReportDO::getTaskId, reqVO.getTaskId())
                .inIfPresent(IotRdDailyReportDO::getTaskId, reqVO.getTaskIds())
                .eqIfPresent(IotRdDailyReportDO::getProjectClassification, reqVO.getProjectClassification())
                .eqIfPresent(IotRdDailyReportDO::getTechniqueIds, reqVO.getTechniqueIds())
                .eqIfPresent(IotRdDailyReportDO::getDeviceIds, reqVO.getDeviceIds())
                .betweenIfPresent(IotRdDailyReportDO::getStartTime, reqVO.getStartTime())
                .betweenIfPresent(IotRdDailyReportDO::getEndTime, reqVO.getEndTime())
                .eqIfPresent(IotRdDailyReportDO::getCumulativeWorkingWell, reqVO.getCumulativeWorkingWell())
                .eqIfPresent(IotRdDailyReportDO::getCumulativeWorkingLayers, reqVO.getCumulativeWorkingLayers())
                .eqIfPresent(IotRdDailyReportDO::getDailyPumpTrips, reqVO.getDailyPumpTrips())
                .eqIfPresent(IotRdDailyReportDO::getDailyToolsSand, reqVO.getDailyToolsSand())
                .eqIfPresent(IotRdDailyReportDO::getRunCount, reqVO.getRunCount())
                .eqIfPresent(IotRdDailyReportDO::getBridgePlug, reqVO.getBridgePlug())
                .eqIfPresent(IotRdDailyReportDO::getWaterVolume, reqVO.getWaterVolume())
                .eqIfPresent(IotRdDailyReportDO::getHourCount, reqVO.getHourCount())
                .eqIfPresent(IotRdDailyReportDO::getDailyFuel, reqVO.getDailyFuel())
                .eqIfPresent(IotRdDailyReportDO::getDailyPowerUsage, reqVO.getDailyPowerUsage())
                .betweenIfPresent(IotRdDailyReportDO::getProductionTime, reqVO.getProductionTime())
                .betweenIfPresent(IotRdDailyReportDO::getNonProductionTime, reqVO.getNonProductionTime())
                .eqIfPresent(IotRdDailyReportDO::getRdNptReason, reqVO.getRdNptReason())
                .betweenIfPresent(IotRdDailyReportDO::getConstructionStartDate, reqVO.getConstructionStartDate())
                .betweenIfPresent(IotRdDailyReportDO::getConstructionEndDate, reqVO.getConstructionEndDate())
                .eqIfPresent(IotRdDailyReportDO::getProductionStatus, reqVO.getProductionStatus())
                .eqIfPresent(IotRdDailyReportDO::getExternalRental, reqVO.getExternalRental())
                .eqIfPresent(IotRdDailyReportDO::getNextPlan, reqVO.getNextPlan())
                .eqIfPresent(IotRdDailyReportDO::getRdStatus, reqVO.getRdStatus())
                .eqIfPresent(IotRdDailyReportDO::getMalfunction, reqVO.getMalfunction())
                .betweenIfPresent(IotRdDailyReportDO::getFaultDowntime, reqVO.getFaultDowntime())
                .eqIfPresent(IotRdDailyReportDO::getPersonnel, reqVO.getPersonnel())
                .eqIfPresent(IotRdDailyReportDO::getTotalStaffNum, reqVO.getTotalStaffNum())
                .eqIfPresent(IotRdDailyReportDO::getLeaveStaffNum, reqVO.getLeaveStaffNum())
                .eqIfPresent(IotRdDailyReportDO::getExtProperty, reqVO.getExtProperty())
                .eqIfPresent(IotRdDailyReportDO::getSort, reqVO.getSort())
                .eqIfPresent(IotRdDailyReportDO::getRemark, reqVO.getRemark())
                .eqIfPresent(IotRdDailyReportDO::getStatus, reqVO.getStatus())
                .eqIfPresent(IotRdDailyReportDO::getProcessInstanceId, reqVO.getProcessInstanceId())
                .eqIfPresent(IotRdDailyReportDO::getAuditStatus, reqVO.getAuditStatus())
                .betweenIfPresent(IotRdDailyReportDO::getCreateTime, reqVO.getCreateTime()));
    }

    /**
     * 构建 瑞都日报 公共查询条件
     * @param reqVO 查询条件
     */
    default LambdaQueryWrapperX<IotRdDailyReportDO> buildCommonQuery(IotRdDailyReportPageReqVO reqVO) {
        return new LambdaQueryWrapperX<IotRdDailyReportDO>()
                .inIfPresent(IotRdDailyReportDO::getDeptId, reqVO.getDeptIds())
                .inIfPresent(IotRdDailyReportDO::getProjectId, reqVO.getProjectIds())
                .eqIfPresent(IotRdDailyReportDO::getTaskId, reqVO.getTaskId())
                .inIfPresent(IotRdDailyReportDO::getTaskId, reqVO.getTaskIds())
                .eqIfPresent(IotRdDailyReportDO::getProjectClassification, reqVO.getProjectClassification())
                .eqIfPresent(IotRdDailyReportDO::getTechniqueIds, reqVO.getTechniqueIds())
                .eqIfPresent(IotRdDailyReportDO::getDeviceIds, reqVO.getDeviceIds())
                .betweenIfPresent(IotRdDailyReportDO::getStartTime, reqVO.getStartTime())
                .betweenIfPresent(IotRdDailyReportDO::getEndTime, reqVO.getEndTime())
                .eqIfPresent(IotRdDailyReportDO::getCumulativeWorkingWell, reqVO.getCumulativeWorkingWell())
                .eqIfPresent(IotRdDailyReportDO::getCumulativeWorkingLayers, reqVO.getCumulativeWorkingLayers())
                .eqIfPresent(IotRdDailyReportDO::getDailyPumpTrips, reqVO.getDailyPumpTrips())
                .eqIfPresent(IotRdDailyReportDO::getDailyToolsSand, reqVO.getDailyToolsSand())
                .eqIfPresent(IotRdDailyReportDO::getRunCount, reqVO.getRunCount())
                .eqIfPresent(IotRdDailyReportDO::getBridgePlug, reqVO.getBridgePlug())
                .eqIfPresent(IotRdDailyReportDO::getWaterVolume, reqVO.getWaterVolume())
                .eqIfPresent(IotRdDailyReportDO::getHourCount, reqVO.getHourCount())
                .eqIfPresent(IotRdDailyReportDO::getDailyFuel, reqVO.getDailyFuel())
                .eqIfPresent(IotRdDailyReportDO::getDailyPowerUsage, reqVO.getDailyPowerUsage())
                .betweenIfPresent(IotRdDailyReportDO::getProductionTime, reqVO.getProductionTime())
                .betweenIfPresent(IotRdDailyReportDO::getNonProductionTime, reqVO.getNonProductionTime())
                .eqIfPresent(IotRdDailyReportDO::getRdNptReason, reqVO.getRdNptReason())
                .betweenIfPresent(IotRdDailyReportDO::getConstructionStartDate, reqVO.getConstructionStartDate())
                .betweenIfPresent(IotRdDailyReportDO::getConstructionEndDate, reqVO.getConstructionEndDate())
                .eqIfPresent(IotRdDailyReportDO::getProductionStatus, reqVO.getProductionStatus())
                .eqIfPresent(IotRdDailyReportDO::getExternalRental, reqVO.getExternalRental())
                .eqIfPresent(IotRdDailyReportDO::getNextPlan, reqVO.getNextPlan())
                .eqIfPresent(IotRdDailyReportDO::getRdStatus, reqVO.getRdStatus())
                .eqIfPresent(IotRdDailyReportDO::getMalfunction, reqVO.getMalfunction())
                .betweenIfPresent(IotRdDailyReportDO::getFaultDowntime, reqVO.getFaultDowntime())
                .eqIfPresent(IotRdDailyReportDO::getPersonnel, reqVO.getPersonnel())
                .eqIfPresent(IotRdDailyReportDO::getTotalStaffNum, reqVO.getTotalStaffNum())
                .eqIfPresent(IotRdDailyReportDO::getLeaveStaffNum, reqVO.getLeaveStaffNum())
                .eqIfPresent(IotRdDailyReportDO::getExtProperty, reqVO.getExtProperty())
                .eqIfPresent(IotRdDailyReportDO::getSort, reqVO.getSort())
                .eqIfPresent(IotRdDailyReportDO::getRemark, reqVO.getRemark())
                .eqIfPresent(IotRdDailyReportDO::getStatus, reqVO.getStatus())
                .eqIfPresent(IotRdDailyReportDO::getProcessInstanceId, reqVO.getProcessInstanceId())
                .eqIfPresent(IotRdDailyReportDO::getAuditStatus, reqVO.getAuditStatus())
                .betweenIfPresent(IotRdDailyReportDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(IotRdDailyReportDO::getCreateTime);
    }

    /**
     * 基础字段的查询逻辑 不包含 projectIds / taskIds 集合条件
     * @param reqVO
     * @return
     */
    default LambdaQueryWrapperX<IotRdDailyReportDO> buildBaseQuery(IotRdDailyReportPageReqVO reqVO) {
        return new LambdaQueryWrapperX<IotRdDailyReportDO>()
                .inIfPresent(IotRdDailyReportDO::getDeptId, reqVO.getDeptIds())
                .eqIfPresent(IotRdDailyReportDO::getProjectId, reqVO.getProjectId())
                .eqIfPresent(IotRdDailyReportDO::getTaskId, reqVO.getTaskId())               // 精确 taskId 保留
                .eqIfPresent(IotRdDailyReportDO::getProjectClassification, reqVO.getProjectClassification())
                .eqIfPresent(IotRdDailyReportDO::getTechniqueIds, reqVO.getTechniqueIds())
                .eqIfPresent(IotRdDailyReportDO::getDeviceIds, reqVO.getDeviceIds())
                .betweenIfPresent(IotRdDailyReportDO::getStartTime, reqVO.getStartTime())
                .betweenIfPresent(IotRdDailyReportDO::getEndTime, reqVO.getEndTime())
                .eqIfPresent(IotRdDailyReportDO::getCumulativeWorkingWell, reqVO.getCumulativeWorkingWell())
                .eqIfPresent(IotRdDailyReportDO::getCumulativeWorkingLayers, reqVO.getCumulativeWorkingLayers())
                .eqIfPresent(IotRdDailyReportDO::getDailyPumpTrips, reqVO.getDailyPumpTrips())
                .eqIfPresent(IotRdDailyReportDO::getDailyToolsSand, reqVO.getDailyToolsSand())
                .eqIfPresent(IotRdDailyReportDO::getRunCount, reqVO.getRunCount())
                .eqIfPresent(IotRdDailyReportDO::getBridgePlug, reqVO.getBridgePlug())
                .eqIfPresent(IotRdDailyReportDO::getWaterVolume, reqVO.getWaterVolume())
                .eqIfPresent(IotRdDailyReportDO::getHourCount, reqVO.getHourCount())
                .eqIfPresent(IotRdDailyReportDO::getDailyFuel, reqVO.getDailyFuel())
                .eqIfPresent(IotRdDailyReportDO::getDailyPowerUsage, reqVO.getDailyPowerUsage())
                .betweenIfPresent(IotRdDailyReportDO::getProductionTime, reqVO.getProductionTime())
                .betweenIfPresent(IotRdDailyReportDO::getNonProductionTime, reqVO.getNonProductionTime())
                .eqIfPresent(IotRdDailyReportDO::getRdNptReason, reqVO.getRdNptReason())
                .betweenIfPresent(IotRdDailyReportDO::getConstructionStartDate, reqVO.getConstructionStartDate())
                .betweenIfPresent(IotRdDailyReportDO::getConstructionEndDate, reqVO.getConstructionEndDate())
                .eqIfPresent(IotRdDailyReportDO::getProductionStatus, reqVO.getProductionStatus())
                .eqIfPresent(IotRdDailyReportDO::getExternalRental, reqVO.getExternalRental())
                .eqIfPresent(IotRdDailyReportDO::getNextPlan, reqVO.getNextPlan())
                .eqIfPresent(IotRdDailyReportDO::getRdStatus, reqVO.getRdStatus())
                .eqIfPresent(IotRdDailyReportDO::getMalfunction, reqVO.getMalfunction())
                .betweenIfPresent(IotRdDailyReportDO::getFaultDowntime, reqVO.getFaultDowntime())
                .eqIfPresent(IotRdDailyReportDO::getPersonnel, reqVO.getPersonnel())
                .eqIfPresent(IotRdDailyReportDO::getTotalStaffNum, reqVO.getTotalStaffNum())
                .eqIfPresent(IotRdDailyReportDO::getLeaveStaffNum, reqVO.getLeaveStaffNum())
                .eqIfPresent(IotRdDailyReportDO::getExtProperty, reqVO.getExtProperty())
                .eqIfPresent(IotRdDailyReportDO::getSort, reqVO.getSort())
                .eqIfPresent(IotRdDailyReportDO::getRemark, reqVO.getRemark())
                .eqIfPresent(IotRdDailyReportDO::getStatus, reqVO.getStatus())
                .eqIfPresent(IotRdDailyReportDO::getProcessInstanceId, reqVO.getProcessInstanceId())
                .eqIfPresent(IotRdDailyReportDO::getAuditStatus, reqVO.getAuditStatus())
                .betweenIfPresent(IotRdDailyReportDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(IotRdDailyReportDO::getCreateTime);
    }

    /**
     * 根据条件查询 瑞都 日报记录
     *
     * @param deptId     施工队伍 id
     * @param taskId     任务ID，可选参数，用于筛选任务ID匹配的记录
     * @param dateTimeStr   日报日期
     * @return 返回符合条件的 瑞都 日报记录
     */
    default IotRdDailyReportDO selectExistReport(Long deptId, Long taskId, String dateTimeStr) {
        LambdaQueryWrapperX<IotRdDailyReportDO> wrapper = new LambdaQueryWrapperX<>();

        // 施工队伍条件
        wrapper.eqIfPresent(IotRdDailyReportDO::getDeptId, deptId);
        // 任务相关条件：若 taskId 非空，则按 taskId 匹配；否则查询 project_id 和 task_id 均为 null 的记录

        wrapper.isNull(IotRdDailyReportDO::getProjectId)
                .isNull(IotRdDailyReportDO::getTaskId);
        // 日期条件
        if (StrUtil.isNotBlank(dateTimeStr)) {
            wrapper.apply("DATE(create_time) = {0}", dateTimeStr);
        }
        wrapper.last("limit 1");
        return selectOne(wrapper);
    }

    /**
     * 根据条件查询 瑞都 指定施工队伍 指定日期 日报记录
     *
     * @param deptId     施工队伍 id
     * @param taskId     任务ID，可选参数，用于筛选任务ID匹配的记录
     * @param dateTimeStr   日报日期
     * @return 返回符合条件的 瑞都 日报记录
     */
    default IotRdDailyReportDO selectExistTaskReport(Long deptId, Long taskId, String dateTimeStr) {
        LambdaQueryWrapperX<IotRdDailyReportDO> wrapper = new LambdaQueryWrapperX<>();

        // 施工队伍条件
        wrapper.eqIfPresent(IotRdDailyReportDO::getDeptId, deptId);
        // 任务相关条件：若 taskId 非空，则按 taskId 匹配；否则查询 project_id 和 task_id 均为 null 的记录

        wrapper.eqIfPresent(IotRdDailyReportDO::getTaskId, taskId);
        // 日期条件
        if (StrUtil.isNotBlank(dateTimeStr)) {
            wrapper.apply("DATE(create_time) = {0}", dateTimeStr);
        }
        wrapper.last("limit 1");
        return selectOne(wrapper);
    }

    /**
     * 瑞都日报 关联的任务进度
     * @param reqVO 查询条件
     */
    List<IotRdDailyReportDO> selectListGrouped(@Param("reqVO") IotRdDailyReportPageReqVO reqVO);

    /**
     * 瑞都日报 关联的任务 施工周期
     */
    List<IotRdDailyReportTaskPeriodVO> taskConstructionPeriod();

    /**
     * 根据 井号 查询 瑞都日报 按照队伍分组 小计
     * @param page
     * @param reqVO
     * @param projectIds
     * @return
     */
    IPage<IotRdDailyReportDO> rdWellNameDailyReports(IPage<IotRdDailyReportDO> page, @Param("reqVO") IotRdDailyReportPageReqVO reqVO,
                                                     @Param("taskIds") Collection<Long> taskIds,
                                                     @Param("projectIds") Collection<Long> projectIds, @Param("deptIds") Collection<Long> deptIds);

    /**
     * 根据 井号 查询 瑞都日报 按照队伍分组 小计 查询小组内最后1条记录id
     * @param page
     * @param reqVO
     * @param projectIds
     * @return
     */
    @TenantIgnore
    List<IotRdDailyReportDO> rdWellNameDailyReportsGroupIds(IPage<IotRdDailyReportDO> page, @Param("reqVO") IotRdDailyReportPageReqVO reqVO,
                                                            @Param("taskIds") Collection<Long> taskIds,
                                                            @Param("projectIds") Collection<Long> projectIds, @Param("deptIds") Collection<Long> deptIds);

    /**
     * 根据 队伍 查询 瑞都日报 按照任务井分组 小计
     * @param page
     * @param reqVO
     * @param projectIds
     * @return
     */
    IPage<IotRdDailyReportDO> rdDeptDailyReports(IPage<IotRdDailyReportDO> page, @Param("reqVO") IotRdDailyReportPageReqVO reqVO,
                                                 @Param("taskIds") Collection<Long> taskIds,
                                                 @Param("projectIds") Collection<Long> projectIds, @Param("deptIds") Collection<Long> deptIds);

    /**
     * 以队伍为维度 查询 井号 分组后的 瑞都日报 按照任务井分组 小计 查询小组内最后1条记录id
     * @param page
     * @param reqVO
     * @param projectIds
     * @return
     */
    List<IotRdDailyReportDO> rdDeptDailyReportsGroupIds(IPage<IotRdDailyReportDO> page, @Param("reqVO") IotRdDailyReportPageReqVO reqVO,
                                                        @Param("taskIds") Collection<Long> taskIds,
                                                        @Param("projectIds") Collection<Long> projectIds, @Param("deptIds") Collection<Long> deptIds);

    /**
     * 瑞都日报状态统计
     * @param reqVO
     * @return
     */
    List<AllOrderResp> selectStatusNumber(@Param("reqVO") IotMaintainPageReqVO reqVO);

}