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

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.module.pms.controller.admin.iotprojecttaskplan.vo.IotProjectTaskPlanPageReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotprojecttaskplan.IotProjectTaskPlanDO;
import org.apache.ibatis.annotations.Mapper;

import java.time.LocalDate;
import java.time.LocalDateTime;

/**
 * 日报任务计划(工作量) Mapper
 *
 * @author ruqi
 */
@Mapper
public interface IotProjectTaskPlanMapper extends BaseMapperX<IotProjectTaskPlanDO> {

    default PageResult<IotProjectTaskPlanDO> selectPage(IotProjectTaskPlanPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<IotProjectTaskPlanDO>()
                // .eqIfPresent(IotProjectTaskPlanDO::getDeptId, reqVO.getDeptId())
                .inIfPresent(IotProjectTaskPlanDO::getDeptId, reqVO.getDeptIds())
                .eqIfPresent(IotProjectTaskPlanDO::getCompanyId, reqVO.getCompanyId())
                .eqIfPresent(IotProjectTaskPlanDO::getProjectId, reqVO.getProjectId())
                .eqIfPresent(IotProjectTaskPlanDO::getTaskId, reqVO.getTaskId())
                .eqIfPresent(IotProjectTaskPlanDO::getBusiness, reqVO.getBusiness())
                .eqIfPresent(IotProjectTaskPlanDO::getStatus, reqVO.getStatus())
                .eqIfPresent(IotProjectTaskPlanDO::getDescription, reqVO.getDescription())
                .betweenIfPresent(IotProjectTaskPlanDO::getStartTime, reqVO.getStartTime())
                .betweenIfPresent(IotProjectTaskPlanDO::getEndTime, reqVO.getEndTime())
                .eqIfPresent(IotProjectTaskPlanDO::getPlanGasInjection, reqVO.getPlanGasInjection())
                .eqIfPresent(IotProjectTaskPlanDO::getPlanFootage, reqVO.getPlanFootage())
                .eqIfPresent(IotProjectTaskPlanDO::getPlanWellTrips, reqVO.getPlanWellTrips())
                .eqIfPresent(IotProjectTaskPlanDO::getPlanLayers, reqVO.getPlanLayers())
                .eqIfPresent(IotProjectTaskPlanDO::getWorkloadUnit, reqVO.getWorkloadUnit())
                .eqIfPresent(IotProjectTaskPlanDO::getRemark, reqVO.getRemark())
                .betweenIfPresent(IotProjectTaskPlanDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(IotProjectTaskPlanDO::getId));
    }

    /**
     * 判断指定部门在指定月份（基于 startTime 的年月）是否存在记录
     * @param deptId    部门ID
     * @param startTime 用于提取年月的起始时间
     * @return true-存在，false-不存在
     */
    default boolean existsByDeptIdAndMonth(Long deptId, LocalDateTime startTime) {
        if (deptId == null || startTime == null) {
            return false; // 可根据业务决定是否跳过校验（例如，必填字段不允许为空）
        }
        // 计算该月起始和结束时间（包含整月，精确到秒）
        LocalDate date = startTime.toLocalDate();
        LocalDateTime startOfMonth = date.withDayOfMonth(1).atStartOfDay();
        LocalDateTime endOfMonth = date.withDayOfMonth(date.lengthOfMonth()).atTime(23, 59, 59);

        return selectCount(new LambdaQueryWrapperX<IotProjectTaskPlanDO>()
                .eq(IotProjectTaskPlanDO::getDeptId, deptId)
                .between(IotProjectTaskPlanDO::getStartTime, startOfMonth, endOfMonth)
        ) > 0;
    }

    /**
     * 查询指定部门在指定月份（基于 startTime 的年月）是否存在记录，可排除指定ID
     * @param deptId    部门ID
     * @param startTime 用于提取年月的起始时间
     * @param excludeId 需要排除的记录ID（更新时传入自身ID，新增时传 null）
     * @return 匹配到的第一条记录，若无则返回 null
     */
    default IotProjectTaskPlanDO selectOneByDeptIdAndMonth(Long deptId, LocalDateTime startTime, String business, Long excludeId) {
        if (deptId == null || startTime == null) {
            return null;
        }
        // 计算该月起始和结束时间
        LocalDate date = startTime.toLocalDate();
        LocalDateTime startOfMonth = date.withDayOfMonth(1).atStartOfDay();
        LocalDateTime endOfMonth = date.withDayOfMonth(date.lengthOfMonth()).atTime(23, 59, 59);

        // 显式声明为 LambdaQueryWrapperX 类型，避免类型推断问题
        LambdaQueryWrapperX<IotProjectTaskPlanDO> wrapper = new LambdaQueryWrapperX<>();
        wrapper.eq(IotProjectTaskPlanDO::getDeptId, deptId)
                .eq(IotProjectTaskPlanDO::getBusiness, business)
                .between(IotProjectTaskPlanDO::getStartTime, startOfMonth, endOfMonth);

        // 排除指定ID（若不为null）
        if (excludeId != null) {
            wrapper.ne(IotProjectTaskPlanDO::getId, excludeId);
        }

        // 只取第一条（如果有唯一约束，只会有一条，取第一条即可）
        return selectOne(wrapper);
    }
}