package com.fdkankan.scene.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.constant.RecStatus;
import com.fdkankan.common.constant.TbStatus;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.response.ResultData;
import com.fdkankan.common.util.DateExtUtil;
import com.fdkankan.scene.entity.Folder;
import com.fdkankan.scene.entity.FolderScene;
import com.fdkankan.scene.entity.ScenePro;
import com.fdkankan.scene.mapper.IFolderMapper;
import com.fdkankan.scene.service.IFolderSceneService;
import com.fdkankan.scene.service.IFolderService;
import com.fdkankan.scene.service.ISceneProService;
import com.fdkankan.scene.vo.FolderParamVO;
import com.fdkankan.scene.vo.FolderVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * <p>
 * 文件夹表 服务实现类
 * </p>
 *
 * @author dengsixing
 * @since 2021-12-24
 */
@Service
public class FolderServiceImpl extends ServiceImpl<IFolderMapper, Folder> implements IFolderService {

    @Autowired
    IFolderSceneService folderSceneService;
    @Autowired
    ISceneProService sceneProService;

    @Override
    public List<Folder> findByParentId(Long parentId) {
        return baseMapper.selectList(
                new LambdaQueryWrapper<Folder>()
                        .eq(Folder::getTbStatus, TbStatus.VALID.code())
                        .eq(Folder::getParentId, parentId));
    }

    @Override
    public List<Folder> findByParentIdAndName(Long parentId, String folderName, Long userId) {
        return baseMapper.selectByCondition(
                FolderVO.builder()
                        .recStatus(RecStatus.VALID.code())
                        .folderName(folderName)
                        .userId(userId)
                        .parentId(parentId).build());
    }

    @Override
    public List<Folder> findByUserIdAndType(Long userId, Integer folderType, String folderName) {
        return baseMapper.selectByUserIdAndType(
                FolderVO.builder()
                        .folderName(folderName)
                        .userId(userId)
                        .folderType(folderType).build());
    }

    /**
     * 这里的ids似乎没用
     * @param id
     * @param ids
     */
    @Override
    public void deleteAllFile(Long id, Set<Long> ids) {
        Folder folder = new Folder();
        folder.setTbStatus(TbStatus.DELETE.code());

        this.update(new LambdaUpdateWrapper<Folder>()
                .eq(Folder::getId, id)
                .set(Folder::getTbStatus, TbStatus.DELETE.code()));

        List<FolderScene> folderSceneList = folderSceneService.findByFolderId(id);
        if(CollUtil.isNotEmpty(folderSceneList)){
            folderSceneList.forEach(folderScene -> ids.add(folderScene.getSceneId()));
        }

        folderSceneService.deleteByFolderId(id);

        List<Folder> list = this.findByParentId(id);
        if(CollUtil.isNotEmpty(list)){
            for (Folder item : list) {
                deleteAllFile(item.getId(), ids);
            }
        }
    }

