package com.fjhx.oa.service.netdisk.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.common.constant.SourceConstant;
import com.fjhx.file.entity.FileInfo;
import com.fjhx.file.entity.ObsFile;
import com.fjhx.file.service.FileInfoService;
import com.fjhx.oa.entity.netdisk.dto.NetdiskDto;
import com.fjhx.oa.entity.netdisk.dto.NetdiskSelectDto;
import com.fjhx.oa.entity.netdisk.po.Netdisk;
import com.fjhx.oa.entity.netdisk.vo.NetdiskVo;
import com.fjhx.oa.mapper.netdisk.NetdiskMapper;
import com.fjhx.oa.service.netdisk.NetdiskService;
import com.obs.services.internal.ServiceException;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.ruoyi.system.utils.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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


/**
 * <p>
 * 网盘 服务实现类
 * </p>
 *
 * @author
 * @since 2023-04-07
 */
@DS(SourceConstant.OA)
@Service
public class NetdiskServiceImpl extends ServiceImpl<NetdiskMapper, Netdisk> implements NetdiskService {

    @Autowired
    FileInfoService fileInfoService;

    @Override
    public Page<NetdiskVo> getPage(NetdiskSelectDto dto) {
        IWrapper<Netdisk> wrapper = getWrapper();
        wrapper.orderByDesc("n", Netdisk::getId);
        if (ObjectUtil.isEmpty(dto.getParentFolderId())) {
            wrapper.eq(Netdisk::getParentFolderId, "-1");
        } else {
            wrapper.eq(Netdisk::getParentFolderId, dto.getParentFolderId());
        }
        wrapper.like(Netdisk::getName, dto.getKeyword());
        Page<NetdiskVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        UserUtil.assignmentNickName(page.getRecords(), Netdisk::getCreateUser, NetdiskVo::setCreateUserName);
        return page;
    }

    //网盘目录子目录树
    @Override
    public List<NetdiskVo> tree() {
        QueryWrapper<Netdisk> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("type", 1);
        List<Netdisk> list = list(queryWrapper);
        return treeRecursion(list,-1l);
    }

    private List<NetdiskVo> treeRecursion(List<Netdisk> list, Long id){
        List<Netdisk> netdiskList = list.stream().filter(f -> f.getParentFolderId().equals(id)).collect(Collectors.toList());
        List<NetdiskVo> netdiskVos = BeanUtil.copyToList(netdiskList, NetdiskVo.class);
        for (NetdiskVo netdisk :netdiskVos){
            netdisk.setNetdiskList(treeRecursion(list,netdisk.getId()));
        }
        return netdiskVos;
    }

    @Override
    public NetdiskVo detail(Long id) {
        Netdisk Netdisk = this.getById(id);
        NetdiskVo result = BeanUtil.toBean(Netdisk, NetdiskVo.class);
        return result;
    }


    @DSTransactional
    @Override
    public void add(NetdiskDto netdiskDto) {
        //如果父文件夹id为空就赋值初始值-1
        if (ObjectUtil.isEmpty(netdiskDto.getParentFolderId())) {
            netdiskDto.setParentFolderId(-1l);
        }
        if (netdiskDto.getType() == 1) {
            //如果是文件夹，直接创建
            this.save(netdiskDto);
        } else {
            //如果是文件，根据列表创建文件记录
            List<Netdisk> netdiskList = new ArrayList<>();
            List<FileInfo> fileInfoList = new ArrayList<>();

            List<ObsFile> fileList = netdiskDto.getFileList();
            for (ObsFile obsFile : fileList) {
                //保存网盘信息
                long id = IdWorker.getId();
                Netdisk netdisk = new Netdisk();
                netdisk.setId(id);
                netdisk.setType(netdiskDto.getType());
                netdisk.setParentFolderId(netdiskDto.getParentFolderId());
                netdisk.setName(obsFile.getFileName());
                String fileType = "";
                if (obsFile.getFileName().indexOf(".") > 0) {
                    fileType = obsFile.getFileName().substring(obsFile.getFileName().lastIndexOf(".") + 1);
                }
                netdisk.setFileType(fileType);
                netdisk.setFileSize(obsFile.getFileSize());
                netdiskList.add(netdisk);
                //更新文件信息
                FileInfo fileInfo = new FileInfo();
                fileInfo.setId(obsFile.getId());
                fileInfo.setBusinessId(id);
                fileInfo.setBusinessType(0);
                fileInfoList.add(fileInfo);
            }

            DynamicDataSourceContextHolder.push(SourceConstant.BASE);
            fileInfoService.updateBatchById(fileInfoList);
            DynamicDataSourceContextHolder.poll();
            saveBatch(netdiskList);
        }
    }

    @DSTransactional
    @Override
    public void edit(NetdiskDto netdiskDto) {
        this.updateById(netdiskDto);
        Netdisk byId = getById(netdiskDto.getId());
        if(byId.getType()==2) {
            DynamicDataSourceContextHolder.push(SourceConstant.BASE);
            FileInfo fileInfo = fileInfoService.getOne(q -> q.eq(FileInfo::getBusinessId, netdiskDto.getId()));
            if (ObjectUtil.isNotEmpty(fileInfo)) {
                fileInfo.setFileName(netdiskDto.getName());
                fileInfoService.updateById(fileInfo);
            } else {
                throw new ServiceException("文件信息不存在");
            }
            DynamicDataSourceContextHolder.poll();
        }
    }

    @DSTransactional
    @Override
    public void delete(List<Long> ids) {
        this.removeBatchByIds(ids);
        DynamicDataSourceContextHolder.push(SourceConstant.BASE);
        List<FileInfo> list = fileInfoService.list(q -> q.in(FileInfo::getBusinessId, ids));
        if (ObjectUtil.isNotEmpty(list)) {
            List<Long> fids = list.stream().map(FileInfo::getId).collect(Collectors.toList());
            fileInfoService.removeBatchByIds(fids);
        }
        DynamicDataSourceContextHolder.poll();
    }

}
