
package com.tmerclub.cloud.live.controller.app;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.tmerclub.cloud.api.feign.SearchSpuFeignClient;
import com.tmerclub.cloud.api.multishop.bo.EsShopDetailBO;
import com.tmerclub.cloud.api.multishop.feign.ShopDetailFeignClient;
import com.tmerclub.cloud.api.platform.config.FeignShopConfig;
import com.tmerclub.cloud.api.vo.EsPageVO;
import com.tmerclub.cloud.common.bean.AliLive;
import com.tmerclub.cloud.common.constant.Constant;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.leaf.manager.SegmentManager;
import com.tmerclub.cloud.common.product.constant.SpuStatus;
import com.tmerclub.cloud.common.product.dto.ProductSearchDTO;
import com.tmerclub.cloud.common.product.vo.search.ProductSearchVO;
import com.tmerclub.cloud.common.product.vo.search.SpuSearchVO;
import com.tmerclub.cloud.common.response.ServerResponseEntity;
import com.tmerclub.cloud.constant.DistributedIdKey;
import com.tmerclub.cloud.live.constant.LiveRoomStatusType;
import com.tmerclub.cloud.live.constant.PlayBackType;
import com.tmerclub.cloud.live.dto.LiveRoomDTO;
import com.tmerclub.cloud.live.service.LiveRoomProdService;
import com.tmerclub.cloud.live.service.LiveRoomService;
import com.tmerclub.cloud.live.util.AliLiveUtil;
import com.tmerclub.cloud.live.vo.LiveRoomProdVO;
import com.tmerclub.cloud.live.vo.LiveRoomVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 直播间
 * @author TRACK
 */
@RestController("appLiveRoomController")
@RequestMapping("/ua/live_room")
@Tag(name = "用户直播间")
public class LiveRoomController {

    @Autowired
    private LiveRoomService liveRoomService;
    @Autowired
    private LiveRoomProdService liveRoomProdService;
    @Autowired
    private FeignShopConfig feignShopConfig;
    @Autowired
    private SegmentManager segmentManager;
    @DubboReference
    private ShopDetailFeignClient shopDetailFeignClient;
    @DubboReference
    private SearchSpuFeignClient searchSpuFeignClient;
    private static final int NON_SORT = 25;

    @GetMapping("/page")
    @Operation(summary = "获取直播间列表", description = "分页获取直播间列表")
    public ServerResponseEntity<PageVO<LiveRoomVO>> page(@Valid PageDTO pageDTO, LiveRoomDTO liveRoom) {
        // 如果type为空，则为搜索直播信息
        if (Objects.isNull(liveRoom.getSearchType()) && StrUtil.isBlank(liveRoom.getName())) {
            liveRoom.setSearchType(1);
            liveRoom.setName("");
        }
        PageVO<LiveRoomVO> liveRoomPage = liveRoomService.pageRoomAndDetail(pageDTO, liveRoom);
        return ServerResponseEntity.success(liveRoomPage);
    }

    @GetMapping("/get_live_room_info")
    @Operation(summary = "获取直播间信息", description = "根据roomId获取直播间")
    @Parameters({
            @Parameter(name = "roomId", description = "直播间id"),
            @Parameter(name = "userType", description = "用户类型 0.游客 1.用户")
    })
    public ServerResponseEntity<LiveRoomVO> getByRoomId(@RequestParam(value = "roomId") Long roomId,
                                                        @RequestParam(value = "userType") Integer userType) {
        LiveRoomVO livingRoomInfo = liveRoomService.getLivingRoomInfo(null, roomId);
        if (Objects.isNull(livingRoomInfo)) {
            throw new LuckException("直播间不存在，请刷新后重试");
        }
        ServerResponseEntity<EsShopDetailBO> shopResponse = shopDetailFeignClient.getShopByShopId(livingRoomInfo.getShopId());
        if (!shopResponse.isSuccess()) {
            throw new LuckException(shopResponse.getMsg());
        }
        EsShopDetailBO shopDetailBO = shopResponse.getData();
        livingRoomInfo.setShopName(shopDetailBO.getShopName());
        livingRoomInfo.setShopLogo(shopDetailBO.getShopLogo());
        if (Objects.equals(userType, 0)) {
            livingRoomInfo.setUuid(segmentManager.getSegmentId(DistributedIdKey.tmerclub_LIVE_ROOM_USER));
        }
        return ServerResponseEntity.success(livingRoomInfo);
    }

