package com.ssyf.task.service;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ssyf.module.robot.domain.entity.*;
import com.ssyf.module.robot.domain.query.RobotManualControlQuery;
import com.ssyf.module.robot.service.*;
import com.ssyf.task.models.RobotTaskContext;
import com.ssyf.task.websocket.LiveRoomWsManager;
import com.ssyf.task.websocket.WsMessageStorageService;
import com.ssyf.task.websocket.RRobotWsMessage;
import com.ssyf.third.bmiss.model.*;
import com.ssyf.third.bmiss.services.BusinessService;
import com.ssyf.third.bmiss.services.GiftService;
import com.ssyf.third.bmiss.services.LiveService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 机器人手动控制服务
 * 为运营提供手动接管机器人的功能，支持单独操作机器人进行各种互动
 */
@Slf4j
@Service
public class RobotManualControlService {
    @Lazy
    @Autowired private RConfigRelationService configRelationService;
    @Lazy
    @Autowired private RRunningConfigService runningConfigService;

    @Lazy
    @Autowired private BusinessService businessService;
    @Lazy
    @Autowired private LiveService liveService;
    @Lazy
    @Autowired private GiftService giftService;
    @Lazy
    @Autowired private RobotSessionManager sessionManager;
    @Lazy
    @Autowired private LiveRoomActionService actionService;
    @Lazy
    @Autowired private GiftDecisionManager giftDecisionManager;

    @Autowired
    @Lazy
    private RRobotFeeService rRobotFeeService;
    @Lazy
    @Autowired private RRobotAccountService robotAccountService;
    @Lazy
    @Autowired private RRobotFeeService robotFeeService;
    @Lazy
    @Autowired private RGiftConfigService giftConfigService;
    @Lazy
    @Autowired private RRobotRunningInfoService runningInfoService;
    @Autowired
    @Lazy
    private LiveRoomStrategyService liveRoomStrategyService;
    @Lazy
    @Autowired
    private RobotResourceManager resourceManager;
    @Lazy
    @Autowired private RobotRecordService recordService;
    @Autowired
    private LiveRoomWsManager wsManager;

    @Lazy
    @Autowired
    private LiveRoomActionService liveRoomActionService;

    @Lazy
    @Autowired
    private WsMessageStorageService wsMessageStorageService;

    @Lazy
    @Autowired
    private AsrSpeechManagerService asrSpeechManagerService;

    @Autowired private RedissonClient redissonClient;
    @Autowired private StringRedisTemplate redisTemplate;

    // Redis Key 常量
    private static final String KEY_MANUAL_CONTROL = "robot:manual:control:";
    private static final String KEY_CURRENT_ROOM = "robot:current:room:";
    private static final String KEY_SESSION = "robot:session:";
    private static final long DEFAULT_CONTROL_DURATION_MINUTES = 30;

