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

import cn.reghao.file.api.iface.OssService;
import cn.reghao.jutil.jdk.web.db.Page;
import cn.reghao.jutil.jdk.web.db.PageList;
import cn.reghao.jutil.jdk.web.result.Result;
import cn.reghao.tnb.common.web.WebResult;
import cn.reghao.jutil.jdk.string.SnowFlake;
import cn.reghao.tnb.auth.api.iface.AccountQuery;
import cn.reghao.tnb.common.auth.UserContext;
import cn.reghao.tnb.common.db.SelectOption;
import cn.reghao.tnb.content.api.constant.AlbumAction;
import cn.reghao.tnb.content.api.constant.PostScope;
import cn.reghao.tnb.content.api.constant.PostType;
import cn.reghao.tnb.content.api.dto.VideoCard;
import cn.reghao.tnb.content.app.vod.db.repository.AlbumRepository;
import cn.reghao.tnb.content.app.vod.db.repository.VideoRepository;
import cn.reghao.tnb.content.app.vod.model.dto.*;
import cn.reghao.tnb.content.app.vod.model.po.PostAlbum;
import cn.reghao.tnb.content.app.vod.model.po.PostItem;
import cn.reghao.tnb.content.app.vod.model.po.VideoPost;
import cn.reghao.tnb.content.app.vod.model.query.AlbumQuery;
import cn.reghao.tnb.content.app.vod.model.vo.AlbumInfo;
import cn.reghao.tnb.content.app.vod.model.vo.AlbumItem;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * @author reghao
 * @date 2024-10-31 14:03:30
 */
@Service
public class AlbumService {
    @DubboReference(check = false)
    private OssService ossService;
    @DubboReference(check = false, retries = 0, timeout = 60_000)
    private AccountQuery accountQuery;

    private final int pageSize = 12;
    private final SnowFlake idGenerator;
    private final AlbumRepository albumRepository;
    private final VideoRepository videoRepository;
    private final VideoPostQuery videoPostQuery;
    private final ContentPermission contentPermission;

    public AlbumService(AlbumRepository albumRepository, VideoRepository videoRepository,
                        VideoPostQuery videoPostQuery, ContentPermission contentPermission) {
        this.idGenerator = new SnowFlake(1L, 1L);
        this.albumRepository = albumRepository;
        this.videoPostQuery = videoPostQuery;
        this.videoRepository = videoRepository;
        this.contentPermission = contentPermission;
    }

    public void createAlbum(AlbumCreateDto albumCreateDto) {
        long albumId = idGenerator.nextId();
        PostAlbum postAlbum = new PostAlbum(albumId, albumCreateDto);
        albumRepository.savePostAlbum(postAlbum);
    }

    public Result doAlbumAction(AlbumActionDto albumActionDto) {
        long loginUser = UserContext.getUserId();
        int action = albumActionDto.getAction();
        long albumId = albumActionDto.getAlbumId();
        String postId = albumActionDto.getPostId();
        if (action == AlbumAction.Add.getCode()) {
            PostItem postItem = new PostItem(albumId, postId);
            albumRepository.savePostItem(postItem);
        } else if (action == AlbumAction.Remove.getCode()) {
            albumRepository.deletePostItem(albumId, postId);
        } else if (action == AlbumAction.SetCover.getCode()) {
            AlbumQuery albumQuery = new AlbumQuery.Builder().createBy(loginUser).albumId(albumId).build();
            Page page = new Page(1, 1);
            List<PostAlbum> list = albumRepository.getPostAlbums(page, albumQuery);
            if (!list.isEmpty()) {
                PostAlbum postAlbum = list.get(0);
                int postType = postAlbum.getPostType();
                String coverUrl;
                if (postType == PostType.Video.getCode()) {
                    VideoPost videoPost = videoRepository.getVideoPost(postId);
                    coverUrl = videoPost.getCoverUrl();
                    albumRepository.updateAlbumCover(albumId, coverUrl);
                }
            }
        } else {
            return Result.fail("ActionType not matched");
        }
        return Result.success();
    }

