package com.njcn.rdms.module.project.service.status;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.njcn.rdms.framework.common.pojo.PageResult;
import com.njcn.rdms.module.project.controller.admin.status.vo.model.ObjectStatusModelPageReqVO;
import com.njcn.rdms.module.project.controller.admin.status.vo.model.ObjectStatusModelRespVO;
import com.njcn.rdms.module.project.controller.admin.status.vo.model.ObjectStatusModelSaveReqVO;
import com.njcn.rdms.module.project.dal.dataobject.status.ObjectStatusModelDO;
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusModelMapper;
import com.njcn.rdms.module.project.dal.mysql.status.ObjectStatusTransitionMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Objects;

import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.invalidParamException;

/**
 * 对象状态模型 Service 实现。
 */
@Service
public class ObjectStatusModelServiceImpl implements ObjectStatusModelService {

    @Resource
    private ObjectStatusModelMapper objectStatusModelMapper;
    @Resource
    private ObjectStatusTransitionMapper objectStatusTransitionMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createModel(ObjectStatusModelSaveReqVO createReqVO) {
        validateDuplicateStatusCode(createReqVO.getObjectType(), createReqVO.getStatusCode(), null);
        validateInitialStatusUnique(createReqVO.getObjectType(), createReqVO.getInitialFlag(), null);
        ObjectStatusModelDO model = BeanUtil.copyProperties(createReqVO, ObjectStatusModelDO.class);
        objectStatusModelMapper.insert(model);
        return model.getId();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateModel(ObjectStatusModelSaveReqVO updateReqVO) {
        ObjectStatusModelDO existing = validateModelExists(updateReqVO.getId());
        ObjectStatusModelDO update = BeanUtil.copyProperties(updateReqVO, ObjectStatusModelDO.class);

//        if (!Objects.equals(existing.getObjectType(), update.getObjectType())) {
//            throw invalidParamException("对象类型创建后不允许修改");
//        }
//        if (!Objects.equals(existing.getStatusCode(), update.getStatusCode())) {
//            throw invalidParamException("状态编码创建后不允许修改");
//        }

        validateDuplicateStatusCode(update.getObjectType(), update.getStatusCode(), existing.getId());
        validateInitialStatusUnique(update.getObjectType(), update.getInitialFlag(), existing.getId());

        existing.setStatusName(update.getStatusName());
        existing.setSort(update.getSort());
        existing.setStatus(update.getStatus());
        existing.setInitialFlag(update.getInitialFlag());
        existing.setTerminalFlag(update.getTerminalFlag());
        existing.setAllowEdit(update.getAllowEdit());
        existing.setRemark(update.getRemark());
        objectStatusModelMapper.updateById(existing);
    }

    @Override
    public ObjectStatusModelRespVO getModel(Long id) {
        return BeanUtil.copyProperties(objectStatusModelMapper.selectById(id), ObjectStatusModelRespVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteModel(Long id) {
        ObjectStatusModelDO existing = validateModelExists(id);
        Long referenceCount = objectStatusTransitionMapper.selectReferenceCountByStatusCode(existing.getObjectType(), existing.getStatusCode());
        if (referenceCount != null && referenceCount > 0) {
            throw invalidParamException("状态编码 [{}] 已被状态流转引用，不能删除", existing.getStatusCode());
        }
        objectStatusModelMapper.physicalDeleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteModelList(List<Long> ids) {
        for (int i = 0; i < ids.size(); i++) {
            this.deleteModel(ids.get(i));
        }
    }

    @Override
    public PageResult<ObjectStatusModelDO> getModelPage(ObjectStatusModelPageReqVO pageReqVO) {
        return objectStatusModelMapper.selectPage(pageReqVO);
    }

    /**
     * 校验同一对象类型下的状态编码不能重复。
     */
    private void validateDuplicateStatusCode(String objectType, String statusCode, Long excludeId) {
        ObjectStatusModelDO duplicate = objectStatusModelMapper.selectByObjectTypeAndStatusCode(objectType, statusCode);
        if (ObjectUtil.isNotNull(duplicate) && !Objects.equals(duplicate.getId(), excludeId)) {
            throw invalidParamException("对象状态模型 [{}] 下状态编码 [{}] 已存在", objectType, statusCode);
        }
    }

    /**
     * 校验同一对象状态模型只能存在一个初始状态。
     */
    private void validateInitialStatusUnique(String objectType, Boolean initialFlag, Long excludeId) {
        if (!Boolean.TRUE.equals(initialFlag)) {
            return;
        }
        ObjectStatusModelDO initialStatus = objectStatusModelMapper.selectInitialByObjectType(objectType);
        if (ObjectUtil.isNotNull(initialStatus) && !Objects.equals(initialStatus.getId(), excludeId)) {
            throw invalidParamException("对象状态模型 [{}] 已存在初始状态，不能重复配置", objectType);
        }
    }



    /**
     * 校验状态模型存在。
     */
    private ObjectStatusModelDO validateModelExists(Long id) {
        ObjectStatusModelDO model = objectStatusModelMapper.selectById(id);
        if (Objects.isNull(model)) {
            throw invalidParamException("状态模型不存在");
        }
        return model;
    }

}
