package com.fdkankan.ucenter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fdkankan.ucenter.entity.Folder;
import com.fdkankan.ucenter.entity.FolderScene;
import com.fdkankan.ucenter.entity.ScenePlus;
import com.fdkankan.ucenter.entity.ScenePro;
import com.fdkankan.ucenter.mapper.IFolderSceneMapper;
import com.fdkankan.ucenter.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.ucenter.vo.response.GroupByCount;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 * 文件夹和场景关联表 服务实现类
 * </p>
 *
 * @author 
 * @since 2022-07-08
 */
@Service
public class FolderSceneServiceImpl extends ServiceImpl<IFolderSceneMapper, FolderScene> implements IFolderSceneService {

    @Autowired
    private ISceneProService sceneProService;
    @Autowired
    private IScenePlusService scenePlusService;
    @Autowired
    private IFolderService folderService;

    @Override
    public void deleteByFolderIds(List<Long> delIds,Long userId) {
        LambdaQueryWrapper<FolderScene> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(FolderScene::getFolderId,delIds);
        List<FolderScene> list = this.list(wrapper);
        List<Long> sceneIds = list.parallelStream().map(FolderScene::getSceneId).collect(Collectors.toList());
        if(sceneIds.size() >0){
            sceneProService.deleteByIds(sceneIds,userId);
        }
        List<Long> ids = list.parallelStream().map(FolderScene::getId).collect(Collectors.toList());
        this.removeByIds(ids);
    }

    @Override
    public FolderScene getByTypeNum(String num, Integer type) {
        return getBaseMapper().getByTypeNum(num,type);
    }

    @Override
    public FolderScene getByType(String sceneId, Integer type) {
        return getBaseMapper().getByType(sceneId,type);
    }

    @Override
    public HashMap<Long, Long> getGroupByFolderIds(List<Folder> folderIds) {
        List<Long> ids = folderIds.parallelStream().map(Folder::getId).collect(Collectors.toList());
        List<GroupByCount> list = getBaseMapper().getGroupByFolderIds(ids);
        HashMap<Long ,Folder> folderMap = new HashMap<>();
        for (Folder folder : folderIds) {
            folderMap.put(folder.getId(),folder);
        }
        HashMap<Long, Long> map = new HashMap<>();
        for (GroupByCount groupByCount : list) {
            Folder folder = this.getParentFolder(folderMap,groupByCount.getId());
            map.merge(folder.getId(), groupByCount.getCount(), Long::sum);
        }
        return map;
    }

    private Folder getParentFolder(HashMap<Long, Folder> folderMap, Long id) {
        Folder folder = folderMap.get(id);
        if(folder != null && folder.getParentId()!=null && folderMap.containsKey(folder.getParentId())){
            return getParentFolder(folderMap,folder.getParentId());
        }
        return folder;
    }

    @Override
    public Long getCountByFolderAndSon(Long folderId) {
        List <Long > folderIdList = new ArrayList<>();
        folderIdList.add(folderId);
        this.getFolderSon(folderId,folderIdList);
        if(folderIdList.size() >0){
            LambdaQueryWrapper<FolderScene> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(FolderScene::getFolderId,folderIdList);
            return this.count(wrapper);
        }
        return 0L;
    }

    private void getFolderSon(Long folderId, List<Long> folderIdList) {
        LambdaQueryWrapper<Folder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Folder::getParentId,folderId);
        List<Folder> list = folderService.list(wrapper);
        if(list.size() <=0){
            return;
        }
        List<Long> collect = list.stream().map(Folder::getId).collect(Collectors.toList());
        folderIdList.addAll(collect);
        for (Long aLong : collect) {
            this.getFolderSon(aLong,folderIdList);
        }
    }

    @Override
    public void delBySceneId(List<Long> proIds) {
        if(proIds.size() >0){
            LambdaQueryWrapper<FolderScene> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(FolderScene::getSceneId,proIds);
            this.remove(wrapper);
        }
    }

    @Override
    public void delByCameraIds(List<Long> cameraIds) {
        if(cameraIds.size() >0){
            List<ScenePro> proList = sceneProService.getListByCameraIds(cameraIds);
            List<ScenePlus> plusList = scenePlusService.getListByCameraIds(cameraIds);
            List<Long > sceneIds = new ArrayList<>();
            if(proList.size() >0){
                List<Long> proIds = proList.stream().map(ScenePro::getId).collect(Collectors.toList());
                if(proIds.size() >0){
                    sceneIds.addAll(proIds);
                }
            }
            if(plusList.size() >0){
                List<Long> plusIds = plusList.stream().map(ScenePlus::getId).collect(Collectors.toList());
                if(plusIds.size() >0){
                    sceneIds.addAll(plusIds);
                }
            }
            if(sceneIds.size() >0){
                this.delBySceneId(sceneIds);
            }
        }
    }
}
