package com.ssyf.third.bmiss.services;

import com.ssyf.third.bmiss.model.ApiResponse;
import com.ssyf.third.bmiss.model.LiveRoom;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 直播服务类
 * 提供直播间列表获取、直播间信息查询等功能，并支持Redis缓存
 * 
 * @author system
 * @since 1.0
 */
@Slf4j
@Service
public class LiveService {

    private static final String LIVE_ROOM_LIST_CACHE_KEY = "live:room:list";
    private static final String LIVE_ROOM_DETAIL_CACHE_PREFIX = "live:room:detail:";
    private static final String LIVE_ROOM_NAME_CACHE_PREFIX = "live:room:name:";
    private static final long DEFAULT_CACHE_TTL = 5 * 60; // 5分钟
    
    @Autowired
    private BusinessService businessService;
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    /**
     * 获取所有开播的直播间列表
     * 优先从缓存获取，缓存不存在时调用BusinessService获取并缓存
     * 
     * @return 直播间列表
     */
    @SuppressWarnings("unchecked")
    public List<LiveRoom> getLiveRoomList() {
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        
        // 从缓存获取
        List<LiveRoom> cachedLiveRooms = (List<LiveRoom>) ops.get(LIVE_ROOM_LIST_CACHE_KEY);
        if (cachedLiveRooms != null) {
            return cachedLiveRooms;
        }
        
        // 缓存不存在，调用业务服务获取
        // 这里需要传入null作为roomId来获取所有开播的直播间
        ApiResponse<List<LiveRoom>> response = businessService.startBroadcastAnchor(null);
        
        // 提取直播间列表数据
        List<LiveRoom> liveRooms = extractLiveRooms(response);
        
        // 缓存结果（仅成功响应）
        if (liveRooms != null && !liveRooms.isEmpty()) {
            ops.set(LIVE_ROOM_LIST_CACHE_KEY, liveRooms, DEFAULT_CACHE_TTL, TimeUnit.SECONDS);
            
            // 同时缓存每个直播间的详细信息
            cacheLiveRoomDetails(liveRooms);
            
            log.info("直播间列表已缓存，TTL: {}秒", DEFAULT_CACHE_TTL);
        }

        return liveRooms;
    }
    
    /**
     * 从ApiResponse中提取直播间列表数据
     * 
     * @param response 直播间列表响应
     * @return 直播间列表
     */
    private List<LiveRoom> extractLiveRooms(ApiResponse<List<LiveRoom>> response) {
        if (response == null || response.getCode() != 200 || response.getData() == null) {
            return new ArrayList<>();
        }
        
        return response.getData();
    }

    public List<LiveRoom> getLiveByRoomIds(List<Integer> roomIds) {
        List<LiveRoom> roomList = getLiveRoomList();
        return roomList.stream().filter(room -> roomIds.contains(room.getUser_id())).collect(Collectors.toList());
    }
    
    /**
     * 获取指定直播间信息（通过直播间ID）
     * 
     * @param roomId 直播间ID
     * @return 直播间信息
     */
    public LiveRoom getLiveRoomById(Long roomId) {
        if (roomId == null) {
            return null;
        }
        
        String cacheKey = LIVE_ROOM_DETAIL_CACHE_PREFIX + roomId;
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        
        // 从缓存获取
        LiveRoom cachedRoom = (LiveRoom) ops.get(cacheKey);
        if (cachedRoom != null) {
            log.info("从缓存获取直播间信息，直播间ID: {}", roomId);
            return cachedRoom;
        }
        
        // 缓存不存在，从直播间列表中查找
        List<LiveRoom> roomList = getLiveRoomList();
        if (roomList == null || roomList.isEmpty()) {
            return null;
        }
        
        LiveRoom targetRoom = findLiveRoomById(roomList, roomId);
        
        // 缓存找到的直播间信息
        if (targetRoom != null) {
            ops.set(cacheKey, targetRoom, DEFAULT_CACHE_TTL, TimeUnit.SECONDS);
            log.info("直播间信息已缓存，直播间ID: {}, TTL: {}秒", roomId, DEFAULT_CACHE_TTL);
        }
        
        return targetRoom;
    }
    
