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

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.status.vo.transition.ObjectStatusTransitionPageReqVO;
import com.njcn.rdms.module.project.dal.dataobject.status.ObjectStatusTransitionDO;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.util.StringUtils;

import java.util.List;

@Mapper
public interface ObjectStatusTransitionMapper extends BaseMapperX<ObjectStatusTransitionDO> {

    default PageResult<ObjectStatusTransitionDO> selectPage(ObjectStatusTransitionPageReqVO reqVO) {
        LambdaQueryWrapperX<ObjectStatusTransitionDO> queryWrapper = new LambdaQueryWrapperX<>();
        if (StringUtils.hasText(reqVO.getKeyword())) {
            queryWrapper.and(wrapper -> wrapper.like(ObjectStatusTransitionDO::getActionCode, reqVO.getKeyword())
                    .or()
                    .like(ObjectStatusTransitionDO::getActionName, reqVO.getKeyword()));
        }
        queryWrapper.eqIfPresent(ObjectStatusTransitionDO::getObjectType, reqVO.getObjectType())
                .eqIfPresent(ObjectStatusTransitionDO::getFromStatusCode, reqVO.getFromStatusCode())
                .eqIfPresent(ObjectStatusTransitionDO::getToStatusCode, reqVO.getToStatusCode())
                .eqIfPresent(ObjectStatusTransitionDO::getStatus, reqVO.getStatus())
                .betweenIfPresent(BaseDO::getUpdateTime, reqVO.getUpdateTime())
                .orderByAsc(ObjectStatusTransitionDO::getObjectType)
                .orderByAsc(ObjectStatusTransitionDO::getFromStatusCode)
                .orderByAsc(ObjectStatusTransitionDO::getActionCode)
                .orderByAsc(ObjectStatusTransitionDO::getId);
        return selectPage(reqVO, queryWrapper);
    }

    /**
     * 按对象类型、起始状态、动作编码查询唯一流转，不区分启停状态。
     */
    default ObjectStatusTransitionDO selectByUniqueKey(String objectType, String fromStatusCode, String actionCode) {
        return selectOne(new LambdaQueryWrapperX<ObjectStatusTransitionDO>()
                .eq(ObjectStatusTransitionDO::getObjectType, objectType)
                .eq(ObjectStatusTransitionDO::getFromStatusCode, fromStatusCode)
                .eq(ObjectStatusTransitionDO::getActionCode, actionCode));
    }

    default ObjectStatusTransitionDO selectByObjectTypeAndFromStatusAndAction(String objectType,
                                                                              String fromStatusCode,
                                                                              String actionCode) {
        return selectOne(new LambdaQueryWrapperX<ObjectStatusTransitionDO>()
                .eq(ObjectStatusTransitionDO::getObjectType, objectType)
                .eq(ObjectStatusTransitionDO::getFromStatusCode, fromStatusCode)
                .eq(ObjectStatusTransitionDO::getActionCode, actionCode)
                .eq(ObjectStatusTransitionDO::getStatus, 0));
    }

    default List<ObjectStatusTransitionDO> selectListByObjectTypeAndFromStatus(String objectType, String fromStatusCode) {
        return selectList(new LambdaQueryWrapperX<ObjectStatusTransitionDO>()
                .eq(ObjectStatusTransitionDO::getObjectType, objectType)
                .eq(ObjectStatusTransitionDO::getFromStatusCode, fromStatusCode)
                .eq(ObjectStatusTransitionDO::getStatus, 0));
    }

    default List<ObjectStatusTransitionDO> selectListByObjectTypeAndFromStatuses(String objectType, List<String> fromStatusCodes) {
        return selectList(new LambdaQueryWrapperX<ObjectStatusTransitionDO>()
                .eq(ObjectStatusTransitionDO::getObjectType, objectType)
                .in(ObjectStatusTransitionDO::getFromStatusCode, fromStatusCodes)
                .eq(ObjectStatusTransitionDO::getStatus, 0));
    }

    /**
     * 统计某状态编码在流转配置中的引用次数。
     */
    default Long selectReferenceCountByStatusCode(String objectType, String statusCode) {
        return selectCount(new LambdaQueryWrapperX<ObjectStatusTransitionDO>()
                .eq(ObjectStatusTransitionDO::getObjectType, objectType)
                .and(wrapper -> wrapper.eq(ObjectStatusTransitionDO::getFromStatusCode, statusCode)
                        .or()
                        .eq(ObjectStatusTransitionDO::getToStatusCode, statusCode)));
    }

    /**
     * 反查动作中文名：同 objectType + action_code 下 action_name 唯一一致（已核实），取任一行。
     * 供错误提示等用户可见文案使用；查不到返回 null，由上层回退到原 actionCode。
     */
    default String selectActionNameByObjectTypeAndAction(String objectType, String actionCode) {
        List<ObjectStatusTransitionDO> list = selectList(new LambdaQueryWrapperX<ObjectStatusTransitionDO>()
                .eq(ObjectStatusTransitionDO::getObjectType, objectType)
                .eq(ObjectStatusTransitionDO::getActionCode, actionCode)
                .last("LIMIT 1"));
        return list.isEmpty() ? null : list.get(0).getActionName();
    }

    /**
     * 物理删除
     */
    @Delete("DELETE FROM rdms_object_status_transition WHERE id = #{id}")
    int physicalDeleteById(Long id);

}
