package com.red.circle.other.infra.gateway.user;

import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService;
import com.red.circle.other.infra.database.mongo.entity.team.team.TeamMember;
import com.red.circle.other.infra.database.mongo.service.team.team.TeamMemberService;
import com.red.circle.other.infra.database.rds.service.sys.EnumConfigService;
import com.red.circle.other.infra.database.rds.service.user.device.LatestMobileDeviceService;
import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.tool.core.thread.ThreadPoolManager;
import com.red.circle.other.domain.gateway.user.ability.RegisterDeviceGateway;
import com.red.circle.other.infra.database.rds.service.user.device.DeviceRegisterQuantityService;
import com.red.circle.other.infra.database.rds.service.user.device.IpRegisterQuantityService;
import com.red.circle.other.inner.model.cmd.user.IncrDeviceRegisterCmd;
import com.red.circle.other.inner.model.cmd.user.device.AllowDeviceRegisterCmd;
import com.red.circle.other.inner.enums.config.EnumConfigKey;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

/**
 * 注册设备 实现.
 *
 * @author pengliang on 2023/12/17
 */
@Component
@RequiredArgsConstructor
public class RegisterDeviceGatewayImpl implements RegisterDeviceGateway {

  private final IpRegisterQuantityService ipRegisterQuantityService;
  private final DeviceRegisterQuantityService deviceRegisterQuantityService;
  private final LatestMobileDeviceService latestMobileDeviceService;
  private final UserProfileGateway userProfileGateway;
  private final TeamMemberService teamMemberService;
  private final EnumConfigCacheService enumConfigCacheService;

  /**
   * 累计注册数量.
   */
  @Override
  public void incrRegisterQuantityAsync(IncrDeviceRegisterCmd cmd) {
    ThreadPoolManager.getInstance().execute(() -> {
      if (StringUtils.isNotBlank(cmd.getDeviceNo())) {
        deviceRegisterQuantityService.incrQuantity(cmd.getDeviceNo(), cmd.getSysOrigin());
      }

      if (StringUtils.isNotBlank(cmd.getIp())) {
        ipRegisterQuantityService.incrQuantity(cmd.getIp(), cmd.getSysOrigin());
      }
    });
  }

  /**
   * 是否允许用户设备注册.
   *
   * @return true 允许注册、false 不允许
   */
  @Override
  public boolean checkAllowDeviceRegister(AllowDeviceRegisterCmd cmd) {
    return !isLimitDevice(cmd) && !isLimitIp(cmd);
  }

  private boolean isLimitIp(AllowDeviceRegisterCmd cmd) {
    return cmd.checkIp() && checkIpQuantity(cmd);
  }

  private boolean isLimitDevice(AllowDeviceRegisterCmd cmd) {
    return cmd.checkDevice() && checkDeviceNoQuantity(cmd);
  }

  private boolean checkIpQuantity(AllowDeviceRegisterCmd cmd) {
    return ipRegisterQuantityService.getIpQuantity(cmd.getIp(), cmd.getSysOrigin())
        >= cmd.getIpLimit();
  }

  private boolean checkDeviceNoQuantity(AllowDeviceRegisterCmd cmd) {
    return deviceRegisterQuantityService.getDeviceNoQuantity(cmd.getDeviceNo(), cmd.getSysOrigin())
        >= cmd.getDeviceLimit();
  }

  @Override
  public String getDeviceFingerprintByUserId(Long userId) {
    return latestMobileDeviceService.getDeviceFingerprintByUserId(userId);
  }

  @Override
  public Boolean checkDeviceFingerprintHasAnchor(Long userId) {
    if (userId == null) {
      return false;
    }

    com.red.circle.other.domain.model.user.UserProfile userProfile = userProfileGateway.getByUserId(userId);
    if (userProfile == null) {
      return false;
    }

    String fingerprint = latestMobileDeviceService.getDeviceFingerprintByUserId(userId);
    if (StringUtils.isBlank(fingerprint)) {
      return false;
    }

    // 跳过白名单用户
    String whitelistConfig = enumConfigCacheService.getValue(
        EnumConfigKey.DEVICE_REGISTER_WHITELIST, userProfile.getOriginSys());
    if (StringUtils.isNotBlank(whitelistConfig) && whitelistConfig.contains(String.valueOf(userProfile.getAccount()))) {
      return false;
    }

    java.util.List<Long> userIds = latestMobileDeviceService.listUserIdsByDeviceFingerprint(
        fingerprint, userProfile.getOriginSys());

    if (userIds == null || userIds.isEmpty()) {
      return false;
    }

    for (Long otherUserId : userIds) {
      if (java.util.Objects.equals(otherUserId, userId)) {
        continue;
      }

      // 判断是否为主播：检查用户是否为团队成员
      TeamMember teamMember =
          teamMemberService.getByMemberId(otherUserId);
      if (teamMember != null) {
        return true;
      }
    }

    return false;
  }

}
