package com.red.circle.other.app.listener.task;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.common.base.Throwables;
import com.red.circle.common.business.core.enums.SysOriginPlatformEnum;
import com.red.circle.common.business.enums.SendPropsOrigin;
import com.red.circle.component.mq.MessageEventProcess;
import com.red.circle.component.mq.MessageEventProcessDescribe;
import com.red.circle.component.mq.config.RocketMqMessageListener;
import com.red.circle.component.mq.service.Action;
import com.red.circle.component.mq.service.ConsumerMessage;
import com.red.circle.component.mq.service.MessageListener;
import com.red.circle.component.redis.service.RedisService;
import com.red.circle.external.inner.endpoint.message.ImGroupClient;
import com.red.circle.mq.business.model.event.task.TaskApprovalEvent;
import com.red.circle.mq.rocket.business.streams.TaskSink;
import com.red.circle.other.app.dto.cmd.SpinsTaskProgressUpdateCmd;
import com.red.circle.other.app.service.SpinsUserTaskProgressService;
import com.red.circle.other.app.service.room.RoomProfileService;
import com.red.circle.other.app.service.task.TaskService;
import com.red.circle.other.app.util.DateTimeAsiaRiyadhUtils;
import com.red.circle.other.domain.gateway.user.UserProfileGateway;
import com.red.circle.other.domain.gateway.user.ability.InviteUserGateway;
import com.red.circle.other.domain.model.user.UserConsumptionLevel;
import com.red.circle.other.infra.database.rds.dao.h5.UserInviteTaskRecordDAO;
import com.red.circle.other.infra.database.rds.dao.user.user.UserInviteUserDAO;
import com.red.circle.other.infra.database.rds.entity.h5.UserInviteTaskRecord;
import com.red.circle.other.infra.database.rds.entity.user.user.LatestMobileDevice;
import com.red.circle.other.infra.database.rds.entity.user.user.UserInviteUser;
import com.red.circle.other.infra.database.rds.enums.h5.MemberActiveEnum;
import com.red.circle.other.infra.database.rds.service.family.FamilyMemberInfoService;
import com.red.circle.other.infra.database.rds.service.sys.EnumConfigService;
import com.red.circle.other.infra.database.rds.service.sys.GameListConfigService;
import com.red.circle.other.infra.database.rds.service.user.device.LatestMobileDeviceService;
import com.red.circle.other.infra.database.rds.service.user.user.CpRelationshipService;
import com.red.circle.other.infra.database.rds.service.user.user.RelationshipFriendService;
import com.red.circle.other.inner.endpoint.activity.PropsActivityClient;
import com.red.circle.other.inner.model.cmd.activity.SendActivityRewardCmd;
import com.red.circle.tool.core.collection.CollectionUtils;
import com.red.circle.tool.core.date.LocalDateUtils;
import com.red.circle.tool.core.date.TimestampUtils;
import com.red.circle.tool.core.sequence.IdWorkerUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@RocketMqMessageListener(groupId = TaskSink.INPUT, tag = TaskSink.TAG)
@RequiredArgsConstructor
public class TaskListener implements MessageListener {
    private final MessageEventProcess messageEventProcess;
    private final TaskService taskService;
    private final RedisService redisService;
    private final RelationshipFriendService relationshipFriendService;
    private final InviteUserGateway inviteUserGateway;
    private final SpinsUserTaskProgressService spinsUserTaskProgressService;

    @Override
    public Action consume(ConsumerMessage message) {
        return messageEventProcess.consume(
                MessageEventProcessDescribe.builder()
                        .logTag("任务审核")
                        .consumeMsgTimeoutMinute(1)
                        .repeatConsumeMinute(1)
                        .repeatConsumeTag("task_approval")
                        .checkConsumeTag(TaskSink.TAG)
                        .message(message)
                        .build(),
                TaskApprovalEvent.class,
                eventBody -> {
                    log.warn("任务审核 event {}", eventBody);
                    Integer taskId = eventBody.getTaskId();
                    switch (taskId) {
                        case 1:
                            // 处理任务-1 的逻辑 上麦10分钟
                            handleTask1(eventBody);
                            break;
                        case 2:
                            // 处理任务-2 的逻辑 在房间内赠送礼物
                            handleTask2(eventBody);
                            break;
                        case 3:
                            // 处理任务-3 的逻辑 在商店购买任意商品
                            handleTask3(eventBody);
                            break;
                        case 4:
                            // 处理任务-4 的逻辑 玩一局游戏
                            handleTask4(eventBody);
                            break;
                        case 5:
                            // 处理任务-5 的逻辑 创建我的房间
                            handleTask5(eventBody);
                            break;
                        case 6:
                            // 处理任务-6 的逻辑 添加10个好友
                            handleTask6(eventBody);
                            break;
                        case 7:
                            // 处理任务-7 的逻辑 加入3个房间
                            handleTask7(eventBody);
                            break;
                        case 8:
                            // 处理任务-8 的逻辑 发送10个幸运礼物
                            handleTask8(eventBody);
                            break;
                        case 9:
                            // 处理任务-9 的逻辑 关注一个用户
                            handleTask9(eventBody);
                            break;
                        case 10:
                            // 处理任务-10 的逻辑 关注一个房间
                            handleTask10(eventBody);
                            break;
                        case 11:
                            // 处理任务-11 的逻辑 填写其他人的邀请码
                            handleTask11(eventBody);
                          break;
                        default:
                            // 处理未知任务 ID 的情况
                            handleUnknownTask(taskId);
                    }
                }
        );
    }

