package com.red.circle.other.app.command.violation.room;

import com.alibaba.fastjson.JSON;
import com.red.circle.external.inner.endpoint.message.OfficialNoticeClient;
import com.red.circle.external.inner.model.cmd.message.notice.official.NoticeExtTemplateCustomizeCmd;
import com.red.circle.external.inner.model.enums.message.OfficialNoticeTypeEnum;
import com.red.circle.framework.core.asserts.ResponseAssert;
import com.red.circle.framework.core.response.CommonErrorCode;
import com.red.circle.other.app.dto.cmd.room.SwitchUseThemeCmd;
import com.red.circle.other.app.dto.cmd.violation.RoomViolationHandleCmd;
import com.red.circle.other.app.dto.clientobject.violation.ViolationHandleResultCO;
import com.red.circle.other.app.enums.violation.OperationTypeEnum;
import com.red.circle.other.app.enums.violation.TargetTypeEnum;
import com.red.circle.other.app.enums.violation.ViolationTypeEnum;
import com.red.circle.other.app.service.room.RoomThemeService;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.gateway.user.ability.UserRegionGateway;
import com.red.circle.other.domain.gateway.violation.ViolationRecordGateway;
import com.red.circle.other.domain.model.user.UserProfile;
import com.red.circle.other.domain.violation.ViolationRecord;
import com.red.circle.other.infra.database.cache.service.other.EnumConfigCacheService;
import com.red.circle.other.infra.database.mongo.entity.live.RoomProfile;
import com.red.circle.other.infra.database.mongo.service.live.RoomProfileManagerService;
import com.red.circle.other.infra.database.rds.entity.props.RoomThemeUserBackpack;
import com.red.circle.other.infra.database.rds.service.props.RoomThemeUserBackpackService;
import com.red.circle.other.infra.database.rds.service.sys.AdministratorAuthService;
import com.red.circle.other.infra.database.rds.service.sys.AdministratorService;
import com.red.circle.other.inner.asserts.RoomErrorCode;
import com.red.circle.other.inner.enums.config.EnumConfigKey;
import com.red.circle.other.inner.enums.material.PropsCommodityType;
import com.red.circle.other.inner.model.dto.user.props.UserPropsResourcesDTO;
import com.red.circle.other.inner.model.dto.user.props.UserUsePropsDTO;
import com.red.circle.tool.core.collection.CollectionUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 房间违规调整命令执行器
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class RoomViolationAdjustCmdExe {

    private final ViolationRecordGateway violationRecordGateway;
    private final RoomProfileManagerService roomProfileManagerService;
    private final AdministratorAuthService administratorAuthService;
    private final OfficialNoticeClient officialNoticeClient;
    private final UserRegionGateway userRegionGateway;
    private final UserProfileGateway userProfileGateway;
    private final EnumConfigCacheService enumConfigCacheService;
    private final AdministratorService administratorService;
    private final RoomThemeUserBackpackService roomThemeUserBackpackService;


    // 默认内容配置
    private static final String DEFAULT_ROOM_NOTICE = "Welcome to my room";
    private static final String DEFAULT_THEME = "default";

    public ViolationHandleResultCO execute(RoomViolationHandleCmd cmd) {
        ViolationTypeEnum violationTypeEnum = ViolationTypeEnum.getByCode(cmd.getViolationType());
        ResponseAssert.notNull(CommonErrorCode.DATA_ERROR, violationTypeEnum);

        // 1. 验证管理员权限
        ResponseAssert.isTrue(CommonErrorCode.INSUFFICIENT_PERMISSION, administratorService.existsAdmin(cmd.getReqUserId()) &&
                administratorAuthService.existsAuth(cmd.requiredReqUserId(), violationTypeEnum.name()));

        // 2. 查询房间信息
        RoomProfile roomProfile = roomProfileManagerService.getProfileById(Long.valueOf(cmd.getRoomId()));
        ResponseAssert.notNull(RoomErrorCode.ROOM_NOT_EXISTS, roomProfile);

        // 3. 获取原始内容
        String originalContent = getOriginalContent(roomProfile, violationTypeEnum);

        // 4. 调整违规内容
        String adjustedContent = adjustViolationContent(roomProfile, violationTypeEnum);

        UserProfile userProfile = userProfileGateway.getByUserId(cmd.getReqUserId());

        // 5. 保存违规记录
        ViolationRecord record = ViolationRecord.builder()
                .targetType(TargetTypeEnum.ROOM.getCode())
                .targetId(cmd.getRoomId())
                .violationType(cmd.getViolationType())
                .operationType(OperationTypeEnum.ADJUST.getCode())
                .description(cmd.getDescription())
                .screenshotUrls(JSON.toJSONString(cmd.getScreenshotUrls()))
                .originalContent(originalContent)
                .adjustedContent(adjustedContent)
                .operatorId(userProfile.getId())
                .operatorName(userProfile.getUserNickname())
                .build();

        Long recordId = violationRecordGateway.save(record);

        // 6. 发送调整通知
        sendAdjustNotification(roomProfile.getUserId(), violationTypeEnum, adjustedContent);

        return ViolationHandleResultCO.builder()
                .recordId(recordId)
                .success(true)
                .message("调整成功")
                .originalContent(originalContent)
                .adjustedContent(adjustedContent)
                .build();
    }

    /**
     * 获取原始内容
     */
    private String getOriginalContent(RoomProfile roomProfile, ViolationTypeEnum violationType) {
        return switch (violationType) {
            case ROOM_NICKNAME -> roomProfile.getRoomName();
            case ROOM_COVER -> roomProfile.getRoomCover();
            case ROOM_NOTICE -> roomProfile.getRoomDesc();
            case ROOM_THEME -> "";
            default -> null;
        };
    }

    /**
     * 调整违规内容
     */
    private String adjustViolationContent(RoomProfile roomProfile, ViolationTypeEnum violationType) {
        String adjustedContent;
        
        switch (violationType) {
            case ROOM_NICKNAME -> {
                adjustedContent = roomProfile.getRoomAccount() + "&" + roomProfile.getId();
                RoomProfile updateProfile = new RoomProfile();
                updateProfile.setId(roomProfile.getId());
                updateProfile.setRoomName(adjustedContent);
                roomProfileManagerService.updateSelectiveProfile(updateProfile);
            }
            case ROOM_COVER -> {
                adjustedContent = enumConfigCacheService.getValue(EnumConfigKey.DEFAULT_ROOM_COVER, roomProfile.getSysOrigin());
                roomProfileManagerService.updateRoomCoverByUserId(roomProfile.getUserId(), adjustedContent);
            }
            case ROOM_NOTICE -> {
                adjustedContent = DEFAULT_ROOM_NOTICE;
                roomProfileManagerService.updateRoomDescByIds(java.util.Collections.singletonList(roomProfile.getId()), adjustedContent);
            }
            case ROOM_THEME -> {
                UserProfile userProfile = userProfileGateway.getByUserId(roomProfile.getUserId());

                List<UserUsePropsDTO> usePropsEntities = userProfile.filterProps(
                        useProps -> Objects.equals(useProps.getPropsResources().getType(),
                                PropsCommodityType.THEME.name()));

                if (CollectionUtils.isEmpty(usePropsEntities)) {
                    return "null";
                }

                UserUsePropsDTO useProps = usePropsEntities.get(0);
                UserPropsResourcesDTO resources = useProps.getPropsResources();
                adjustedContent = String.valueOf(resources.getId());

                RoomThemeUserBackpack themeUserBackpack = roomThemeUserBackpackService.getById(resources.getId());
                if (themeUserBackpack == null) {
                    return "null";
                }

                roomThemeUserBackpackService.cleanUseTheme(userProfile.getId());
                userProfileGateway.removeCacheAll(userProfile.getId());

                /*SwitchUseThemeCmd themeCmd = new SwitchUseThemeCmd();
                themeCmd.setThemeId(themeUserBackpack.getThemeId());
                themeCmd.setReqUserId(roomProfile.getUserId());
                roomThemeService.switchUseTheme(themeCmd);*/
            }
            default -> adjustedContent = null;
        }
        
        return adjustedContent;
    }

    /**
     * 发送调整通知
     */
    private void sendAdjustNotification(Long userId, ViolationTypeEnum violationType, String adjustedContent) {
        String content = getAdjustNotificationContent(userId, violationType, adjustedContent);
        
        Map<String, Object> titleMap = new HashMap<>();
        titleMap.put("type", "violation_adjust");
        titleMap.put("violationType", violationType.getCode());
        
        officialNoticeClient.send(
                NoticeExtTemplateCustomizeCmd.builder()
                        .toAccount(userId)
                        .noticeType(OfficialNoticeTypeEnum.VIOLATION_ADJUST)
                        .content(content)
                        .title(com.alibaba.fastjson.JSON.toJSONString(titleMap))
                        .build());
    }

    /**
     * 获取调整通知内容
     */
    private String getAdjustNotificationContent(Long userId, ViolationTypeEnum violationType, String adjustedContent) {
        boolean isArabic = isArabicRegion(userId);
        
        return switch (violationType) {
            case ROOM_NICKNAME -> isArabic ?
                String.format("تم تغيير اسم الغرفة إلى '%s' بسبب انتهاك القواعد.", adjustedContent) :
                String.format("Your room name has been changed to '%s' due to violation of rules.", adjustedContent);
            case ROOM_COVER -> isArabic ?
                "تم تغيير صورة ملف الغرفة إلى الصورة الافتراضية بسبب انتهاك القواعد." :
                "Your room profile picture has been changed to the default image due to violation of rules.";
            case ROOM_NOTICE -> isArabic ?
                String.format("تم تغيير إشعار الغرفة إلى '%s' بسبب انتهاك اللوائح.", adjustedContent) :
                String.format("Your room notice has been changed to '%s' due to violation of regulations.", adjustedContent);
            case ROOM_THEME -> isArabic ?
                "تم تغيير سمة الغرفة إلى السمة الافتراضية بسبب انتهاك القواعد." :
                "Your room theme has been changed to the default theme due to violation of rules.";
            default -> isArabic ?
                "تم تعديل معلومات الغرفة بسبب انتهاك القواعد." :
                "Your room information has been adjusted due to violation of rules.";
        };
    }

    private boolean isArabicRegion(Long userId) {
        String regionCode = userRegionGateway.getRegionConfigByUserId(userId).getRegionCode();
        try {
            return "ar".equalsIgnoreCase(regionCode);
        } catch (Exception e) {
            log.warn("Failed to get user region, userId={}", userId, e);
            return false;
        }
    }
}
