package com.apobates.forum.core.impl.service;

import com.apobates.forum.attention.ImageDirectoryEnum;
import com.apobates.forum.attention.core.UploadImagePathConvert;
import com.apobates.forum.core.ImageIOMeta;
import com.apobates.forum.core.dao.AlbumDao;
import com.apobates.forum.core.dao.AlbumPictureDao;
import com.apobates.forum.core.entity.Album;
import com.apobates.forum.core.entity.AlbumPicture;
import com.apobates.forum.core.service.AlbumPictureService;
import com.apobates.forum.utils.lang.BoundedTreeSet;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 *
 * @author xiaofanku
 * @since 20200512
 */
@Service
public class AlbumPictureServiceImpl implements AlbumPictureService {
    @Autowired
    private AlbumPictureDao albumPictureDao;
    @Autowired
    private AlbumDao albumDao;
    private final static Logger logger = LoggerFactory.getLogger(AlbumPictureServiceImpl.class);
    
    @Override
    public long create(long albumId, String encodeImageAddr, String caption, int ranking, boolean status, boolean cover) throws IllegalArgumentException, IllegalStateException {
        if (null == encodeImageAddr || encodeImageAddr.isEmpty()) {
            throw new IllegalArgumentException("图片地址不可用或不被接受");
        }
        Album data = albumDao.findOne(albumId).orElseThrow(()-> new IllegalStateException("像册不存在"));
        AlbumPicture ap = new AlbumPicture(data, encodeImageAddr, caption, status, ranking, cover);
        try {
            albumPictureDao.save(ap);
            if (ap.getId() > 0) {
                return ap.getId();
            }
        } catch (Exception e) {
            if (logger.isDebugEnabled()) {
                logger.debug("为像册增加图片失败", e);
            }
        }
        return 0L;
    }
    
    @Override
    public Optional<AlbumPicture> create(long albumId, String encodeImageAddr, String caption, int ranking, boolean status) throws IllegalArgumentException, IllegalStateException {
        if (null == encodeImageAddr || encodeImageAddr.isEmpty()) {
            throw new IllegalArgumentException("图片地址不可用或不被接受");
        }
        Album album = albumDao.findOne(albumId).orElseThrow(()-> new IllegalStateException("像册不存在"));
        AlbumPicture ap = new AlbumPicture(album, encodeImageAddr, caption, status, ranking, false);
        try {
            album.getPictures().add(ap);
            albumDao.edit(album);
            return Optional.of(ap);
        } catch (Exception e) {
            if (logger.isDebugEnabled()) {
                logger.debug("为像册增加图片失败", e);
            }
        }
        return Optional.empty();
    }
    
    @Override
    public Map<Long, TreeSet<AlbumPicture>> getAll(Set<Long> albumIdSet, ImageIOMeta imageIO, String scale, String defaultPicture, final int showSize) {
        if (null == albumIdSet || albumIdSet.isEmpty()) {
            return Collections.emptyMap();
        }
        List<Long> albumIds = albumIdSet.stream().filter(albumId -> albumId > 0).collect(Collectors.toList());
        return thumbMapper(albumPictureDao.findAllByAlbum(albumIds), imageIO, scale, defaultPicture).collect(Collectors.groupingBy(AlbumPicture::getAlbumId, Collectors.toCollection(()->new BoundedTreeSet<>(showSize))));//限制数量
    }
    
    @Override
    public Stream<AlbumPicture> getAll(Set<Long> albumIdSet, ImageIOMeta imageIO, final String scale, final String defaultPicture) { 
        if (null == albumIdSet || albumIdSet.isEmpty()) {
            return Stream.empty();
        }
        List<Long> albumIds = albumIdSet.stream().filter(albumId -> albumId > 0).collect(Collectors.toList());
        return thumbMapper(albumPictureDao.findAllByAlbum(albumIds), imageIO, scale, defaultPicture);
    }

    private static Stream<AlbumPicture>  thumbMapper(Stream<AlbumPicture> aps, ImageIOMeta imageIO, String thumbScale, String defaultPic){
        //上传图片的路径转换
        final UploadImagePathConvert uipc = new UploadImagePathConvert(imageIO.getImageBucketDomain(), imageIO.getUploadImageDirectName());
        Function<AlbumPicture,AlbumPicture> decodeMapper = (ap)->{
            String tmpThumb=null, tmpLink=null;
            try {
                tmpLink = uipc.decode(ap.getLink(), ImageDirectoryEnum.DEFAT, "auto").map(URL::toString).orElse(defaultPic); //"/static/img/140x140.png"
                tmpThumb = uipc.decode(ap.getLink(), ImageDirectoryEnum.DEFAT, thumbScale).map(URL::toString).orElse(defaultPic);
            } catch (MalformedURLException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug(String.format("%s is malformed fail", ap.getLink()), ex);
                }
            }
            if(tmpLink!=null){
                AlbumPicture safeIns = new AlbumPicture();
                safeIns.setLink(tmpLink);
                safeIns.setThumb(Commons.optional(tmpThumb, defaultPic));
                safeIns.setCover(ap.isCover());
                safeIns.setStatus(ap.isStatus());
                safeIns.setCaption(ap.getCaption());
                safeIns.setId(ap.getId());
                safeIns.setRanking(ap.getRanking());
                safeIns.setAlbum(ap.getAlbum());
                return safeIns;
            }
            return ap;
        };
        return aps.map(decodeMapper);
    }
    
    @Override
    public Stream<AlbumPicture> getAll(long albumId) {
        return albumPictureDao.findAllByAlbum(albumId);
    }
    
    @Override
    public Optional<AlbumPicture> get(long id) {
        return albumPictureDao.findOne(id);
    }
    
    @Override
    public int delete(long id) {
        return albumPictureDao.delete(Set.of(id));
    }
    
    @Override
    public int delete(Set<Long> idSet) {
        if (null == idSet || idSet.isEmpty()) {
            return 0;
        }
        return albumPictureDao.delete(idSet);
    }
}
