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.AuthStatus;
import com.izouma.nineth.enums.CollectionType;
import com.izouma.nineth.exception.BusinessException;
import com.izouma.nineth.repo.*;
import com.izouma.nineth.utils.JpaUtils;
import com.izouma.nineth.utils.ObjUtils;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
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;
    private CollectionPrivilegeRepo collectionPrivilegeRepo;
    private CacheService            cacheService;
    private UserRepo                userRepo;
    private SysConfigService        sysConfigService;

    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();

        CollectionPrivilege cp = collectionPrivilegeRepo.findByCollectionId(asset.getCollectionId());
        if (cp.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.setHeadBg(cp.getHeadBg());
        showroom.setShowroomBg(cp.getShowroomBg());
        showroom.setMaxCollection(cp.getMaxCollection());
        showroom.setNickname(asset.getOwner());
        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());
                showCollection.setStatus(getStatus(collection));
                showCollection.setPrice(collection.getPrice());
                showCollectionRepo.save(showCollection);
            }
        });

        cacheService.clearShowroom();
        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("已创建过展厅");
        }
        CollectionPrivilege cp = collectionPrivilegeRepo.findByCollectionId(asset.getCollectionId());
        Showroom showroom = Showroom.builder()
                .headBg(cp.getHeadBg())
                .showroomBg(cp.getShowroomBg())
                .maxCollection(cp.getMaxCollection())
                .publish(false)
                .userId(asset.getUserId())
                .assetId(asset.getId())
                .nickname(asset.getOwner())
                .type("USER")
                .status(AuthStatus.SUCCESS)
                .build();
        showroom = showroomRepo.save(showroom);

        cacheService.clearShowroom();
        return showroom;
    }

    public Showroom save(Long userId) {
        User user = userRepo.findByIdAndDelFalse(userId).orElseThrow(new BusinessException("无用户"));
        if (!user.isCompany()) {
            throw new BusinessException("无用户权限");
        }

        if (showroomRepo.findByUserIdAndType(user.getId(), "COMPANY").isPresent()) {
            throw new BusinessException("已创建过展厅");
        }
        int maxCollection = sysConfigService.getInt("max_collection");

        Showroom showroom = Showroom.builder()
                .headBg("")
                .showroomBg("")
                .maxCollection(maxCollection)
                .publish(false)
                .userId(user.getId())
                .nickname(user.getNickname())
                .type("COMPANY")
                .status(AuthStatus.NOT_AUTH)
                .build();
        showroom = showroomRepo.save(showroom);

        cacheService.clearShowroom();
        return 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)) {
            showCollections = showCollections.stream().distinct().collect(Collectors.toList());

            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());
                            coll.setStatus(getStatus(collection));
                            coll.setPrice(collection.getPrice());
                            showCollectionRepo.save(coll);
                        }
                    }
                }
            });
        } else {
            // 删掉本次没有的
            showCollectionRepo.deleteAllByShowroomId(recordRoom.getId());
        }
        if (CollUtil.isNotEmpty(removeRecord)) {
            showCollectionRepo.deleteAllByIdIn(removeRecord);
        }

        ObjUtils.merge(recordRoom, showroom);
        recordRoom.setPublish(true);

        showroom = showroomRepo.save(recordRoom);
        cacheService.clearShowroom();
        return showroom;
    }

    public void audit(Long id, AuthStatus status, String reason) {
        Showroom showroom = showroomRepo.findById(id).orElseThrow(new BusinessException("无展厅"));
        if (!"COMPANY".equals(showroom.getType())) {
            // 非企业类型不需要审核
            showroom.setStatus(null);
            showroomRepo.save(showroom);
            return;
        }
        showroom.setStatus(status);
        showroom.setReason(reason);
        showroomRepo.save(showroom);
        cacheService.clearShowroom();
    }

    public String getStatus(Collection collection) {
        boolean salable = collection.isSalable();
        if (collection.getSaleTime() != null) {
            if (collection.getSaleTime().isAfter(LocalDateTime.now())) {
                return "仅展示";
            }
        }
        if (!salable) {
            return "仅展示";
        }
        if (collection.getSoldOut() > 1) {
            return "寄售中";
        }
        if (collection.isNoSoldOut()) {
            return "仅展示";
        }
        if (collection.getSoldOut() != 1 & collection.getStock() == 0) {
            return "仅展示";
        }
        return "寄售中";
    }

    public String getStatusById(Long collectionId) {
        Collection collection = collectionRepo.findById(collectionId).orElseThrow(new BusinessException("暂无"));
        return getStatus(collection);
    }
}