    /**
     * 获取指定直播间信息（通过直播间名称）
     * 
     * @param roomName 直播间名称
     * @return 直播间信息
     */
    public LiveRoom getLiveRoomByName(String roomName) {
        if (roomName == null || roomName.trim().isEmpty()) {
            return null;
        }
        
        String cacheKey = LIVE_ROOM_NAME_CACHE_PREFIX + roomName.hashCode();
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        
        // 从缓存获取
        LiveRoom cachedRoom = (LiveRoom) ops.get(cacheKey);
        if (cachedRoom != null) {
            log.info("从缓存获取直播间信息，直播间名称: {}", roomName);
            return cachedRoom;
        }
        
        // 缓存不存在，从直播间列表中查找
        List<LiveRoom> roomList = getLiveRoomList();
        if (roomList == null || roomList.isEmpty()) {
            return null;
        }
        
        LiveRoom targetRoom = findLiveRoomByName(roomList, roomName);
        
        // 缓存找到的直播间信息
        if (targetRoom != null) {
            ops.set(cacheKey, targetRoom, DEFAULT_CACHE_TTL, TimeUnit.SECONDS);
            log.info("直播间信息已缓存，直播间名称: {}, TTL: {}秒", roomName, DEFAULT_CACHE_TTL);
        }
        
        return targetRoom;
    }
    
    /**
     * 获取指定直播间信息（通过直播ID）
     * 
     * @param liveId 直播ID
     * @return 直播间信息
     */
    public LiveRoom getLiveRoomByLiveId(Long liveId) {
        // 这里假设直播ID和直播间ID相同，或者需要根据业务逻辑调整
        return getLiveRoomById(liveId);
    }
    
    /**
     * 重置直播间缓存（全部）
     */
    public void resetCache() {
        clearLiveRoomCache();
        log.info("直播服务缓存已重置");
    }
    
    /**
     * 清空直播间缓存
     */
    public void clearLiveRoomCache() {
        // 清除直播间列表缓存
        redisTemplate.delete(LIVE_ROOM_LIST_CACHE_KEY);
        
        // 清除所有直播间详情缓存
        redisTemplate.delete(redisTemplate.keys(LIVE_ROOM_DETAIL_CACHE_PREFIX + "*"));
        
        // 清除所有直播间名称缓存
        redisTemplate.delete(redisTemplate.keys(LIVE_ROOM_NAME_CACHE_PREFIX + "*"));
        
        log.info("直播服务缓存已清空");
    }
    
    /**
     * 清除指定直播间信息缓存
     * 
     * @param roomId 直播间ID
     */
    public void clearLiveRoomCache(Long roomId) {
        if (roomId == null) {
            return;
        }
        
        // 清除直播间详情缓存
        redisTemplate.delete(LIVE_ROOM_DETAIL_CACHE_PREFIX + roomId);
        
        // 清除直播间列表缓存（因为包含该直播间信息）
        redisTemplate.delete(LIVE_ROOM_LIST_CACHE_KEY);
        
        log.info("直播间缓存已清除，直播间ID: {}", roomId);
    }
    
    /**
     * 缓存直播间详细信息
     * 
     * @param liveRooms 直播间列表
     */
    private void cacheLiveRoomDetails(List<LiveRoom> liveRooms) {
        if (liveRooms == null || liveRooms.isEmpty()) {
            return;
        }
        
        ValueOperations<String, Object> ops = redisTemplate.opsForValue();
        
        for (LiveRoom room : liveRooms) {
            if (room.getId() != null) {
                String detailKey = LIVE_ROOM_DETAIL_CACHE_PREFIX + room.getId();
                ops.set(detailKey, room, DEFAULT_CACHE_TTL, TimeUnit.SECONDS);
                
                // 如果直播间有名称，也缓存名称映射
                if (room.getTitle() != null) {
                    String nameKey = LIVE_ROOM_NAME_CACHE_PREFIX + room.getTitle().hashCode();
                    ops.set(nameKey, room, DEFAULT_CACHE_TTL, TimeUnit.SECONDS);
                }
            }
        }
    }
    
    /**
     * 在直播间列表中查找指定ID的直播间
     * 
     * @param liveRooms 直播间列表
     * @param roomId 直播间ID
     * @return 直播间信息
     */
    private LiveRoom findLiveRoomById(List<LiveRoom> liveRooms, Long roomId) {
        if (liveRooms == null || roomId == null) {
            return null;
        }
        
        for (LiveRoom room : liveRooms) {
            if (roomId.equals(room.getId())) {
                return room;
            }
        }
        
        return null;
    }
    
    /**
     * 在直播间列表中查找指定名称的直播间
     * 
     * @param liveRooms 直播间列表
     * @param roomName 直播间名称
     * @return 直播间信息
     */
    private LiveRoom findLiveRoomByName(List<LiveRoom> liveRooms, String roomName) {
        if (liveRooms == null || roomName == null) {
            return null;
        }
        
        for (LiveRoom room : liveRooms) {
            if (roomName.equals(room.getTitle())) {
                return room;
            }
        }
        
        return null;
    }
}