    public PageList<AlbumInfo> getUserAlbums(String userIdStr, int pn) {
        long userId = accountQuery.getUserIdLong(userIdStr);
        List<Integer> scopes = contentPermission.getUserScopes();
        long loginUser = UserContext.getUserId();
        if (loginUser == userId) {
            scopes.add(PostScope.PRIVATE.getCode());
        }

        AlbumQuery albumQuery = new AlbumQuery.Builder()
                .createBy(userId)
                .scope(scopes)
                .build();

        int total = albumRepository.countPostAlbum(albumQuery);
        Page page = new Page(pn, pageSize);
        List<PostAlbum> list = albumRepository.getPostAlbums(page, albumQuery);
        List<AlbumInfo> list1 = list.stream().map(postAlbum -> {
            int scope = postAlbum.getScope();
            String coverUrl = postAlbum.getCoverUrl();
            if (scope != PostScope.PUBLIC.getCode() && coverUrl != null) {
                PostItem postItem = albumRepository.getByUrl(coverUrl);
                if (postItem != null) {
                    int channelCode = postItem.getChannelCode();
                    String objectId = postItem.getObjectId();
                    try {
                        String signedUrl = ossService.getSignedUrl(objectId, null);
                        postAlbum.setCoverUrl(signedUrl);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return new AlbumInfo(postAlbum);
        }).collect(Collectors.toList());
        return PageList.pageList(pn, pageSize, total, list1);
    }

    public PageList<AlbumInfo> getUserAlbums(long userId, int pn) {
        List<Integer> scopes = contentPermission.getUserScopes();
        long loginUser = UserContext.getUserId();
        if (loginUser == userId) {
            scopes.add(PostScope.PRIVATE.getCode());
        }

        AlbumQuery albumQuery = new AlbumQuery.Builder()
                .createBy(userId)
                .scope(scopes)
                .build();

        int total = albumRepository.countPostAlbum(albumQuery);
        Page page = new Page(pn, pageSize);
        List<PostAlbum> list = albumRepository.getPostAlbums(page, albumQuery);
        List<AlbumInfo> list1 = list.stream().map(postAlbum -> {
            int scope = postAlbum.getScope();
            String coverUrl = postAlbum.getCoverUrl();
            if (scope != PostScope.PUBLIC.getCode() && coverUrl != null) {
                PostItem postItem = albumRepository.getByUrl(coverUrl);
                if (postItem != null) {
                    int channelCode = postItem.getChannelCode();
                    String objectId = postItem.getObjectId();
                    try {
                        String signedUrl = ossService.getSignedUrl(objectId, null);
                        postAlbum.setCoverUrl(signedUrl);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return new AlbumInfo(postAlbum);
        }).collect(Collectors.toList());
        return PageList.pageList(pn, pageSize, total, list1);
    }

    public String getAlbumContent(Long albumId, Integer pn) {
        long loginUser = UserContext.getUserId();
        AlbumQuery albumQuery;
        if (albumId == null) {
            albumQuery = new AlbumQuery.Builder().createBy(loginUser).build();
        } else {
            albumQuery = new AlbumQuery.Builder()
                    .createBy(loginUser)
                    .albumId(albumId)
                    .build();
        }
        Page page = new Page(1, pageSize);
        List<PostAlbum> list = albumRepository.getPostAlbums(page, albumQuery);
        if (list.isEmpty()) {
            return WebResult.notFound();
        }

        PostAlbum postAlbum = list.get(0);
        albumId = postAlbum.getAlbumId();
        long owner = postAlbum.getCreateBy();
        int scope = postAlbum.getScope();
        if (scope == PostScope.PRIVATE.getCode() && owner != loginUser) {
            return WebResult.notFound();
        }

        boolean hasPermission = contentPermission.hasPermission(owner, scope, loginUser);
        if (!hasPermission) {
            return WebResult.failWithMsg("permission denied");
        }

        AlbumInfo albumInfo = new AlbumInfo(postAlbum);
        int postType = postAlbum.getPostType();
        int total = albumRepository.countPostItem(albumId);
        Page page1 = new Page(pn, pageSize);
        List<PostItem> items = albumRepository.getPostItems(page1, albumId);
        List<String> contentIds = items.stream().map(PostItem::getPostId).collect(Collectors.toList());
        AlbumItem albumItem;
        if (!contentIds.isEmpty() && postType == PostType.Video.getCode()) {
            List<VideoCard> videoCards = videoPostQuery.getVideoCards(contentIds);
            PageList<VideoCard> pageList = PageList.pageList(pn, pageSize, total, videoCards);
            albumItem = new AlbumItem(albumInfo, pageList);
        } else {
            albumItem = new AlbumItem(albumInfo);
        }

        return WebResult.success(albumItem);
    }

    public List<SelectOption> getSelectOptions() {
        long loginUser = UserContext.getUserId();
        AlbumQuery albumQuery = new AlbumQuery.Builder()
                .createBy(loginUser)
                .build();
        Page page = new Page(1, 100);
        List<PostAlbum> list = albumRepository.getPostAlbums(page, albumQuery);

        return list.stream().map(postAlbum -> {
            long albumId = postAlbum.getAlbumId();
            String albumName = postAlbum.getAlbumName();
            return new SelectOption(albumName, albumId+"");
        }).collect(Collectors.toList());
    }

    public PageList<PostAlbum> getPlaylist(int pn) {
        List<Integer> scopes = contentPermission.getUserScopes();
        AlbumQuery albumQuery = new AlbumQuery.Builder()
                .postType(PostType.Video.getCode())
                .scope(scopes)
                .build();
        int total = albumRepository.countPostAlbum(albumQuery);
        Page page = new Page(pn, pageSize);
        List<PostAlbum> list = albumRepository.getPostAlbums(page, albumQuery);
        return PageList.pageList(pn, pageSize, total, list);
    }

    public String getPlaylistItems(long albumId) {
        AlbumQuery albumQuery = new AlbumQuery.Builder()
                .albumId(albumId)
                .build();
        Page page = new Page(1, 1);
        List<PostAlbum> list = albumRepository.getPostAlbums(page, albumQuery);
        if (list.isEmpty()) {
            return WebResult.notFound();
        }

        PostAlbum postAlbum = list.get(0);
        long owner = postAlbum.getCreateBy();
        int scope = postAlbum.getScope();
        long loginUser = UserContext.getUserId();
        if (scope == PostScope.PRIVATE.getCode() && owner != loginUser) {
            return WebResult.notFound();
        }

        boolean hasPermission = contentPermission.hasPermission(owner, scope, loginUser);
        if (!hasPermission) {
            return WebResult.failWithMsg("permission denied");
        }

        AlbumInfo albumInfo = new AlbumInfo(postAlbum);
        int postType = postAlbum.getPostType();
        int total = albumRepository.countPostItem(albumId);
        Page page1 = new Page(1, 1000);
        List<PostItem> items = albumRepository.getPostItems(page1, albumId);
        List<String> contentIds = items.stream().map(PostItem::getPostId).collect(Collectors.toList());
        AlbumItem albumItem;
        if (!contentIds.isEmpty() && postType == PostType.Video.getCode()) {
            List<VideoCard> videoCards = videoPostQuery.getVideoCards(contentIds);
            PageList<VideoCard> pageList = PageList.pageList(1, 100, total, videoCards);
            albumItem = new AlbumItem(albumInfo, pageList);
        } else {
            albumItem = new AlbumItem(albumInfo);
        }

        return WebResult.success(albumItem);
    }
}
