package cn.reghao.tnb.content.app.data.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.tnb.auth.api.iface.AccountQuery;
import cn.reghao.tnb.common.auth.UserContext;
import cn.reghao.tnb.content.api.constant.PostScope;
import cn.reghao.tnb.content.api.constant.PostType;
import cn.reghao.tnb.content.api.dto.ImagePublishSbt;
import cn.reghao.tnb.content.app.data.model.dto.AlbumImageData;
import cn.reghao.tnb.content.app.data.model.vo.AlbumCard;
import cn.reghao.tnb.content.app.data.model.vo.ImageAlbumCard;
import cn.reghao.tnb.content.app.data.model.vo.ImageData;
import cn.reghao.tnb.common.util.IdService;
import cn.reghao.tnb.content.app.vod.db.repository.AlbumRepository;
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.query.AlbumQuery;
import cn.reghao.tnb.content.app.vod.service.ContentPermission;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

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

/**
 * @author reghao
 * @date 2023-08-21 10:49:28
 */
@Slf4j
@Service
public class ImagePostService {
    @DubboReference(check = false, retries = 0, timeout = 60_000)
    private AccountQuery accountQuery;
    @DubboReference(check = false, timeout = 60_000)
    private OssService ossService;

    private final int pageSize = 12;
    private final AlbumRepository albumRepository;
    private final ContentPermission contentPermission;
    private final IdService idService;

    public ImagePostService(AlbumRepository albumRepository, ContentPermission contentPermission,
                            IdService idService) {
        this.idService = idService;
        this.albumRepository = albumRepository;
        this.contentPermission = contentPermission;
    }

    public Result create(ImagePublishSbt imagePublishSbt) {
        String albumName = imagePublishSbt.getAlbumName();
        int scope = imagePublishSbt.getScope();
        long albumId = idService.getLongId();
        int postType = PostType.Image.getCode();
        int channelCode = 102;
        PostAlbum postAlbum = new PostAlbum(albumId, albumName, scope, postType, channelCode);
        albumRepository.savePostAlbum(postAlbum);
        return Result.success();
    }

    public Result add(AlbumImageData albumImageData) {
        long loginUser = UserContext.getUserId();
        long albumId = albumImageData.getAlbumId();
        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()) {
            String errMsg = String.format("相册 %s 不存在", albumId);
            return Result.fail(errMsg);
        }
        PostAlbum postAlbum = list.get(0);

        int total = albumRepository.countPostItem(albumId);
        int imageCount = total + 1;
        if (imageCount > 1000) {
            String errMsg = "一个相册最多可包含 1000 张图片";
            return Result.fail(errMsg);
        }

        String imageFileId = albumImageData.getImageFileId();
        int channelCode = postAlbum.getChannelCode();
        try {
            //ObjectMeta objectMeta = ossService.getObjectMeta(coverFileId);
            /*Map<String, ConvertedImageInfo> map = imageFileIds.stream()
                    .map(imageFileId -> ossService.getWebpInfo(channelCode, imageFileId))
                    .filter(Objects::nonNull)
                    .collect(Collectors.toMap(ConvertedImageInfo::getImageFileId, convertedImageInfo -> convertedImageInfo));
            if (map.isEmpty()) {
                String errMsg = String.format("相册 %s 中的图片转换为 webp 失败", albumId);
                return Result.fail(errMsg);
            }*/
            /*PostItem postItem = new PostItem(albumId, channelCode, imageInfo);
            ObjectChannel objectChannel = ossService.getChannel(channelCode);
            if (objectChannel == null ) {
                String errMsg = String.format("channelCode %s 的 scope 在 oss 中不存在", channelCode);
                return Result.fail(errMsg);
            }

            int scope = postAlbum.getScope();
            if (objectChannel.getScope() != scope) {
                ossService.setObjectScope(channelCode, imageFileId, scope);
            }
            albumRepository.addAlbumImage(albumId, imageCount, postItem);*/
            return Result.success();
        } catch (Exception e) {
            log.error("{}", e.getMessage());
        }