    @GetMapping("/page_living_room_prod")
    @Operation(summary = "获取直播间商品列表", description = "分页获取直播间商品列表")
    public ServerResponseEntity<PageVO<LiveRoomProdVO>> pageLivingRoomProd(@Valid PageDTO pageDTO, Long roomId) {
        PageVO<LiveRoomProdVO> spuPageVO = new PageVO<>();
        List<LiveRoomProdVO> liveRoomProdList = liveRoomProdService.listLiveRoomProd(roomId);
        if (CollUtil.isEmpty(liveRoomProdList)) {
            spuPageVO.setList(new ArrayList<>(0));
            spuPageVO.setTotal(0L);
            spuPageVO.setPages(0);
            return ServerResponseEntity.success(spuPageVO);
        }

        List<Long> spuIds = liveRoomProdList.stream().map(LiveRoomProdVO::getSpuId).toList();
        ProductSearchDTO productSearchDTO = new ProductSearchDTO();
        productSearchDTO.setPageNum(pageDTO.getPageNum());
        productSearchDTO.setPageSize(pageDTO.getPageSize());
        productSearchDTO.setSpuIds(spuIds);
        productSearchDTO.setSpuStatus(SpuStatus.PUT_SHELF.value());
        productSearchDTO.setSort(NON_SORT);
        ServerResponseEntity<EsPageVO<ProductSearchVO>> spuResponse = searchSpuFeignClient.search(productSearchDTO);
        if (!spuResponse.isSuccess()) {
            throw new LuckException(spuResponse.getMsg());
        }
        EsPageVO<ProductSearchVO> spuData = spuResponse.getData();
        List<ProductSearchVO> productSearchList = spuData.getList();
        if (CollUtil.isEmpty(productSearchList) || CollUtil.isEmpty(productSearchList.get(0).getSpus())) {
            spuPageVO.setList(new ArrayList<>(0));
            spuPageVO.setTotal(0L);
            spuPageVO.setPages(0);
            return ServerResponseEntity.success(spuPageVO);
        }

        List<SpuSearchVO> spuList = productSearchList.get(0).getSpus();
        Map<Long, SpuSearchVO> spuMap = spuList.stream().collect(Collectors.toMap(SpuSearchVO::getSpuId, spu -> spu));
        Map<Long, LiveRoomProdVO> liveRoomProdMap = liveRoomProdList.stream().collect(Collectors.toMap(LiveRoomProdVO::getSpuId, spu -> spu));
        List<LiveRoomProdVO> resList = new ArrayList<>(Constant.INITIAL_CAPACITY);
        for (Long spuId : spuMap.keySet()) {
            SpuSearchVO spuSearchVO = spuMap.get(spuId);
            if (Objects.isNull(spuSearchVO)) {
                continue;
            }
            LiveRoomProdVO liveRoomProdVO = liveRoomProdMap.get(spuId);
            if (Objects.isNull(liveRoomProdVO)) {
                continue;
            }
            liveRoomProdVO.setSpuSearchVO(spuSearchVO);
            resList.add(liveRoomProdVO);
        }
        spuPageVO.setList(resList);
        spuPageVO.setTotal(spuData.getTotal());
        spuPageVO.setPages(spuData.getPages());
        return ServerResponseEntity.success(spuPageVO);
    }

    @GetMapping("/get_spu_live_room_info")
    @Operation(summary = "根据商品id获取当前直播间", description = "根据商品id获取当前直播间")
    public ServerResponseEntity<LiveRoomProdVO> getSpuLiveRoomInfo(@RequestParam(value = "spuId") Long spuId) {
        LiveRoomProdVO liveRoomProdVO = liveRoomProdService.getLivingRoomBySpuId(spuId);
        return ServerResponseEntity.success(liveRoomProdVO);
    }

    @GetMapping("/get_pull_url")
    @Operation(summary = "获取播流地址", description = "获取播流地址")
    @Parameters({
            @Parameter(name = "roomId", description = "直播间id"),
            @Parameter(name = "playBackType", description = "播放类型 1.rtmp 2.flv 3.m3u8")
    })
    public ServerResponseEntity<String> getPullUrl(@RequestParam Long roomId, @RequestParam Integer playBackType) {
        AliLive aliLive = feignShopConfig.getAliLive();
        if (Objects.isNull(aliLive) || StrUtil.isBlank(aliLive.getAppName())) {
            throw new LuckException("无法获取到直播配置");
        }
        LiveRoomVO livingRoom = liveRoomService.getLivingRoomInfo(null, roomId);
        if (Objects.isNull(livingRoom)) {
            throw new LuckException("直播间不存在，请刷新后重试");
        }
        if (Objects.equals(livingRoom.getLiveStatus(), LiveRoomStatusType.FINISHED.value())) {
            throw new LuckException("直播间不存在，请刷新后重试");
        }
        if (Objects.isNull(PlayBackType.instance(playBackType))) {
            throw new LuckException("播放类型错误");
        }
        // 不超过256字符 支持数字、大小写字母、短划线(-)、下划线(_)、等号(=)
        // {appName}-{roomId}-{shopId}-{userId}
        String streamName = StrUtil.format("{}-{}-{}-{}", aliLive.getAppName(), livingRoom.getRoomId(), livingRoom.getShopId(), livingRoom.getUserId());
        String pullUrl = AliLiveUtil.getPullUrl(streamName, playBackType, livingRoom.getEndTime(), aliLive);
        return ServerResponseEntity.success(pullUrl);
    }
}
