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

import com.njcn.rdms.framework.common.pojo.PageResult;
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
import com.njcn.rdms.framework.mybatis.core.mapper.BaseMapperX;
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.njcn.rdms.module.project.controller.admin.personal.vo.item.PersonalItemPageReqVO;
import com.njcn.rdms.module.project.dal.dataobject.personal.PersonalItemDO;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.List;

@Mapper
public interface PersonalItemMapper extends BaseMapperX<PersonalItemDO> {

    default PersonalItemDO selectByIdAndOwnerId(Long id, Long ownerId) {
        return selectOne(new LambdaQueryWrapperX<PersonalItemDO>()
                .eq(PersonalItemDO::getId, id)
                .eq(PersonalItemDO::getOwnerId, ownerId));
    }

    default PageResult<PersonalItemDO> selectPageByOwnerId(Long ownerId, PersonalItemPageReqVO reqVO) {
        LambdaQueryWrapperX<PersonalItemDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eq(PersonalItemDO::getOwnerId, ownerId);
        queryWrapper.eqIfPresent(PersonalItemDO::getStatusCode, reqVO.getStatusCode());
        queryWrapper.betweenIfPresent(BaseDO::getUpdateTime, reqVO.getUpdateTime());
        queryWrapper.orderByDesc(BaseDO::getUpdateTime);
        queryWrapper.orderByDesc(PersonalItemDO::getId);
        if (StringUtils.hasText(reqVO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper.like(PersonalItemDO::getTaskTitle, reqVO.getKeyword()));
        }
        return selectPage(reqVO, queryWrapper);
    }

    default int updateStatusByIdAndStatus(Long id, String fromStatus, String toStatus, String lastStatusReason) {
        PersonalItemDO update = new PersonalItemDO();
        update.setStatusCode(toStatus);
        update.setLastStatusReason(lastStatusReason);
        return update(update, new LambdaQueryWrapperX<PersonalItemDO>()
                .eq(PersonalItemDO::getId, id)
                .eq(PersonalItemDO::getStatusCode, fromStatus));
    }

    default int deleteByIdAndStatus(Long id, String fromStatus) {
        return delete(new LambdaQueryWrapperX<PersonalItemDO>()
                .eq(PersonalItemDO::getId, id)
                .eq(PersonalItemDO::getStatusCode, fromStatus));
    }

    default List<PersonalItemDO> selectPlannedListByOwnerIdAndOverlap(Long ownerId, LocalDate startDate, LocalDate endDate,
                                                                      String excludedStatusCode) {
        LambdaQueryWrapperX<PersonalItemDO> queryWrapper = new LambdaQueryWrapperX<PersonalItemDO>()
                .eq(PersonalItemDO::getOwnerId, ownerId);
        if (StringUtils.hasText(excludedStatusCode)) {
            queryWrapper.ne(PersonalItemDO::getStatusCode, excludedStatusCode);
        }
        queryWrapper.isNotNull(PersonalItemDO::getPlannedStartDate);
        queryWrapper.isNotNull(PersonalItemDO::getPlannedEndDate);
        queryWrapper.le(PersonalItemDO::getPlannedStartDate, endDate);
        queryWrapper.ge(PersonalItemDO::getPlannedEndDate, startDate);
        queryWrapper.orderByAsc(PersonalItemDO::getPlannedStartDate);
        queryWrapper.orderByAsc(PersonalItemDO::getId);
        return selectList(queryWrapper);
    }

    default List<PersonalItemDO> selectListByOwnerIdAndStatusNot(Long ownerId, String excludedStatusCode) {
        if (ownerId == null) {
            return List.of();
        }
        LambdaQueryWrapperX<PersonalItemDO> queryWrapper = new LambdaQueryWrapperX<PersonalItemDO>()
                .eq(PersonalItemDO::getOwnerId, ownerId);
        if (StringUtils.hasText(excludedStatusCode)) {
            queryWrapper.ne(PersonalItemDO::getStatusCode, excludedStatusCode);
        }
        queryWrapper.orderByAsc(PersonalItemDO::getId);
        return selectList(queryWrapper);
    }
}
