package jnpf.attendance.event;

import com.alibaba.fastjson.JSON;
import jnpf.attendance.service.AttendanceUserService;
import jnpf.constants.MessageTopicConstants;
import jnpf.database.util.TenantDataSourceUtil;
import jnpf.message.model.permission.PermissionRelationOrganizeUserListDTO;
import jnpf.model.attendance.model.OrganizeUserConsumerDTO;
import jnpf.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQMessageListener;
import org.apache.rocketmq.spring.core.RocketMQListener;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static jnpf.constants.RedisConstant.GROUP_JOIN_USERS_KEY;
import static jnpf.constants.RedisConstant.GROUP_ONBOARDING_KEY;

/**
 * 入职请求信息
 */
@Component
@RocketMQMessageListener(
        topic = MessageTopicConstants.PERSONNEL_ONBOARDING_TOPIC,
        consumerGroup = MessageTopicConstants.ONBOARDING_GROUP,
        replyTimeout = 600000,
        maxReconsumeTimes = 3,
        nameServer = "${spring.cloud.stream.rocketmq.binder.name-server}"
)
@Slf4j
public class OnboardingConsumerMQListener implements RocketMQListener<String> {
    @Autowired
    private AttendanceUserService attendanceUserService;
    @Autowired
    private RedissonClient redissonClient;

    @Override
    public void onMessage(String message) {
        if (StringUtil.isEmpty(message)) {
            return;
        }
        log.error("接收入职/变动请求信息{}", message);
        OrganizeUserConsumerDTO messageList = JSON.parseObject(message, OrganizeUserConsumerDTO.class);
        if (StringUtil.equals(messageList.getBeforeOrgId(), messageList.getOrganizeId())) {
            return;
        }
        RLock lock = null;
        try {
            String key = String.format(GROUP_JOIN_USERS_KEY, messageList.getUserId());
            lock = redissonClient.getLock(key);
            if (!lock.tryLock(5, 10, TimeUnit.SECONDS)) {
                log.error("接收组织人员添加通知，目前用户【{}】正在被变更！", messageList.getUserId());
                throw new RuntimeException(String.format("接收组织人员添加通知，目前用户【%s】正在被变更，触发重试", messageList.getUserId()));
            }
            PermissionRelationOrganizeUserListDTO permissionRelationOrganizeUserListDTO = new PermissionRelationOrganizeUserListDTO();
            permissionRelationOrganizeUserListDTO.setUserId(messageList.getUserId());
            permissionRelationOrganizeUserListDTO.setOldOrganizeId(messageList.getBeforeOrgId());
            permissionRelationOrganizeUserListDTO.setOrganizeId(messageList.getOrganizeId());
            permissionRelationOrganizeUserListDTO.setEntryDate(messageList.getEntryDate());
            permissionRelationOrganizeUserListDTO.setTenantId(messageList.getTenantId());
            TenantDataSourceUtil.switchTenant(messageList.getTenantId());
            if (StringUtil.isNotEmpty(messageList.getBeforeOrgId())) {
                attendanceUserService.removeUsers(List.of(permissionRelationOrganizeUserListDTO), false);
            }
            attendanceUserService.addUsers(List.of(permissionRelationOrganizeUserListDTO), true);
        } catch (Exception e) {
            log.error("消息解析异常: message={}", message, e);
            throw new RuntimeException(e.getMessage());
        } finally{
            if (Objects.nonNull(lock) && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }

    }
}
