package com.njcn.rdms.module.project.dal.mysql.performance;

import com.njcn.rdms.framework.common.pojo.PageResult;
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.njcn.rdms.framework.mybatis.core.mapper.BaseMapperX;
import com.njcn.rdms.module.project.constant.PerformanceConstants;
import com.njcn.rdms.module.project.controller.admin.performance.vo.PerformanceSheetPageReqVO;
import com.njcn.rdms.module.project.dal.dataobject.performance.PerformanceSheetDO;
import org.apache.ibatis.annotations.Mapper;

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

@Mapper
public interface PerformanceSheetMapper extends BaseMapperX<PerformanceSheetDO> {

    default PerformanceSheetDO selectByEmployeeIdAndPeriodMonth(Long employeeId, String periodMonth) {
        return selectOne(new LambdaQueryWrapperX<PerformanceSheetDO>()
                .eq(PerformanceSheetDO::getEmployeeId, employeeId)
                .eq(PerformanceSheetDO::getPeriodMonth, periodMonth));
    }

    default PerformanceSheetDO selectLatestHistoryWithFile(Long employeeId, String beforePeriodMonth) {
        return selectOne(new LambdaQueryWrapperX<PerformanceSheetDO>()
                .eq(PerformanceSheetDO::getEmployeeId, employeeId)
                .lt(PerformanceSheetDO::getPeriodMonth, beforePeriodMonth)
                .isNotNull(PerformanceSheetDO::getFileId)
                .orderByDesc(PerformanceSheetDO::getPeriodMonth)
                .orderByDesc(PerformanceSheetDO::getId)
                .last("LIMIT 1"));
    }

    default PageResult<PerformanceSheetDO> selectEmployeePage(Long employeeId, PerformanceSheetPageReqVO reqVO) {
        LambdaQueryWrapperX<PerformanceSheetDO> wrapper = buildPageQuery(reqVO)
                .eq(PerformanceSheetDO::getEmployeeId, employeeId)
                .in(PerformanceSheetDO::getStatusCode, List.of(
                        PerformanceConstants.STATUS_SENT,
                        PerformanceConstants.STATUS_CONFIRMED))
                .orderByDesc(PerformanceSheetDO::getPeriodMonth)
                .orderByDesc(PerformanceSheetDO::getId);
        return selectPage(reqVO, wrapper);
    }

    default PageResult<PerformanceSheetDO> selectEmployeePage(Collection<Long> employeeIds,
            PerformanceSheetPageReqVO reqVO) {
        if (employeeIds == null || employeeIds.isEmpty()) {
            return new PageResult<>(List.of(), 0L);
        }
        LambdaQueryWrapperX<PerformanceSheetDO> wrapper = buildPageQuery(reqVO)
                .in(PerformanceSheetDO::getEmployeeId, employeeIds)
                .orderByDesc(PerformanceSheetDO::getPeriodMonth)
                .orderByDesc(PerformanceSheetDO::getId);
        return selectPage(reqVO, wrapper);
    }

    default List<PerformanceSheetDO> selectListByEmployeeIdsAndPeriodMonth(Collection<Long> employeeIds,
            String periodMonth) {
        if (employeeIds == null || employeeIds.isEmpty()) {
            return List.of();
        }
        return selectList(new LambdaQueryWrapperX<PerformanceSheetDO>()
                .in(PerformanceSheetDO::getEmployeeId, employeeIds)
                .eq(PerformanceSheetDO::getPeriodMonth, periodMonth)
                .orderByAsc(PerformanceSheetDO::getEmployeeName));
    }

    /**
     * 按员工 ID 列表与月份区间查询绩效表。
     */
    default List<PerformanceSheetDO> selectListByEmployeeIdsAndPeriodMonthRange(Collection<Long> employeeIds,
            String periodMonthStart,
            String periodMonthEnd) {
        if (employeeIds == null || employeeIds.isEmpty()) {
            return List.of();
        }
        return selectList(new LambdaQueryWrapperX<PerformanceSheetDO>()
                .in(PerformanceSheetDO::getEmployeeId, employeeIds)
                .geIfPresent(PerformanceSheetDO::getPeriodMonth, periodMonthStart)
                .leIfPresent(PerformanceSheetDO::getPeriodMonth, periodMonthEnd)
                .orderByAsc(PerformanceSheetDO::getEmployeeName));
    }

    default List<PerformanceSheetDO> selectExportList(PerformanceSheetPageReqVO reqVO, Collection<Long> employeeIds) {
        if (employeeIds == null || employeeIds.isEmpty()) {
            return List.of();
        }
        return selectList(buildPageQuery(reqVO)
                .in(PerformanceSheetDO::getEmployeeId, employeeIds)
                .orderByDesc(PerformanceSheetDO::getPeriodMonth)
                .orderByDesc(PerformanceSheetDO::getId));
    }

    default int updateExcelByIdAndVersion(PerformanceSheetDO update, Long id, Integer fileVersion) {
        return update(update, new LambdaQueryWrapperX<PerformanceSheetDO>()
                .eq(PerformanceSheetDO::getId, id)
                .eq(PerformanceSheetDO::getFileVersion, fileVersion));
    }

    default int updateStatusByIdAndStatus(PerformanceSheetDO update, Long id, String fromStatus) {
        return update(update, new LambdaQueryWrapperX<PerformanceSheetDO>()
                .eq(PerformanceSheetDO::getId, id)
                .eq(PerformanceSheetDO::getStatusCode, fromStatus));
    }

    default int updateByIdAndStatusAndSignOffStatus(PerformanceSheetDO update, Long id, String fromStatus,
            String fromSignOffStatus) {
        return update(update, new LambdaQueryWrapperX<PerformanceSheetDO>()
                .eq(PerformanceSheetDO::getId, id)
                .eq(PerformanceSheetDO::getStatusCode, fromStatus)
                .eq(PerformanceSheetDO::getSignOffStatus, fromSignOffStatus));
    }

    private LambdaQueryWrapperX<PerformanceSheetDO> buildPageQuery(PerformanceSheetPageReqVO reqVO) {
        return new LambdaQueryWrapperX<PerformanceSheetDO>()
                .geIfPresent(PerformanceSheetDO::getPeriodMonth, reqVO.getPeriodMonthStart())
                .leIfPresent(PerformanceSheetDO::getPeriodMonth, reqVO.getPeriodMonthEnd())
                .likeIfPresent(PerformanceSheetDO::getEmployeeName, reqVO.getEmployeeName())
                .eqIfPresent(PerformanceSheetDO::getEmployeeDeptId, reqVO.getEmployeeDeptId())
                .likeIfPresent(PerformanceSheetDO::getEmployeeDeptName, reqVO.getEmployeeDeptName())
                .eqIfPresent(PerformanceSheetDO::getManagerId, reqVO.getManagerId())
                .likeIfPresent(PerformanceSheetDO::getManagerName, reqVO.getManagerName())
                .eqIfPresent(PerformanceSheetDO::getStatusCode, reqVO.getStatusCode())
                .eqIfPresent(PerformanceSheetDO::getSignOffStatus, reqVO.getSignOffStatus());
    }
}