    @Override
    public void move(FolderVO folderVO) {

        if(StrUtil.isEmpty(folderVO.getFolderIds()) && StrUtil.isEmpty(folderVO.getSceneIds())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        if(Objects.isNull(folderVO.getFolderType())){
            throw new BusinessException(ErrorCode.PARAM_REQUIRED);
        }

        String[] folderIds = folderVO.getFolderIds().split(",");

        Folder folder = null;
        for (String folderId : folderIds) {
            folder = this.getOne(
                    new LambdaQueryWrapper<Folder>()
                            .eq(Folder::getTbStatus, TbStatus.VALID.code())
                            .eq(Folder::getId, Long.valueOf(folderId)));
            if(Objects.isNull(folder)){
                continue;
            }
            folder.setParentId(folderVO.getParentId());

            List<Folder> subList = this.findByParentIdAndName(folderVO.getParentId(), folder.getFolderName(), folderVO.getUserId());
            if(CollUtil.isNotEmpty(subList)){
                //表示迁移回当前目录，不做处理
                if(subList.get(0).getId().equals(Long.parseLong(folderId))){
                    return;
                }
                throw new BusinessException(ErrorCode.FAILURE_CODE_5030);
            }

            updateById(folder);
        }

        if(StrUtil.isNotEmpty(folderVO.getSceneIds())){
            String[] sceneIds = folderVO.getSceneIds().split(",");

            FolderScene folderScene = null;
            for (String sceneId : sceneIds) {
                folderScene = folderSceneService.findByType(Long.valueOf(sceneId), folderVO.getFolderType());
                if(Objects.nonNull(folderScene)){
                    folderSceneService.removeById(folderScene.getId());
                }

                if(Objects.nonNull(folderVO.getParentId())){
                    folderScene = new FolderScene();
                    folderScene.setSceneId(Long.valueOf(sceneId));
                    folderScene.setFolderId(folderVO.getParentId());

                    folderSceneService.save(folderScene);
                }
            }
        }


    }

    @Override
    public List<FolderVO> convert(List<Folder> list) {
        List<FolderVO> responseFolders = new ArrayList<>();
        Integer sceneNumFile = 0;
        for (Folder folder : list){
            sceneNumFile = 0;
            FolderVO folderVO = FolderVO.builder().build();
            BeanUtils.copyProperties(folder, folderVO);
            folderVO.setName(folder.getFolderName());
            folderVO.setType(folder.getFolderType());
            if(folder.getCreateTime() != null){
                folderVO.setCreateTimeStr(DateUtil.format(folder.getCreateTime(), DateExtUtil.dateStyle4));
            }
            folderVO.setIsFolder(1);

            Integer sceneNum = 0;

            List<FolderScene> folderSceneList =
                    folderSceneService.list(
                            new LambdaQueryWrapper<FolderScene>()
                                    .eq(FolderScene::getFolderId, folder.getId())
                                    .orderByDesc(FolderScene::getId));

            if(CollUtil.isNotEmpty(folderSceneList)){
                sceneNumFile =  sceneProService.findFolderIdScence(folder.getId(),folder.getUserId());
            }

            sceneNum += sceneNumFile;

            //获取当前文件夹里面文件夹的场景数
            sceneNum = folderChildrenSceneNum(folderVO.getId(), sceneNum);
//                log.info(responseFolder.getName() + ",该场景最终数量：" + sceneNum);
            folderVO.setSceneNum(sceneNum);
            if(CollUtil.isNotEmpty(folderSceneList)){
                ScenePro scenePro = sceneProService.getOne(
                            new LambdaQueryWrapper<ScenePro>()
                                .select(ScenePro::getThumb)
                                .eq(ScenePro::getId,folderSceneList.get(0).getSceneId()));
                folderVO.setImg(scenePro == null? "" : scenePro.getThumb());
            }

            responseFolders.add(folderVO);
        }
        return responseFolders;
    }

    @Override
    public ResultData save(FolderParamVO param) {

        LambdaQueryWrapper<Folder> wrapper = new LambdaQueryWrapper<Folder>()
            .eq(Folder::getFolderName, param.getName()).eq(Folder::getUserId, param.getUserId());
        if(Objects.isNull(param.getParentId())){
            wrapper.isNull(Folder::getParentId);
        }else{
            wrapper.eq(Folder::getParentId, param.getParentId());
        }
        if(param.getType() !=null){
            wrapper.eq(Folder::getFolderType,param.getType());
        }
        long count = this.count(wrapper);
        if(count > 0){
            throw new BusinessException(ErrorCode.FAILURE_CODE_5030);
        }

        Folder folder = new Folder();
        BeanUtils.copyProperties(param, folder);
        folder.setFolderName(param.getName());
        folder.setFolderType(param.getType());

        this.save(folder);

        return ResultData.ok();
    }

    //根据文件夹，递归获取该文件夹中所有文件夹的场景数量之和
    public int folderChildrenSceneNum(Long parentId, Integer sceneNum){
        List<Folder> byParentId = this.findByParentId(parentId);
        if(byParentId != null && byParentId.size() > 0){
            Integer sceneNumFile = 0;
            for (Folder folder : byParentId) {
                sceneNumFile = 0;
                List<FolderScene> folderSceneList =
                        folderSceneService.list(
                                new LambdaQueryWrapper<FolderScene>()
                                        .eq(FolderScene::getFolderId, folder.getId())
                                        .orderByDesc(FolderScene::getId));

                if(CollUtil.isNotEmpty(folderSceneList)){
                    sceneNumFile =  sceneProService.findFolderIdScence(folder.getId(),folder.getUserId());
                }

                sceneNum += sceneNumFile;
                sceneNum = folderChildrenSceneNum(folder.getId(), sceneNum);
            }
        }
        return sceneNum;
    }
}