        return Result.fail("");
    }

    private boolean isCollected(String imageFileId) {
        long loginUser = UserContext.getUserId();
        return albumRepository.getByImagePost(imageFileId, loginUser) != null;
    }

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

        AlbumQuery albumQuery = new AlbumQuery.Builder()
                .createBy(userId)
                .postType(PostType.Image.getCode())
                .scope(scopes)
                .build();
        int total = albumRepository.countPostAlbum(albumQuery);
        Page page1 = new Page(page, pageSize);
        List<PostAlbum> list = albumRepository.getPostAlbums(page1, albumQuery);
        List<AlbumCard> albumCards = list.stream().map(postAlbum -> {
            try {
                int scope = postAlbum.getScope();
                if (scope != PostScope.PUBLIC.getCode()) {
                    int channelCode = postAlbum.getChannelCode();
                    if (channelCode != 501) {
                        String coverUrl = postAlbum.getCoverUrl();
                        if (!coverUrl.isBlank()) {
                            PostItem postItem = albumRepository.getByUrl(coverUrl);
                            String objectId = postItem.getObjectId();
                            postAlbum.setCoverUrl(ossService.getSignedUrl(objectId, null));
                        }
                    }
                }
                String userIdStr = accountQuery.getUserIdStr(postAlbum.getCreateBy());
                return new AlbumCard(postAlbum, userIdStr);
            } catch (Exception e) {
                log.error("{}", e.getMessage());
            }
            return null;
        }).filter(Objects::nonNull).collect(Collectors.toList());
        return PageList.pageList(page, pageSize, total, albumCards);
    }

    public String getImageAlbum(long albumId, int pageNumber) {
        AlbumQuery albumQuery = new AlbumQuery.Builder()
                .albumId(albumId)
                .build();
        Page page = new Page(1, 1);
        List<PostAlbum> postAlbumList = albumRepository.getPostAlbums(page, albumQuery);
        if (postAlbumList.isEmpty()) {
            return WebResult.notFound();
        }
        PostAlbum postAlbum = postAlbumList.get(0);

        long loginUser = UserContext.getUserId();
        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");
        }

        int total = albumRepository.countImageFiles(albumId);
        Page page1 = new Page(pageNumber, pageSize);
        List<PostItem> imageFiles = albumRepository.getImageFiles(albumId, page1);
        Map<String, List<PostItem>> map = imageFiles.stream()
                .collect(Collectors.groupingBy(PostItem::getObjectId));

        List<ImageData> list = new ArrayList<>();
        map.forEach((imageFileId, list1) -> {
            ImageData imageData = new ImageData(imageFileId);
            list1.forEach(imageFile -> {
                String url = imageFile.getUrl();
                String format = imageFile.getFormat();
                if (format.equals("webp")) {
                    imageData.setThumbnailUrl(url);
                } else {
                    imageData.setOriginalUrl(url);
                }
            });

            if (imageData.getThumbnailUrl() == null) {
                imageData.setThumbnailUrl(imageData.getOriginalUrl());
            }
            boolean collected = isCollected(imageFileId);
            imageData.setCollected(collected);
            list.add(imageData);
        });

        PageList<ImageData> pageList = PageList.pageList(pageNumber, pageSize, total, list);
        String userIdStr = accountQuery.getUserIdStr(postAlbum.getCreateBy());
        ImageAlbumCard imageAlbumCard = new ImageAlbumCard(postAlbum, userIdStr);
        imageAlbumCard.setImages(pageList);
        if (scope != PostScope.PUBLIC.getCode()) {
            imageAlbumCard.getImages().getList().forEach(imageData -> {
                String imageFileId = imageData.getImageFileId();
                int channelCode = postAlbum.getChannelCode();
                if (channelCode != 501) {
                    try {
                        String signedUrl = ossService.getSignedUrl(imageFileId, null);
                        imageData.setThumbnailUrl(signedUrl);
                        imageData.setOriginalUrl(signedUrl);
                    } catch (Exception e) {
                        log.error("{}", e.getMessage());
                    }
                }
            });
        }

        return WebResult.success(imageAlbumCard);
    }
}
