package com.patzn.lims.file.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.patzn.lims.file.entity.LmsFile;
import com.patzn.lims.file.entity.LmsFileStorage;
import com.patzn.lims.file.mapper.LmsFileMapper;
import com.patzn.lims.file.service.ILmsFileService;
import com.patzn.lims.file.service.ILmsFileStorageService;
import com.patzn.lims.file.vo.LmsFileVO;
import com.patzn.lims.res.service.MongoDbService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wangweidong
 * @since 2019-12-13
 */
@Slf4j
@Service
public class LmsFileServiceImpl extends BaseServiceImpl<LmsFileMapper, LmsFile> implements ILmsFileService {

    @Autowired
    private ILmsFileStorageService lmsFileStorageService;
    @Autowired
    private MongoDbService mongoDbService;

    @Override
    public Page<LmsFile> page(Page<LmsFile> page, LmsFile schoolFile) {
        QueryWrapper<LmsFile> wrapper = Wrappers.<LmsFile>query(schoolFile);
        return this.page(page, wrapper);
    }


    @Override
    public List<LmsFile> list(LmsFile schoolFile) {
        return this.list(Wrappers.<LmsFile>query(schoolFile));
    }

    @Override
    public Page<LmsFileVO> pageVO(Page<LmsFileVO> page, LmsFileVO schoolFile) {
        if (null==schoolFile.getFolderId()){
            return baseMapper.selectStorageFileVOList(page,schoolFile);
        }else{
            return baseMapper.selectFileVOList(page,schoolFile);
        }
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveFile(String folderId, MultipartFile file, Account account) {
        if (null==account){
            return false;
        }
        if (null==account.getCompanyId()){
            return false;
        }
        String fileName = file.getOriginalFilename();
        try {
            fileName=  fileName.substring(fileName.lastIndexOf("."));
         }catch (Exception e){
            e.printStackTrace();
            return false;

        }
        synchronized (lmsFileStorageService){

            LmsFileStorage storage =null;
            List<LmsFileStorage> storageList = lmsFileStorageService.list(Wrappers.<LmsFileStorage>query().eq("company_id",account.getCompanyId()));
            if (CollectionUtils.isEmpty(storageList)){
                LmsFileStorage sysFileStorage = new LmsFileStorage();
                sysFileStorage.setCompanyId(account.getCompanyId());
                sysFileStorage.setBucket("files");
                sysFileStorage.setName("主文件夹"+account.getCompanyId());
                sysFileStorage.setCapacity(new BigDecimal("512"));
                sysFileStorage.setCapacityKb(new BigDecimal("524288"));
                sysFileStorage.setLeftover(new BigDecimal("512"));
                sysFileStorage.setUsed(BigDecimal.ZERO);
                sysFileStorage.setCtime(new Date());
                sysFileStorage.setUid(account.getUserId());
                sysFileStorage.setDeleted(0);
                lmsFileStorageService.save(sysFileStorage);
                storage= sysFileStorage;
            }else{
                storage=storageList.get(0);
            }

                int version = storage.getVersion();

                BigDecimal all=storage.getCapacityKb();
                BigDecimal usedBig=storage.getUsed();
                if (null==usedBig){
                    usedBig=BigDecimal.ZERO;
                }
                long  size = file.getSize();
                long kbSize= size/1024;//由B换算成kB
                BigDecimal inStock=BigDecimal.valueOf(kbSize);
                BigDecimal nowIn = usedBig.add(inStock);
                if (nowIn.compareTo(all)>0){
                    PtAssert.fail("您的存储空间不足，请联系管理员");
                    return false;
                }

                String result =mongoDbService.saveFile(file);
                if (StringUtils.isBlank(result)){
                    return false;
                }

                LmsFile sysFile =new LmsFile();

                sysFile.setStorageId(storage.getId());
                if (StringUtils.isNotBlank(folderId)){
                    if (StringUtils.isNumeric(folderId)){
                        sysFile.setFolderId(Long.parseLong(folderId));
                    }
                }
                sysFile.setFileSize(inStock);
                sysFile.setFileType(fileName);
                sysFile.setUname(account.getUserName());
                sysFile.setName(file.getOriginalFilename());
                sysFile.setUri(result);

            LmsFileStorage fileStorage = new LmsFileStorage();
                fileStorage.setUsed(nowIn);
                fileStorage.setVersion(version+1);
                if (lmsFileStorageService.update(fileStorage,Wrappers.<LmsFileStorage>query().eq("id",storage.getId()).eq("version",version))){
                  return save(sysFile);
                }

        }
        return false;
    }

    @Override
    public void downLoad(Long id, HttpServletRequest request, HttpServletResponse response) {
        if (null == id){
            PtAssert.fail("文件不存在");
        }
        LmsFile file= getById(id);
        if (null == file) {
            PtAssert.fail("文件不存在");
        }
        String uri=  file.getUri();
        if (StringUtils.isBlank(uri)){
            PtAssert.fail("文件不存在");
        }
        try {

            String key = uri.split("#")[1];
            mongoDbService.downloadFile(key,request,response);
        }catch (Exception e){
           log.error("downLoad下载文件失败，"+e.getMessage(),e);
        }


    }

    public void downBatch(List<LmsFile> fileList, HttpServletResponse response){
//        Map<String, InputStream> mapStream = new HashMap<>(16);
//        try {
//            for (LmsFile file:fileList) {
//                mapStream.put(file.getName() , gridFSClient.download(file.getUri().split("#")[1]));
//            }
//            OutputStream fos = response.getOutputStream();
//            List<FileEntry> fileEntryList = Lists.newArrayList();
//            for (Map.Entry<String, InputStream> streamEntry : mapStream.entrySet()) {
//                fileEntryList.add(new FileEntry(streamEntry.getValue(), streamEntry.getKey()));
//            }
//            ZipUtils.zipFile(fos, fileEntryList);
//        }catch (Exception e){
//            logger.error("downBatch打包下载失败"+e.getMessage(),e);
//        }
    }

    @Override
    public void downloadBatch(Long folderId, HttpServletResponse response) {
        List<LmsFile> fileList =null;
        if (null != folderId ){
            fileList= list(Wrappers.<LmsFile>query().eq("folder_id",folderId));
        }else{
            fileList= list(Wrappers.<LmsFile>query().isNull("folder_id"));
        }
        if (CollectionUtils.isNotEmpty(fileList)){
            downBatch(fileList,response);
        }
    }

    @Override
    public void downloadByIds(Long[] ids, HttpServletResponse response) {
        List<LmsFile> fileList = list(Wrappers.<LmsFile>query().in("id",ids));
        if (CollectionUtils.isNotEmpty(fileList)){
            downBatch(fileList,response);
        }
    }
}
