package com.izouma.nineth.service;

import cn.hutool.core.collection.CollUtil;
import com.izouma.nineth.domain.*;
import com.izouma.nineth.domain.Collection;
import com.izouma.nineth.dto.PageQuery;
import com.izouma.nineth.enums.AssetStatus;
import com.izouma.nineth.enums.CollectionType;
import com.izouma.nineth.exception.BusinessException;
import com.izouma.nineth.repo.AssetRepo;
import com.izouma.nineth.repo.CollectionRepo;
import com.izouma.nineth.repo.ShowCollectionRepo;
import com.izouma.nineth.repo.ShowroomRepo;
import com.izouma.nineth.utils.JpaUtils;
import com.izouma.nineth.utils.ObjUtils;
import lombok.AllArgsConstructor;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import javax.persistence.Id;
import java.util.*;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class ShowroomService {

    private ShowroomRepo       showroomRepo;
    private AssetRepo          assetRepo;
    private CollectionRepo     collectionRepo;
    private ShowCollectionRepo showCollectionRepo;

    public Page<Showroom> all(PageQuery pageQuery) {
        return showroomRepo.findAll(JpaUtils.toSpecification(pageQuery, Showroom.class), JpaUtils.toPageRequest(pageQuery));
    }

    /*
    不做盲盒
     */
    public Showroom save(Long userId, Showroom showroom) {
        Asset asset = assetRepo.findById(showroom.getAssetId()).orElseThrow(new BusinessException("资产不存在"));
        if (!userId.equals(asset.getUserId())) {
            throw new BusinessException("该资产不属于你");
        }
        if (!CollectionType.SHOWROOM.equals(asset.getType())) {
            throw new BusinessException("不是展厅藏品");
        }
        if (!AssetStatus.NORMAL.equals(asset.getStatus())) {
            throw new BusinessException("该状态不可创建展厅");
        }
        if (asset.isConsignment()) {
            throw new BusinessException("寄售中不可以创建");
        }

        if (showroomRepo.findByAssetId(showroom.getAssetId()).isPresent()) {
            throw new BusinessException("已创建过展厅");
        }

        List<ShowCollection> showCollections = showroom.getCollections();

//        Collection showColl = collectionRepo.findById(asset.getCollectionId())
//                .orElseThrow(new BusinessException("无藏品"));
        if (asset.getMaxCollection() < showCollections.size()) {
            throw new BusinessException("选择的藏品数量大于最多可放置数量");
        }

        List<Long> collectionIds = showCollections.stream()
                .map(ShowCollection::getCollectionId)
                .distinct()
                .collect(Collectors.toList());

        List<Collection> collections = collectionRepo.findAllByIdIn(collectionIds);
        Map<Long, Collection> collectionMap = new HashMap<>();
        collections.forEach(collection -> {
            if (!userId.equals(collection.getOwnerId())) {
                throw new BusinessException("该藏品不属于你");
            }
            collectionMap.put(collection.getId(), collection);
        });

        showroom.setUserId(userId);
        showroom.setShowroomBg(asset.getShowroomBg());
        showroom.setMaxCollection(asset.getMaxCollection());
        showroom.setNickname(asset.getOwnerName());
        Showroom show = showroomRepo.save(showroom);

        showCollections.forEach(showCollection -> {
            Collection collection = collectionMap.get(showCollection.getCollectionId());
            if (ObjectUtils.isNotEmpty(collection)) {
                FileObject pic = collection.getPic().get(0);
                showCollection.setPic(pic.getUrl());
                if("video/mp4".equals(pic.getType())){
                    showCollection.setPic(pic.getThumb());
                }
                showCollection.setShowroomId(show.getId());
                showCollection.setAssetId(collection.getAssetId());
                showCollectionRepo.save(showCollection);
            }
        });
        return show;
    }

    public Showroom save(Asset asset) {
        if (!AssetStatus.NORMAL.equals(asset.getStatus())) {
            throw new BusinessException("该状态不可创建展厅");
        }
        if (asset.isConsignment()) {
            throw new BusinessException("寄售中不可以创建");
        }

        if (showroomRepo.findByAssetId(asset.getId()).isPresent()) {
            throw new BusinessException("已创建过展厅");
        }
        Showroom showroom = Showroom.builder()
                .showroomBg(asset.getShowroomBg())
                .maxCollection(asset.getMaxCollection())
                .publish(false)
                .userId(asset.getUserId())
                .assetId(asset.getId())
                .nickname(asset.getOwnerName())
                .build();


        return showroomRepo.save(showroom);
    }

    public Showroom update(Long userId, Showroom showroom) {
        Showroom recordRoom = showroomRepo.findById(showroom.getId()).orElseThrow(new BusinessException("无展厅"));
        showroom.setMaxCollection(recordRoom.getMaxCollection());
        // 上传的藏品
        List<ShowCollection> showCollections = showroom.getCollections();

        List<ShowCollection> recordShowColls = showCollectionRepo.findAllByShowroomId(showroom.getId());
        Map<Long, ShowCollection> showCollectionMap = recordShowColls.stream()
                .collect(Collectors.toMap(ShowCollection::getId, coll -> coll));

        Map<Long, ShowCollection> showCollectionMap1 = recordShowColls.stream()
                .collect(Collectors.toMap(ShowCollection::getCollectionId, coll -> coll));

        Set<Long> removeRecord = new HashSet<>(showCollectionMap.keySet());

        if (CollUtil.isNotEmpty(showCollections)) {

            if (recordRoom.getMaxCollection() < showCollections.size()) {
                throw new BusinessException("选择的藏品数量大于最多可放置数量");
            }
            List<Long> collectionIds = showCollections
                    .stream()
                    .filter(show -> ObjectUtils.isEmpty(show.getId()))
                    .map(ShowCollection::getCollectionId)
                    .collect(Collectors.toList());

            List<Collection> collections = collectionRepo.findAllByIdIn(collectionIds);
            Map<Long, Collection> collectionMap = new HashMap<>();
            collections.forEach(collection -> {
                if (!userId.equals(collection.getOwnerId())) {
                    throw new BusinessException("该藏品不属于你");
                }
                collectionMap.put(collection.getId(), collection);
            });

            showCollections.forEach(coll -> {
                if (coll.getId() != null) {
                    ShowCollection showCollection = showCollectionMap.get(coll.getId());
                    if (ObjectUtils.isNotEmpty(showCollection)) {
                        ObjUtils.merge(showCollection, coll);
                        showCollectionRepo.save(showCollection);
                        // 移除掉
                        removeRecord.remove(coll.getId());
                    }
                } else {
                    ShowCollection showCollection = showCollectionMap1.get(coll.getCollectionId());
                    if (ObjectUtils.isNotEmpty(showCollection)) {
                        ObjUtils.merge(showCollection, coll);
                        showCollectionRepo.save(showCollection);
                        removeRecord.remove(showCollection.getId());
                    } else {
                        Collection collection = collectionMap.get(coll.getCollectionId());
                        if (ObjectUtils.isNotEmpty(collection)) {
                            FileObject pic = collection.getPic().get(0);
                            coll.setPic(pic.getUrl());
                            if("video/mp4".equals(pic.getType())){
                                coll.setPic(pic.getThumb());
                            }
                            coll.setShowroomId(recordRoom.getId());
                            coll.setAssetId(collection.getAssetId());
                            showCollectionRepo.save(coll);
                        }
                    }
                }
            });
        } else {
            // 删掉本次没有的
            showCollectionRepo.softDeleteByRoom(recordRoom.getId());
        }
        if (CollUtil.isNotEmpty(removeRecord)) {
            showCollectionRepo.softDeleteByIdIn(removeRecord);
        }

        ObjUtils.merge(recordRoom, showroom);
        return showroomRepo.save(recordRoom);
    }

}