  private void handleTask1(TaskApprovalEvent eventBody) {
        //    // 增加心跳次数 放一天
        String redisKey = "mic:heartbeat:" + eventBody.getUserId();
        String inc = redisService.getString(redisKey);
        if (StringUtils.isEmpty(inc)) {
            // 计算到凌晨的过期时间（秒）
            long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
            redisService.increment(redisKey, 1, expireSeconds, TimeUnit.SECONDS);
        } else {
            int result = Integer.parseInt(inc) + 1;
            eventBody.setTargetValue(10);
            eventBody.setCompleteValue(Math.min(result, 10));
            updateTaskStatus(eventBody);

            redisService.increment(redisKey, 1);
        }

        // 处理 Spins 上麦任务进度
        handleSpinsMicTask(eventBody.getUserId(), inc);
    }

    /**
     * 处理 Spins 上麦任务进度
     * @param userId 用户ID
     * @param micTimeStr 上麦时长（分钟）字符串
     */
    private void handleSpinsMicTask(Long userId, String micTimeStr) {
        if (StringUtils.isEmpty(micTimeStr)) {
            return;
        }
        
        try {
            int micTime = Integer.parseInt(micTimeStr);
            
            // 处理上麦15分钟任务
            spinsUserTaskProgressService.updateTaskProgress(
                new SpinsTaskProgressUpdateCmd()
                    .setUserId(userId)
                    .setTaskCode("SPINS_MIC_15_MIN")
                    .setProgressValue(micTime)
            );

            // 处理上麦30分钟任务
            spinsUserTaskProgressService.updateTaskProgress(
                new SpinsTaskProgressUpdateCmd()
                    .setUserId(userId)
                    .setTaskCode("SPINS_MIC_30_MIN")
                    .setProgressValue(micTime)
            );

            // 处理上麦1小时任务
            spinsUserTaskProgressService.updateTaskProgress(
                new SpinsTaskProgressUpdateCmd()
                    .setUserId(userId)
                    .setTaskCode("SPINS_MIC_1_HOUR")
                    .setProgressValue(micTime)
            );

            // 处理上麦2小时任务
            spinsUserTaskProgressService.updateTaskProgress(
                new SpinsTaskProgressUpdateCmd()
                    .setUserId(userId)
                    .setTaskCode("SPINS_MIC_2_HOUR")
                    .setProgressValue(micTime)
            );

            log.info("Spins上麦任务进度更新成功, userId={}, micTime={}", userId, micTime);
        } catch (Exception e) {
            log.error("处理Spins上麦任务进度失败, userId={}, micTimeStr={}", userId, micTimeStr, e);
        }
    }

    private void handleTask2(TaskApprovalEvent eventBody) {
        log.warn("处理任务-2 在房间内赠送礼物: {}", eventBody);
        eventBody.setTargetValue(1);
        eventBody.setCompleteValue(1);
        updateTaskStatus(eventBody);
    }

    private void handleTask6(TaskApprovalEvent eventBody) {
        log.warn("处理任务-6 添加10个好友: {}", eventBody);
        Long friendsCount = relationshipFriendService.selectMyFriendsCount(eventBody.getUserId());

        eventBody.setTargetValue(10);
        eventBody.setCompleteValue(Math.min(friendsCount.intValue(), 10));
        updateTaskStatus(eventBody);

    }


    private void handleTask4(TaskApprovalEvent eventBody) {
        // 具体的任务 4 处理逻辑
        log.warn("处理任务-4 玩一局游戏: {}", eventBody);
        eventBody.setTargetValue(1);
        eventBody.setCompleteValue(1);
        updateTaskStatus(eventBody);
    }

    private void handleUnknownTask(Integer taskId) {
        log.warn("未知任务Id {}", taskId);
    }

    // 日常任务 更新任务状态的方法示例
    private boolean updateTaskStatus(TaskApprovalEvent event) {
        if (taskService.checkTaskStatus(event.getUserId(), Long.valueOf(event.getTaskId()), event.getDay())) {
            // 如果有目标值和完成值，使用带进度的方法
            if (event.getTargetValue() != null && event.getCompleteValue() != null) {
                taskService.updateTaskStatus(
                    0, // status传 0，具体状态由方法内部根据 targetValue 和 completeValue 判断
                    event.getUserId(), 
                    Long.valueOf(event.getTaskId()), 
                    event.getDay(),
                    event.getTargetValue(),
                    event.getCompleteValue()
                );
            } else {
                // 没有进度值，直接设置为已完成
                taskService.updateTaskStatus(1, event.getUserId(), Long.valueOf(event.getTaskId()), event.getDay());
            }
            return true;
        }
        log.warn("任务已完成 {}", event);
        return false;
    }