    /**
     * 接管机器人控制权
     * @param robotUuid 机器人UUID
     * @param durationMinutes 控制时长（分钟），默认30分钟
     * @return 是否接管成功
     */
    public boolean takeOverControl(String robotUuid, Integer durationMinutes) {
        if (StrUtil.isBlank(robotUuid)) {
            return false;
        }

        String lockKey = "lock:manual:control:" + robotUuid;
        RLock lock = redissonClient.getLock(lockKey);

        try {
            if (!lock.tryLock(5, 30, TimeUnit.SECONDS)) {
                log.warn("获取机器人控制锁失败: {}", robotUuid);
                return false;
            }

            // 检查是否已被其他运营接管
            String controlKey = KEY_MANUAL_CONTROL + robotUuid;
            if (redisTemplate.hasKey(controlKey)) {
                log.warn("机器人已被其他运营接管: {}", robotUuid);
                return true;
            }

            // 设置控制权，默认30分钟
            long duration = (durationMinutes != null && durationMinutes > 0) ?
                durationMinutes : DEFAULT_CONTROL_DURATION_MINUTES;

            redisTemplate.opsForValue().set(controlKey, "manual", duration, TimeUnit.MINUTES);
            log.info("机器人接管成功: {}, 控制时长: {}分钟", robotUuid, duration);
            return true;

        } catch (Exception e) {
            log.error("接管机器人控制异常: {}", robotUuid, e);
            return false;
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 释放机器人控制权
     * @param robotUuid 机器人UUID
     * @return 是否释放成功
     */
    public boolean releaseControl(String robotUuid) {
        if (StrUtil.isBlank(robotUuid)) {
            return false;
        }

        String controlKey = KEY_MANUAL_CONTROL + robotUuid;
        Boolean deleted = redisTemplate.delete(controlKey);

        if (Boolean.TRUE.equals(deleted)) {
            log.info("机器人控制权释放成功: {}", robotUuid);
            return true;
        } else {
            log.warn("机器人控制权释放失败或未接管: {}", robotUuid);
            return false;
        }
    }

    /**
     * 刷新控制时长
     * @param robotUuid 机器人UUID
     * @return 是否刷新成功
     */
    public boolean refreshControlDuration(String robotUuid) {
        if (StrUtil.isBlank(robotUuid)) {
            return false;
        }

        String controlKey = KEY_MANUAL_CONTROL + robotUuid;
        Long remainingTime = redisTemplate.getExpire(controlKey, TimeUnit.MINUTES);

        if (remainingTime == null || remainingTime <= 0) {
            log.warn("机器人未被接管或已过期: {}", robotUuid);
            return false;
        }

        // 如果剩余时间小于默认时长，则刷新到默认时长
        if (remainingTime < DEFAULT_CONTROL_DURATION_MINUTES) {
            redisTemplate.expire(controlKey, DEFAULT_CONTROL_DURATION_MINUTES, TimeUnit.MINUTES);
            log.debug("刷新机器人控制时长: {}, 新时长: {}分钟", robotUuid, DEFAULT_CONTROL_DURATION_MINUTES);
        } else {
            log.debug("机器人控制时长充足，无需刷新: {}, 剩余: {}分钟", robotUuid, remainingTime);
        }

        return true;
    }

    /**
     * 检查是否具有控制权
     * @param robotUuid 机器人UUID
     * @return 是否具有控制权
     */
    private boolean checkControlPermission(String robotUuid) {
        if (StrUtil.isBlank(robotUuid)) {
            return false;
        }

        String controlKey = KEY_MANUAL_CONTROL + robotUuid;
        return Boolean.TRUE.equals(redisTemplate.hasKey(controlKey));
    }

    /**
     * 检查机器人是否被手动控制
     * @param robotUuid 机器人UUID
     * @return 是否被手动控制
     */
    public boolean isManuallyControlled(String robotUuid) {
        if (StrUtil.isBlank(robotUuid)) {
            return false;
        }

        String controlKey = KEY_MANUAL_CONTROL + robotUuid;
        return Boolean.TRUE.equals(redisTemplate.hasKey(controlKey));
    }

    /**
     * 机器人登录
     * @param robotUuid 机器人UUID
     * @return 登录结果
     */
    public ApiResponse<LoginResponse> loginRobot(String robotUuid) {
        if (!checkControlPermission(robotUuid)) {
            return ApiResponse.error("无控制权限或控制已过期");
        }

        try {
            RRobotAccount account = robotAccountService.getOneByUid(robotUuid);
            if (account == null) {
                return ApiResponse.error("机器人账户不存在");
            }

            // 检查是否已登录
            String sessionKey = KEY_SESSION + robotUuid;
            String sessionJson = redisTemplate.opsForValue().get(sessionKey);
            if (StrUtil.isNotBlank(sessionJson)) {
                // 已登录，直接返回现有会话
                LoginResponse existingSession = JSONUtil.toBean(sessionJson, LoginResponse.class);
                refreshControlDuration(robotUuid);
                return ApiResponse.success(existingSession);
            }

            // 未登录，调用business登录
            ApiResponse<LoginResponse> resp = businessService.loginByEmail(account.getEmail(), account.getPassword());
            if (resp != null && resp.isSuccess() && resp.getData() != null) {
                LoginResponse loginData = resp.getData();
                // 设置session缓存
                redisTemplate.opsForValue().set(sessionKey, JSONUtil.toJsonStr(loginData), 1, TimeUnit.HOURS);
                refreshControlDuration(robotUuid);
                
                // 记录日志
                recordService.recordRobotRunRecord(null, account, null, null, 
                    loginData.getUser_info(), "手动登录", "登录成功", "OK", 4);
                
                return ApiResponse.success(loginData);
            } else {
                log.warn("机器人登录失败: {}", account.getEmail());
                return ApiResponse.error("机器人登录失败");
            }

        } catch (Exception e) {
            log.error("机器人登录异常: {}", robotUuid, e);
            return ApiResponse.error("登录异常: " + e.getMessage());
        }
    }

    /**
     * 机器人登出
     * @param robotUuid 机器人UUID
     * @return 登出结果
     */
    public ApiResponse<Object> logoutRobot(String robotUuid) {
        if (!checkControlPermission(robotUuid)) {
            return ApiResponse.error("无控制权限或控制已过期");
        }

        try {
            RRobotAccount account = robotAccountService.getOneByUid(robotUuid);
            if (account == null) {
                return ApiResponse.error("机器人账户不存在");
            }

            // 获取当前会话
            String sessionKey = KEY_SESSION + robotUuid;
            String sessionJson = redisTemplate.opsForValue().get(sessionKey);
            
            if (StrUtil.isBlank(sessionJson)) {
                // 未登录，直接返回成功
                refreshControlDuration(robotUuid);
                return ApiResponse.success("登出成功（机器人未登录）");
            }

            LoginResponse session = JSONUtil.toBean(sessionJson, LoginResponse.class);

            // 执行登出
            ApiResponse resp = businessService.logout(
                Integer.parseInt(session.getUser_info().getUser_id()),
                session.getToken()
            );

            if (resp.isSuccess()) {
                // 清理session缓存
                redisTemplate.delete(sessionKey);
                actionService.clearRobotCacheOnLogout(account);
                refreshControlDuration(robotUuid);

                // 记录日志
                recordService.recordRobotRunRecord(null, account, null, null,
                    session.getUser_info(), "手动登出", "登出成功", "OK", 4);
            }

            return resp;

        } catch (Exception e) {
            log.error("机器人登出异常: {}", robotUuid, e);
            return ApiResponse.error("登出异常: " + e.getMessage());
        }
    }

    /**
     * 获取直播间在线列表
     * @param forceRefresh 是否强制刷新
     * @return 直播间列表
     */
    public ApiResponse<List<LiveRoom>> getLiveRoomList(Boolean forceRefresh) {
        try {
            List<LiveRoom> liveRooms;
            
            if (Boolean.TRUE.equals(forceRefresh)) {
                // 强制刷新，先清理缓存再获取
                liveService.clearLiveRoomCache();
                liveRooms = liveService.getLiveRoomList();
            } else {
                // 正常调用
                liveRooms = liveService.getLiveRoomList();
            }
            
            return ApiResponse.success(liveRooms);
        } catch (Exception e) {
            log.error("获取直播间列表异常", e);
            return ApiResponse.error("获取直播间列表失败: " + e.getMessage());
        }
    }

    /**
     * 进入直播间
     * @param robotUuid 机器人UUID
     * @param roomId 直播间ID
     * @return 进入结果
     */
    public ApiResponse<String> enterLiveRoom(String robotUuid, Integer roomId) {
        if (!checkControlPermission(robotUuid)) {
            return ApiResponse.error("无控制权限或控制已过期");
        }

        if (roomId == null || roomId <= 0) {
            return ApiResponse.error("直播间ID无效");
        }

        try {
            RRobotAccount account = robotAccountService.getOneByUid(robotUuid);
            if (account == null) {
                return ApiResponse.error("机器人账户不存在");
            }
            // 获取当前会话
            String sessionKey = KEY_SESSION + robotUuid;
            String sessionJson = redisTemplate.opsForValue().get(sessionKey);

            if (StrUtil.isBlank(sessionJson)) {
                // 未登录，直接返回成功
                refreshControlDuration(robotUuid);
                return ApiResponse.success("登出成功（机器人未登录）");
            }

            LoginResponse session = JSONUtil.toBean(sessionJson, LoginResponse.class);

            // 检查是否已进入目标直播间
            String currentRoomKey = KEY_CURRENT_ROOM + robotUuid;
            String currentRoomIdStr = redisTemplate.opsForValue().get(currentRoomKey);
            
            if (StrUtil.isNotBlank(currentRoomIdStr)) {
                int currentRoomId = Integer.parseInt(currentRoomIdStr);
                
                // 如果已经在目标直播间，直接返回成功
                if (currentRoomId == roomId) {
                    log.info("机器人已在目标直播间，无需重复进入: Robot={}, Room={}", robotUuid, roomId);
                    refreshControlDuration(robotUuid);
                    return ApiResponse.success("机器人已在目标直播间");
                }
                
                // 如果在其他直播间，提示用户
                log.warn("机器人已在其他直播间: Robot={}, CurrentRoom={}, TargetRoom={}", 
                        robotUuid, currentRoomId, roomId);
                return ApiResponse.error("机器人当前在直播间" + currentRoomId + "，请先退出当前直播间");
            }

            // 获取直播间信息
            List<LiveRoom> liveRooms = liveService.getLiveRoomList();
            LiveRoom targetRoom = liveRooms.stream()
                .filter(room -> room.getUser_id().equals(roomId))
                .findFirst()
                .orElse(null);

            if (targetRoom == null) {
                return ApiResponse.error("直播间不存在或已下线");
            }

            UserInfo userInfo = session.getUser_info();
            String token = session.getToken();

            // 执行进入直播间流程
            wsManager.ensureConnection(targetRoom, token, (clientId) -> {
                try {
                    // 调用业务接口进入直播间
                    ApiResponse joinResponse = businessService.joinLiveRoom(roomId, 
                            Integer.parseInt(userInfo.getUser_id()), clientId, token);
                    
                    if (!joinResponse.isSuccess()) {
                        log.warn("API拒绝进入直播间: {}, Msg: {}", roomId, joinResponse.getMessage());
                        // 记录进入失败日志
                        recordService.recordRobotRunRecord(targetRoom, account, null, null, userInfo,
                                "进入直播间", "进入直播间失败", joinResponse.getMessage(), 2);
                        return ;
                    }

                    // 二次确认状态
                    ApiResponse stateResponse = businessService.getLiveRoomCurrentState(roomId, clientId, token);
                    if (!stateResponse.isSuccess()) {
                        log.warn("获取直播间状态失败: {}, Msg: {}", roomId, stateResponse.getMessage());
                        recordService.recordRobotRunRecord(targetRoom, account, null, null, userInfo,
                                "进入直播间", "获取状态失败", stateResponse.getMessage(), 2);
                        return;
                    }

                    // 进入成功，缓存当前房间信息
                    redisTemplate.opsForValue().set(currentRoomKey, String.valueOf(roomId), 
                            DEFAULT_CONTROL_DURATION_MINUTES, TimeUnit.MINUTES);
                    
                    // 记录成功日志
                    recordService.recordRobotRunRecord(targetRoom, account, null, null, userInfo,
                            "进入直播间", "进入成功", "OK", 4);
                    
                    // 开启ASR语音解析
                    try {
                        boolean asrStarted = asrSpeechManagerService.startAsr(roomId, userInfo, targetRoom);
                        if (asrStarted) {
                            log.debug("ASR语音解析开启成功，直播间ID: {}, 用户ID: {}", roomId, userInfo.getUser_id());
                        } else {
                            log.warn("ASR语音解析开启失败，直播间ID: {}, 用户ID: {}", roomId, userInfo.getUser_id());
                        }
                    } catch (Exception e) {
                        log.error("开启ASR语音解析异常，直播间ID: {}, 用户ID: {}", roomId, userInfo.getUser_id(), e);
                        // ASR解析失败不影响正常进入直播间流程
                    }
                    

                } catch (Exception e) {
                    log.error("进入直播间流程异常: Account={}, Room={}", account.getEmail(), roomId, e);
                    // 记录异常日志到数据库
                    recordService.recordRobotRunRecord(targetRoom, account, null, null, userInfo,
                            "进入直播间", "进入直播间异常", e.getMessage(), 2);
                }
            });
            return ApiResponse.success("进入直播间成功");

        } catch (Exception e) {
            log.error("进入直播间异常: {}, RoomID={}", robotUuid, roomId, e);
            return ApiResponse.error("进入直播间异常: " + e.getMessage());
        }
    }

    /**
     * 退出直播间
     * @param robotUuid 机器人UUID
     * @return 退出结果
     */
    public ApiResponse<Object> quitLiveRoom(String robotUuid) {
        if (!checkControlPermission(robotUuid)) {
            return ApiResponse.success("无控制权限或控制已过期");
        }

        try {
            RRobotAccount account = robotAccountService.getOneByUid(robotUuid);
            if (account == null) {
                return ApiResponse.success("机器人账户不存在");
            }

            // 检查是否在直播间
            String currentRoomKey = KEY_CURRENT_ROOM + robotUuid;
            String currentRoomId = redisTemplate.opsForValue().get(currentRoomKey);
            if (StrUtil.isBlank(currentRoomId)) {
                return ApiResponse.success("机器人未在直播间");
            }

            // 获取会话
            LoginResponse session = sessionManager.getOrRefreshSession(account);
            if (session == null) {
                return ApiResponse.success("机器人未登录");
            }

            // 获取直播间信息
            LiveRoom currentRoom = new LiveRoom();
            currentRoom.setUser_id(Integer.parseInt(currentRoomId));

            // 执行退出直播间
            boolean quitSuccess = actionService.quitLiveRoom(currentRoom, account, null, null,
                session.getUser_info(), session.getToken());

            if (quitSuccess) {
                // 清理当前房间缓存
                redisTemplate.delete(currentRoomKey);
                refreshControlDuration(robotUuid);

                // 记录日志
                recordService.recordRobotRunRecord(currentRoom, account, null, null,
                    session.getUser_info(), "手动退出直播间", "退出成功", "OK", 4);

                // 结束ASR语音解析
                try {
                    boolean asrEnded = asrSpeechManagerService.endAsr(Integer.parseInt(currentRoomId), session.getUser_info(), currentRoom);
                    if (asrEnded) {
                        log.debug("ASR语音解析结束成功，直播间ID: {}, 用户ID: {}", currentRoomId, session.getUser_info().getUser_id());
                    } else {
                        log.warn("ASR语音解析结束失败，直播间ID: {}, 用户ID: {}", currentRoomId, session.getUser_info().getUser_id());
                    }
                } catch (Exception e) {
                    log.error("结束ASR语音解析异常，直播间ID: {}, 用户ID: {}", currentRoomId, session.getUser_info().getUser_id(), e);
                    // ASR解析失败不影响正常退出直播间流程
                }

                return ApiResponse.success("退出直播间成功");
            } else {
                return ApiResponse.error("退出直播间失败");
            }

        } catch (Exception e) {
            log.error("退出直播间异常: {}", robotUuid, e);
            return ApiResponse.error("退出直播间异常: " + e.getMessage());
        }
    }

    /**
     * 点赞
     * @param robotUuid 机器人UUID
     * @return 点赞结果
     */
    public ApiResponse<Object> likeLiveRoom(String robotUuid) {
        if (!checkControlPermission(robotUuid)) {
            return ApiResponse.error("无控制权限或控制已过期");
        }

        try {
            RRobotAccount account = robotAccountService.getOneByUid(robotUuid);
            if (account == null) {
                return ApiResponse.error("机器人账户不存在");
            }

            // 检查是否在直播间
            String currentRoomKey = KEY_CURRENT_ROOM + robotUuid;
            String currentRoomId = redisTemplate.opsForValue().get(currentRoomKey);
            if (StrUtil.isBlank(currentRoomId)) {
                return ApiResponse.error("机器人未在直播间");
            }

            // 获取会话
            LoginResponse session = sessionManager.getOrRefreshSession(account);
            if (session == null) {
                return ApiResponse.error("机器人未登录");
            }

            // 执行点赞
            ApiResponse resp = businessService.giveLike(
                Integer.parseInt(currentRoomId),
                Integer.parseInt(session.getUser_info().getUser_id()),
                session.getToken()
            );

            if (resp.isSuccess()) {
                refreshControlDuration(robotUuid);

                // 记录日志
                recordService.recordRobotRunRecord(null, account, null, null,
                    session.getUser_info(), "手动点赞", "点赞成功", "OK", 4);
            }

            return resp;

        } catch (Exception e) {
            log.error("点赞异常: {}", robotUuid, e);
            return ApiResponse.error("点赞异常: " + e.getMessage());
        }
    }

    /**
     * 关注主播
     * @param robotUuid 机器人UUID
     * @return 关注结果
     */
    public ApiResponse<Object> followAnchor(String robotUuid) {
        if (!checkControlPermission(robotUuid)) {
            return ApiResponse.error("无控制权限或控制已过期");
        }

        try {
            RRobotAccount account = robotAccountService.getOneByUid(robotUuid);
            if (account == null) {
                return ApiResponse.error("机器人账户不存在");
            }

            // 检查是否在直播间
            String currentRoomKey = KEY_CURRENT_ROOM + robotUuid;
            String currentRoomId = redisTemplate.opsForValue().get(currentRoomKey);
            if (StrUtil.isBlank(currentRoomId)) {
                return ApiResponse.error("机器人未在直播间");
            }

            // 获取会话
            LoginResponse session = sessionManager.getOrRefreshSession(account);
            if (session == null) {
                return ApiResponse.error("机器人未登录");
            }

            // 执行关注
            ApiResponse resp = businessService.followUser(
                Integer.parseInt(currentRoomId),
                session.getToken(),
                1, // source_type
                0  // im_msg_type
            );

            if (resp.isSuccess()) {
                refreshControlDuration(robotUuid);

                // 记录日志
                recordService.recordRobotRunRecord(null, account, null, null,
                    session.getUser_info(), "手动关注", "关注成功", "OK", 4);
            }

            return resp;

        } catch (Exception e) {
            log.error("关注异常: {}", robotUuid, e);
            return ApiResponse.error("关注异常: " + e.getMessage());
        }
    }

    /**
     * 获取礼物列表
     * @param robotUuid 机器人UUID
     * @return 礼物列表
     */
    public ApiResponse<List<GiftDetail>> getGiftList(String robotUuid) {
        if (!checkControlPermission(robotUuid)) {
            return ApiResponse.error("无控制权限或控制已过期");
        }

        try {
            // 检查是否在直播间
            String currentRoomKey = KEY_CURRENT_ROOM + robotUuid;
            String currentRoomId = redisTemplate.opsForValue().get(currentRoomKey);
            if (StrUtil.isBlank(currentRoomId)) {
                return ApiResponse.error("机器人未在直播间");
            }

            // 获取礼物列表
            List<GiftDetail> giftList = giftService.getGiftList(new GiftDetail());
            refreshControlDuration(robotUuid);

            return ApiResponse.success(giftList);

        } catch (Exception e) {
            log.error("获取礼物列表异常: {}", robotUuid, e);
            return ApiResponse.error("获取礼物列表失败: " + e.getMessage());
        }
    }

    /**
     * 送礼
     * @param robotUuid 机器人UUID
     * @param giftId 礼物ID
     * @return 送礼结果
     */
    public ApiResponse<Object> sendGift(String robotUuid, Integer giftId) {
        if (!checkControlPermission(robotUuid)) {
            return ApiResponse.error("无控制权限或控制已过期");
        }

        if (giftId == null || giftId <= 0) {
            return ApiResponse.error("礼物ID无效");
        }

        try {
            RRobotAccount account = robotAccountService.getOneByUid(robotUuid);
            if (account == null) {
                return ApiResponse.error("机器人账户不存在");
            }

            // 检查是否在直播间
            String currentRoomKey = KEY_CURRENT_ROOM + robotUuid;
            String currentRoomId = redisTemplate.opsForValue().get(currentRoomKey);
            if (StrUtil.isBlank(currentRoomId)) {
                return ApiResponse.error("机器人未在直播间");
            }

            // 获取会话
            String sessionKey = KEY_SESSION + robotUuid;
            String sessionJson = redisTemplate.opsForValue().get(sessionKey);
            if (StrUtil.isBlank(sessionJson)) {
                return ApiResponse.error("机器人未登录");
            }
            LoginResponse session = JSONUtil.toBean(sessionJson, LoginResponse.class);

            // 获取礼物列表并验证礼物有效性
            List<GiftDetail> giftList = giftService.getGiftList(new GiftDetail());
            GiftDetail selectedGift = giftList.stream()
                .filter(gift -> gift.getGift_id().equals(giftId))
                .findFirst()
                .orElse(null);

            if (selectedGift == null) {
                return ApiResponse.error("礼物不存在或不可用");
            }

            // 余额检查（移除频次判断，只判断余额）
            RRobotFee robotFee = robotFeeService.getOneAvailable(account);
            if (robotFee == null) {
                return ApiResponse.error("机器人费用记录不存在");
            }

            double giftPrice = selectedGift.getGift_price() != null ? selectedGift.getGift_price().doubleValue() : 0.0;
            
            // 计算实际可用额度
            double totalLimit = robotFee.getTotalAmount() != null ? robotFee.getTotalAmount() : 0.0;
            double usedAmount = robotFee.getUsedAmount() != null ? robotFee.getUsedAmount() : 0.0;
            double applyAmount = robotFee.getApplyAmount() != null ? robotFee.getApplyAmount() : 0.0;
            double remainingHardLimit = totalLimit - usedAmount + applyAmount;

            if (remainingHardLimit <= 0) {
                return ApiResponse.error("机器人费用余额不足");
            }

            // 检查是否买得起礼物
            if (giftPrice > remainingHardLimit) {
                return ApiResponse.error("礼物价格超过可用余额");
            }

            // 申请余额（若不足）
            double needApply = 0.0;
            if (applyAmount < giftPrice) {
                needApply = giftPrice - applyAmount;
                ApiResponse applyResp = businessService.applyForBalance(
                    Integer.parseInt(session.getUser_info().getUser_id()), 
                    "ROBOT_GIFT_MANUAL", needApply, session.getToken());
                
                if (!applyResp.isSuccess()) {
                    log.warn("申请费用失败: Account={}, Amount={}, Msg={}", account.getEmail(), needApply, applyResp.getMessage());
                    recordService.recordRobotRunRecord(null, account, null, null, 
                        session.getUser_info(), "申请费用", "申请费用失败", applyResp.getMessage(), 2);
                    return ApiResponse.error("申请费用失败: " + applyResp.getMessage());
                }
                
                recordService.recordRobotRunRecord(null, account, null, null, 
                    session.getUser_info(), "申请费用", "申请费用成功", String.valueOf(needApply), 4);
            }

            // 执行送礼 - 使用礼物服务的简化方法
            List<Map<String, Object>> giftIdArr = new ArrayList<>();
            Map<String, Object> giftItem = new HashMap<>();
            giftItem.put("gift_id", giftId);
            giftItem.put("skin_id", 0);
            giftItem.put("num", 1);
            giftIdArr.add(giftItem);

            List<Map<String, Object>> recipientArr = new ArrayList<>();
            Map<String, Object> recipient = new HashMap<>();
            recipient.put("user_id", Integer.parseInt(currentRoomId));
            recipientArr.add(recipient);

            ApiResponse<Object> resp = giftService.sendGift(Integer.parseInt(currentRoomId), giftIdArr, 0,
                new HashMap<>(), 0, recipientArr, 0, session.getToken());

            if (resp.isSuccess()) {
                refreshControlDuration(robotUuid);

                // 更新消费记录
                double netApplyChange = needApply - giftPrice;
                rRobotFeeService.updateFeeAfterGift(robotFee.getUuid(),robotUuid, netApplyChange, giftPrice);

                // 记录消费记录
                recordService.recordRobotConsumption(null, account, null, null, 
                    session.getUser_info(), selectedGift, 1);
                
                // 记录日志
                recordService.recordRobotRunRecord(null, account, null, null,
                    session.getUser_info(), "手动送礼", "送礼成功", "礼物ID: " + giftId, 4);
            } else {
                // 送礼失败，回滚申请的余额
                if (needApply > 0) {
                    rRobotFeeService.updateFeeAfterGift(robotFee.getUuid(),robotUuid, needApply, 0.0);
                }
                
                // 记录失败日志
                recordService.recordRobotRunRecord(null, account, null, null,
                    session.getUser_info(), "手动送礼", "送礼失败", resp.getMessage(), 2);
            }

            return resp;

        } catch (Exception e) {
            log.error("送礼异常: {}, GiftID={}", robotUuid, giftId, e);
            return ApiResponse.error("送礼异常: " + e.getMessage());
        }
    }

    /**
     * 发送聊天消息
     * @param robotUuid 机器人UUID
     * @param message 消息内容
     * @return 发送结果
     */
    public ApiResponse<Object> sendChatMessage(String robotUuid, String message) {
        if (!checkControlPermission(robotUuid)) {
            return ApiResponse.error("无控制权限或控制已过期");
        }

        if (StrUtil.isBlank(message)) {
            return ApiResponse.error("消息内容不能为空");
        }

        try {
            RRobotAccount account = robotAccountService.getOneByUid(robotUuid);
            if (account == null) {
                return ApiResponse.error("机器人账户不存在");
            }

            // 检查是否在直播间
            String currentRoomKey = KEY_CURRENT_ROOM + robotUuid;
            String currentRoomId = redisTemplate.opsForValue().get(currentRoomKey);
            if (StrUtil.isBlank(currentRoomId)) {
                return ApiResponse.error("机器人未在直播间");
            }

            // 获取会话
            LoginResponse session = sessionManager.getOrRefreshSession(account);
            if (session == null) {
                return ApiResponse.error("机器人未登录");
            }

            // 执行发送聊天消息
            ApiResponse resp = businessService.liveRoomChat(
                Integer.parseInt(currentRoomId),
                session.getToken(),
                message
            );

            if (resp.isSuccess()) {
                refreshControlDuration(robotUuid);

                // 记录日志
                recordService.recordRobotRunRecord(null, account, null, null,
                    session.getUser_info(), "手动聊天", "发送消息成功", "消息: " + message, 4);
            }

            return resp;

        } catch (Exception e) {
            log.error("发送聊天消息异常: {}", robotUuid, e);
            return ApiResponse.error("发送聊天消息异常: " + e.getMessage());
        }
    }

    /**
     * 获取直播间消息列表
     * @param robotUuid 机器人UUID
     * @param query 查询参数
     * @return 消息列表
     */
    public ApiResponse<List<RRobotWsMessage>> getLiveRoomMessages(String robotUuid, RobotManualControlQuery query) {
        if (!checkControlPermission(robotUuid)) {
            return ApiResponse.error("无控制权限或控制已过期");
        }

        try {
            // 检查是否在直播间
            String currentRoomKey = KEY_CURRENT_ROOM + robotUuid;
            String currentRoomId = redisTemplate.opsForValue().get(currentRoomKey);
            if (StrUtil.isBlank(currentRoomId)) {
                return ApiResponse.error("机器人未在直播间");
            }

            Integer roomId = Integer.parseInt(currentRoomId);
            List<RRobotWsMessage> messages;

            // 根据查询参数选择不同的获取方式
            if (query.getSinceTimestamp() != null && query.getSinceTimestamp() > 0) {
                // 增量同步：获取指定时间戳之后的消息
                int limit = query.getLimit() != null ? query.getLimit() : 100;
                messages = wsMessageStorageService.getMessagesSince(roomId, query.getSinceTimestamp(), limit);
            } else if (query.getTimeRange() != null && query.getTimeRange() > 0) {
                // 时间范围查询：获取指定时间范围内的消息
                messages = wsMessageStorageService.getMessagesByTimeRange(roomId, query.getEndTime(), query.getTimeRange());
            } else if (query.getSkip() != null || query.getLimit() != null) {
                // 分页查询
                int skip = query.getSkip() != null ? query.getSkip() : 0;
                messages = wsMessageStorageService.getMessagesByPage(roomId, skip, query.getLimit());
            } else {
                // 默认获取最近50条消息
                messages = wsMessageStorageService.getRecentMessages(roomId, 50);
            }

            refreshControlDuration(robotUuid);

            // 记录日志
            RRobotAccount account = robotAccountService.getOneByUid(robotUuid);
            if (account != null) {
                LoginResponse session = sessionManager.getOrRefreshSession(account);
                if (session != null) {
                    recordService.recordRobotRunRecord(null, account, null, null,
                        session.getUser_info(), "手动获取消息", "获取消息成功", 
                        "消息数量: " + messages.size(), 4);
                }
            }

            return ApiResponse.success(messages);

        } catch (Exception e) {
            log.error("获取直播间消息异常: {}", robotUuid, e);
            return ApiResponse.error("获取直播间消息异常: " + e.getMessage());
        }
    }

    /**
     * 获取直播间消息总数
     * @param robotUuid 机器人UUID
     * @return 消息总数
     */
    public ApiResponse<Long> getLiveRoomMessageCount(String robotUuid) {
        if (!checkControlPermission(robotUuid)) {
            return ApiResponse.error("无控制权限或控制已过期");
        }

        try {
            // 检查是否在直播间
            String currentRoomKey = KEY_CURRENT_ROOM + robotUuid;
            String currentRoomId = redisTemplate.opsForValue().get(currentRoomKey);
            if (StrUtil.isBlank(currentRoomId)) {
                return ApiResponse.error("机器人未在直播间");
            }

            Integer roomId = Integer.parseInt(currentRoomId);
            long messageCount = wsMessageStorageService.getTotalMessageCount(roomId);

            refreshControlDuration(robotUuid);

            return ApiResponse.success(messageCount);

        } catch (Exception e) {
            log.error("获取直播间消息总数异常: {}", robotUuid, e);
            return ApiResponse.error("获取直播间消息总数异常: " + e.getMessage());
        }
    }
}