package cn.reghao.tnb.content.app.vod.rpc;

import cn.reghao.file.api.iface.OssService;
import cn.reghao.jutil.jdk.db.Page;
import cn.reghao.jutil.jdk.db.PageList;
import cn.reghao.jutil.jdk.serializer.JsonConverter;
import cn.reghao.oss.sdk.model.constant.ObjectScope;
import cn.reghao.oss.sdk.model.dto.media.VideoInfo;
import cn.reghao.oss.sdk.model.dto.media.VideoUrlDto;
import cn.reghao.tnb.content.api.constant.PostScope;
import cn.reghao.tnb.content.api.dto.*;
import cn.reghao.tnb.content.api.iface.AdminVideoService;
import cn.reghao.tnb.content.app.vod.db.mapper.VideoPostMapper;
import cn.reghao.tnb.content.app.vod.db.repository.VideoRepository;
import cn.reghao.tnb.content.app.vod.model.po.BannerVideo;
import cn.reghao.tnb.content.app.vod.model.po.VideoCategory;
import cn.reghao.tnb.content.app.vod.model.po.VideoFile;
import cn.reghao.tnb.content.app.vod.model.po.VideoPost;
import cn.reghao.tnb.content.app.vod.model.query.VideoQuery;
import cn.reghao.tnb.content.app.vod.service.CategoryService;
import cn.reghao.tnb.content.app.vod.service.VideoPostQuery;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2024-02-15 09:39:08
 */
@Slf4j
@DubboService
@Service
public class AdminVideoServiceImpl implements AdminVideoService {
    @DubboReference(check = false)
    private OssService ossService;

    private final RabbitTemplate rabbitTemplate;
    private final VideoPostMapper videoPostMapper;
    private final VideoPostQuery videoPostQuery;
    private final VideoRepository videoRepository;
    private final CategoryService categoryService;

    public AdminVideoServiceImpl(RabbitTemplate rabbitTemplate, VideoPostMapper videoPostMapper,
                                 VideoPostQuery videoPostQuery, VideoRepository videoRepository,
                                 CategoryService categoryService) {
        this.rabbitTemplate = rabbitTemplate;
        this.videoPostMapper = videoPostMapper;
        this.videoPostQuery = videoPostQuery;
        this.videoRepository = videoRepository;
        this.categoryService = categoryService;
    }

    public List<VideoRegion> getVideoRegions() {
        List<VideoCategory> list0 = categoryService.getAllCategory();
        List<VideoRegion> menuTrees = list0.stream().map(videoCategory -> {
            int pid = videoCategory.getPid();
            int id = videoCategory.getId();
            String name = videoCategory.getName();
            int sort = videoCategory.getSort();
            return new VideoRegion(pid, id, name, sort);
        }).collect(Collectors.toList());

        Map<Integer, VideoRegion> allMap = menuTrees.stream().collect(Collectors.toMap(VideoRegion::getId, k -> k));

        Set<Integer> set = new HashSet<>();
        menuTrees.forEach(menuTree -> {
            int pid = menuTree.getPid();
            VideoRegion menuTree1 = allMap.get(pid);
            if (menuTree1 != null) {
                List<VideoRegion> list = menuTree1.getChildren();
                if (list == null) {
                    list = new ArrayList<>();
                    menuTree1.setChildren(list);
                }

                menuTree1.getChildren().add(menuTree);
                menuTree1.getChildren().sort(Comparator.comparingInt(VideoRegion::getSort));
                //allMap.remove(menuTree.getId());
                set.add(menuTree.getId());
            }
        });

        set.forEach(allMap::remove);
        List<VideoRegion> results = new ArrayList<>(allMap.values());
        results.sort(Comparator.comparingInt(VideoRegion::getSort));
        return results;
    }

    public PageList<UserVideoPost> getVideoPosts(VideoSearch videoSearch) {
        int pageNumber = videoSearch.getPageNumber();
        int pageSize = videoSearch.getPageSize();
        Page page = new Page(pageNumber, pageSize);
        String content = videoSearch.getContent();

        VideoQuery videoQuery = new VideoQuery.Builder()
                .status(null)
                .scope(null)
                .title(content)
                .orderBy(videoSearch.getOrderBy())
                .orderDirection(videoSearch.getOrderDirection())
                .build();
        int total = videoPostMapper.countAdminVideo(videoQuery);
        List<UserVideoPost>list = videoPostMapper.findAdminVideoByPage(page, videoQuery).stream()
                .map(videoPostQuery::getUserVideoPost)
                .collect(Collectors.toList());
        return PageList.pageList(pageNumber, 20, total, list);
    }

    @Deprecated
    public void setHotVideo() {
        String routeKey = "tnb.data";
        List<BannerVideo> list = new ArrayList<>();
        rabbitTemplate.convertAndSend(routeKey, JsonConverter.objectToJson(list));
    }

    @Override
    public VideoUrls getVideoUrl(String videoId) {
        double currentTime = 0.0;
        VideoPost videoPost = videoPostMapper.findByVideoId(videoId);
        if (videoPost == null) {
            return new VideoUrls();
        }

        List<VideoUrlDto> list = videoRepository.findVideoUrls(videoId);
        if (list.isEmpty()) {
            return new VideoUrls();
        }

        String urlType = list.get(0).getType();
        int scope = videoPost.getScope();
        if (scope != PostScope.PUBLIC.getCode()) {
            try {
                List<VideoUrl> urls = list.stream().map(videoUrlDto -> {
                    try {
                        int channelId = videoUrlDto.getChannelCode();
                        String quality = videoUrlDto.getQuality();
                        String signedUrl = ossService.getSignedUrl(channelId, videoUrlDto.getObjectId());
                        return new VideoUrl(quality, signedUrl);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    return null;
                }).filter(Objects::nonNull).collect(Collectors.toList());
                return new VideoUrls(currentTime, urlType, urls);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return new VideoUrls();
        } else {
            List<VideoUrl> urls = list.stream().map(videoUrlDto -> {
                String quality = videoUrlDto.getQuality();
                String url = videoUrlDto.getUrl();
                return new VideoUrl(quality, url);
            }).collect(Collectors.toList());
            return new VideoUrls(currentTime, urlType, urls);
        }
    }

    @Override
    public Long getImageAlbum(String objectId) {
        return null;
    }

    @Override
    public void addConvertedVideo(VideoConvertedDto videoConvertedDto) {
        /*String uploadId = videoConvertedDto.getUploadId();
        int channelCode = videoConvertedDto.getChannelCode();
        try {
            VideoInfo videoInfo = ossService.getVideoInfo(channelCode, uploadId);
            if (videoInfo == null) {
                String errMsg = String.format("视频文件 %s 在 oss 中不存在", uploadId);
                log.info(errMsg);
                return;
            }

            String videoFileId = videoConvertedDto.getVideoFileId();
            VideoPost videoPost = videoRepository.getVideoPostByFileId(videoFileId);
            int scope = videoPost.getScope();
            if (scope != ObjectScope.PRIVATE.getCode()) {
                ossService.setObjectScope(channelCode, uploadId, scope);
            }

            String videoId = videoPost.getVideoId();
            VideoFile videoFile = new VideoFile(videoId, videoFileId, channelCode, videoInfo);
            videoRepository.updateVideoPublish(videoId, videoFile);
        } catch (Exception e) {
            e.printStackTrace();
        }*/
    }
}