    private void handleTask3(TaskApprovalEvent eventBody) {
        log.warn("处理任务-3: {}", eventBody);
        eventBody.setTargetValue(1);
        eventBody.setCompleteValue(1);
        updateTaskStatus(eventBody);
    }

    private void handleTask8(TaskApprovalEvent eventBody) {
        log.warn("处理任务-8 发送10个幸运礼物: {}", eventBody);
        // 增加幸运礼物发送次数（不设置过期时间）
        String redisKey = "task:lucky-gift:count:" + eventBody.getUserId();
        String countStr = redisService.getString(redisKey);

        int num = eventBody.getQuantity() == null ? 1 : eventBody.getQuantity();
        if (StringUtils.isEmpty(countStr)) {
            redisService.increment(redisKey, num);
        } else {
            int result = Integer.parseInt(countStr) + num;
            eventBody.setTargetValue(10);
            eventBody.setCompleteValue(Math.min(result, 10));
            boolean updated = updateTaskStatus(eventBody);
            if (updated) {
              redisService.increment(redisKey, 1);
            }
        }
    }

    private void handleTask9(TaskApprovalEvent eventBody) {
        log.warn("处理任务-9 关注一个用户: {}", eventBody);
        // 关注用户计数，每日过期
        String redisKey = "task:follow-user:" + eventBody.getUserId();
        String countStr = redisService.getString(redisKey);

        if (StringUtils.isBlank(countStr)) {
            // 计算到凌晨的过期时间（秒）
            long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
            redisService.increment(redisKey, 1, expireSeconds, TimeUnit.SECONDS);
            // 第一次关注就完成任务
            eventBody.setTargetValue(1);
            eventBody.setCompleteValue(1);
            boolean updated = updateTaskStatus(eventBody);
            if (updated) {
              redisService.increment(redisKey, 1);
            }
        }
    }

    private void handleTask10(TaskApprovalEvent eventBody) {
        log.warn("处理任务-10 关注一个房间: {}", eventBody);
        // 关注房间计数，每日过期
        String redisKey = "task:follow-room:" + eventBody.getUserId();
        String countStr = redisService.getString(redisKey);
        
        if (StringUtils.isEmpty(countStr)) {
            // 计算到凌晨的过期时间（秒）
            long expireSeconds = DateTimeAsiaRiyadhUtils.getSecondsUntilMidnight();
            redisService.increment(redisKey, 1, expireSeconds, TimeUnit.SECONDS);
            eventBody.setTargetValue(1);
            eventBody.setCompleteValue(1);
            // 第一次关注就完成任务
            updateTaskStatus(eventBody);
        } else {
            // 已经完成过了
            if (Integer.parseInt(countStr) >= 1) {
                updateTaskStatus(eventBody);
            } else {
                redisService.increment(redisKey, 1);
                updateTaskStatus(eventBody);
            }
        }
    }

    private void handleTask11(TaskApprovalEvent eventBody) {
      log.warn("处理任务-11: {}", eventBody);
      eventBody.setTargetValue(1);
      eventBody.setCompleteValue(1);
      updateTaskStatus(eventBody);
    }

    private void dealRechargeCommission(TaskApprovalEvent eventBody) {
        if (StringUtils.isNotBlank(eventBody.getSysOrigin()) && eventBody.getCurrencyDiff() > 0L) {
            try {
                inviteUserGateway.getRechargeCommission(BigDecimal.valueOf(eventBody.getCurrencyDiff()), eventBody.getSysOrigin(), eventBody.getUserId());
            } catch (Exception e) {
                log.error("被邀请人充值邀请人获得佣金累计错误: {}", Throwables.getStackTraceAsString(e));
            }
        }
    }

    private void handleTask7(TaskApprovalEvent eventBody) {
        log.warn("处理任务-10 加入3个房间: {}", eventBody);
        //    // 进入一次 +1
        String redisKey = "task:add-room::" + eventBody.getUserId();
        String inc = redisService.getString(redisKey);
        if (StringUtils.isEmpty(inc)) {
            redisService.increment(redisKey, 1);
        } else {
            int result = Integer.parseInt(inc) + 1;
            eventBody.setTargetValue(3);
            eventBody.setCompleteValue(Math.min(result, 3));
            boolean updated = updateTaskStatus(eventBody);
            if (updated) {
              redisService.increment(redisKey, 1);
            }
        }
    }

    private void handleTask5(TaskApprovalEvent eventBody) {
        log.warn("处理任务-5 创建我的房间: {}", eventBody);
        eventBody.setTargetValue(1);
        eventBody.setCompleteValue(1);
        updateTaskStatus(eventBody);

    }
}
