package com.njcn.rdms.module.system.service.permission;

import cn.hutool.core.collection.CollUtil;
import com.njcn.rdms.framework.common.util.object.BeanUtils;
import com.njcn.rdms.module.system.controller.admin.permission.vo.userVisibilityConfig.UserVisibilityConfigSaveReqVO;
import com.njcn.rdms.module.system.dal.dataobject.permission.UserVisibilityConfigDO;
import com.njcn.rdms.module.system.dal.mysql.permission.UserVisibilityConfigMapper;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.njcn.rdms.module.system.enums.ErrorCodeConstants.USER_VISIBILITY_CONFIG_TYPE_FIELD_MISMATCH;

/**
 * 用户数据可见性配置 Service 实现
 */
@Service
public class UserVisibilityConfigServiceImpl implements UserVisibilityConfigService {

    @Resource
    private UserVisibilityConfigMapper userVisibilityConfigMapper;

    @Override
    public UserVisibilityConfigDO getByUserId(Long userId) {
        return userVisibilityConfigMapper.selectByUserId(userId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveOrUpdate(UserVisibilityConfigSaveReqVO reqVO) {
        // 校验 visibilityType 与字段的一致性
        validateTypeFieldConsistency(reqVO);

        UserVisibilityConfigDO existing = userVisibilityConfigMapper.selectByUserId(reqVO.getUserId());
        if (existing == null) {
            // 不存在 → insert
            UserVisibilityConfigDO configDO = BeanUtils.toBean(reqVO, UserVisibilityConfigDO.class);
            userVisibilityConfigMapper.insert(configDO);
            return configDO.getId();
        } else {
            // 已存在 → update（覆盖全部字段）
            UserVisibilityConfigDO configDO = BeanUtils.toBean(reqVO, UserVisibilityConfigDO.class);
            configDO.setId(existing.getId());
            userVisibilityConfigMapper.updateById(configDO);
            return existing.getId();
        }
    }

    @Override
    public void deleteByUserId(Long userId) {
        UserVisibilityConfigDO existing = userVisibilityConfigMapper.selectByUserId(userId);
        if (existing != null) {
            userVisibilityConfigMapper.deleteById(existing.getId());
        }
    }

    /**
     * 校验 visibilityType 与关联字段的一致性：
     * - all：directionIds / projectIds 均须为 null
     * - directions：directionIds 非空；projectIds 须为 null
     * - projects：projectIds 非空；directionIds 须为 null
     */
    private void validateTypeFieldConsistency(UserVisibilityConfigSaveReqVO reqVO) {
        String type = reqVO.getVisibilityType();
        boolean hasDirectionIds = CollUtil.isNotEmpty(reqVO.getVisibleDirectionIds());
        boolean hasProjectIds = CollUtil.isNotEmpty(reqVO.getVisibleProjectIds());

        switch (type) {
            case "all" -> {
                if (hasDirectionIds || hasProjectIds) {
                    throw exception(USER_VISIBILITY_CONFIG_TYPE_FIELD_MISMATCH, type,
                            "type=all 时，visibleDirectionIds 和 visibleProjectIds 均须为空");
                }
            }
            case "directions" -> {
                if (!hasDirectionIds) {
                    throw exception(USER_VISIBILITY_CONFIG_TYPE_FIELD_MISMATCH, type,
                            "type=directions 时，visibleDirectionIds 不能为空");
                }
                if (hasProjectIds) {
                    throw exception(USER_VISIBILITY_CONFIG_TYPE_FIELD_MISMATCH, type,
                            "type=directions 时，visibleProjectIds 须为空");
                }
            }
            case "projects" -> {
                if (!hasProjectIds) {
                    throw exception(USER_VISIBILITY_CONFIG_TYPE_FIELD_MISMATCH, type,
                            "type=projects 时，visibleProjectIds 不能为空");
                }
                if (hasDirectionIds) {
                    throw exception(USER_VISIBILITY_CONFIG_TYPE_FIELD_MISMATCH, type,
                            "type=projects 时，visibleDirectionIds 须为空");
                }
            }
            default -> throw exception(USER_VISIBILITY_CONFIG_TYPE_FIELD_MISMATCH, type,
                    "不支持的 visibilityType，合法值：all / directions / projects");
        }
    }

}
