package com.red.circle.other.app.command.user.vip;

import com.red.circle.other.app.dto.cmd.user.vip.UserVipAbilitySettingCmd;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.infra.database.mongo.entity.user.profile.UserVipAbilitySetting;
import com.red.circle.other.infra.database.mongo.service.user.profile.UserVipAbilitySettingService;
import com.red.circle.other.domain.enums.VipAbilityType;
import com.red.circle.other.domain.enums.ContactMode;
import com.red.circle.other.inner.enums.material.SysNobleVipTypeEnum;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
@RequiredArgsConstructor
public class UserVipAbilityCmdExe {

    private final UserVipAbilitySettingService userVipAbilitySettingService;
    private final UserProfileGateway userProfileGateway;

    public void updateUserVipAbility(UserVipAbilitySettingCmd cmd) {
        Long userId = cmd.getReqUserId();

        // 获取用户 VIP 等级
        String vipLevel = userProfileGateway.getUserVipName(userId);

        // 非 VIP 用户不允许修改设置
        if (vipLevel == null) {
            return;
        }

        SysNobleVipTypeEnum vipEnum = SysNobleVipTypeEnum.getByName(vipLevel);

        // 取已有配置，前端未传的字段保持原值
        UserVipAbilitySetting existing = userVipAbilitySettingService.findByUserId(userId);

        // 功能开关：前端传了才更新，没传保持原值；同时结合 VIP 等级限制
        Boolean kickPrevention = resolveSwitch(cmd.getKickPrevention(),
                existing != null ? existing.getKickPrevention() : Boolean.FALSE,
                VipAbilityType.KICK_PREVENTION.hasAbility(vipLevel));
        Boolean mysteriousInvisibility = resolveSwitch(cmd.getMysteriousInvisibility(),
                existing != null ? existing.getMysteriousInvisibility() : Boolean.FALSE,
                VipAbilityType.MYSTERIOUS_INVISIBILITY.hasAbility(vipLevel));
        Boolean antiBlock = resolveSwitch(cmd.getAntiBlock(),
                existing != null ? existing.getAntiBlock() : Boolean.FALSE,
                VipAbilityType.ANTI_BLOCK.hasAbility(vipLevel));

        // ContactMode：前端未传保持原值
        ContactMode selectedMode;
        if (cmd.getContactMode() != null) {
            selectedMode = ContactMode.valueOf(cmd.getContactMode());
        } else if (existing != null && existing.getContactMode() != null) {
            selectedMode = ContactMode.valueOf(existing.getContactMode());
        } else {
            selectedMode = ContactMode.EVERYONE;
        }
        ContactMode finalMode = getContactMode(selectedMode, vipEnum);

        // 构建 MongoDB 对象
        UserVipAbilitySetting setting = new UserVipAbilitySetting();
        setting.setUserId(userId);
        setting.setContactMode(String.valueOf(finalMode));
        setting.setKickPrevention(kickPrevention);
        setting.setMysteriousInvisibility(mysteriousInvisibility);
        setting.setAntiBlock(antiBlock);
        // existing 有就继承，没有就用当前等级初始化，避免 QryExe 误判为新解锁
        setting.setLastVipLevel(existing != null ? existing.getLastVipLevel() : vipLevel);
        setting.setUpdateTime(new Date());

        // 执行 upsert
        userVipAbilitySettingService.upsert(setting);
    }

    /**
     * 前端传了值则取前端值（结合VIP等级限制），未传则保持原值.
     */
    private Boolean resolveSwitch(Boolean cmdValue, Boolean existingValue, boolean hasVipLevel) {
        if (cmdValue == null) {
            // 未传：保持原值，但如果VIP等级不够则强制关闭
            return hasVipLevel && Boolean.TRUE.equals(existingValue);
        }
        // 传了：结合VIP等级
        return hasVipLevel && Boolean.TRUE.equals(cmdValue);
    }

    @NotNull
    private static ContactMode getContactMode(ContactMode selectedMode, SysNobleVipTypeEnum vipEnum) {
        ContactMode finalMode;

        if (selectedMode == ContactMode.DO_NOT_DISTURB) {
            // 需要 VIP4(DUKE) 及以上
            if (vipEnum == null || vipEnum.ordinal() < SysNobleVipTypeEnum.DUKE.ordinal()) {
                finalMode = ContactMode.EVERYONE;
            } else {
                finalMode = ContactMode.DO_NOT_DISTURB;
            }
        } else if (selectedMode.getMinTargetVipLevel() != null) {
            // 高等级模式，检查 VIP 等级是否满足要求
            if (vipEnum == null || vipEnum.ordinal() < selectedMode.getMinTargetVipLevel().ordinal()) {
                finalMode = ContactMode.EVERYONE; // 等级不足回退
            } else {
                finalMode = selectedMode; // 等级足够
            }
        } else {
            // 普通模式或没有限制
            finalMode = selectedMode;
        }
        return finalMode;
    }
}