package com.tofly.gpsboot.service.comm.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tofly.common.core.util.StringUtil;
import com.tofly.common.ftp.config.FtpUtil;
import com.tofly.gpsboot.common.Constant;
import com.tofly.gpsboot.exception.BusinessException;
import com.tofly.gpsboot.mapper.comm.FileMapper;
import com.tofly.gpsboot.service.comm.IFileInfoService;
import com.tofly.pojo.comm.File;
import com.tofly.pojo.comm.FileInfo;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;


@Service("FileInfoService")
public class FileInfoServiceImpl extends ServiceImpl<FileMapper, File> implements IFileInfoService {

    @Override
    public StringBuilder saveFileList(List<MultipartFile> fileList, String filePathBean, String tableName) {
        StringBuilder fileIds = new StringBuilder("");

        //保存照片
        fileList.forEach(file -> {
            //文件名
            String fileName = file.getOriginalFilename();
            if (!"".equals(fileName)) {
                //文件路径
                assert fileName != null;
                String filePath = filePathBean + IdWorker.getIdStr() + fileName.substring(fileName.lastIndexOf(Constant.POINT));
                boolean b = FtpUtil.uploadFile2Ftp(file, filePath);
                if (b) {
                    File localFile = new File();
                    localFile.setFilePath(filePath);
                    localFile.setFileName(fileName);
                    localFile.setOtherName(IdWorker.getIdStr() + fileName.substring(fileName.lastIndexOf(Constant.POINT)));
                    //关联表名称
                    localFile.setTableName(tableName);
                    //获取后缀
                    String suffix = fileName.substring(fileName.lastIndexOf(Constant.POINT));
                    localFile.setFileFormat(suffix);
                    localFile.setFileSize(file.getSize() + Constant.KB);
                    this.save(localFile);
                    //获得文件ID
                    fileIds.append(localFile.getId()).append(Constant.CSV);
                } else {
                    throw new BusinessException(Constant.FILE_UPLOAD_ERROR_CODE, Constant.FILE_UPLOAD_ERROR);
                }
            }
        });
        if (fileIds.length() > 0) {
            return fileIds.deleteCharAt(fileIds.length() - 1);
        }
        return fileIds;
    }

    @Override
    public List<FileInfo> saveFileInfoList(List<MultipartFile> fileList, String filePathBean, String tableName) {
        List<FileInfo> fileInfoList = new ArrayList<>();
        //保存照片
        fileList.forEach(file -> {
            FileInfo fileInfo = new FileInfo();
            //文件名
            String fileName = file.getOriginalFilename();
            fileInfo.setFileName(fileName);
            if (!"".equals(fileName)) {
                //文件路径
                assert fileName != null;
                //获取后缀
                String suffix = fileName.substring(fileName.lastIndexOf(Constant.POINT));
                fileInfo.setFileFormat(suffix);
                String filePath = filePathBean + IdWorker.getIdStr() + suffix;
                fileInfo.setFilePath(filePath);

                File localFile = new File();
                localFile.setFilePath(filePath);
                localFile.setFileName(fileName);
                localFile.setOtherName(filePath.substring(filePath.lastIndexOf("/") + 1));
                fileInfo.setOtherName(filePath.substring(filePath.lastIndexOf("/") + 1));
                //关联表名称
                localFile.setTableName(tableName);

                localFile.setFileFormat(suffix);
                localFile.setFileSize(new BigDecimal(file.getSize()).divide(BigDecimal.valueOf(1024),1, RoundingMode.HALF_UP) + "KB");
                fileInfo.setFileSize(new BigDecimal(file.getSize()).divide(BigDecimal.valueOf(1024),1, RoundingMode.HALF_UP) + "KB");

                FtpUtil.uploadFile2Ftp(file, filePath);
                this.save(localFile);

                fileInfoList.add(fileInfo);
            }
        });
        return fileInfoList;
    }

    @Override
    public List<String> saveFileList(List<MultipartFile> fileList, String filePathBean) {

        List<String> result = new ArrayList<>();
        //保存照片
        fileList.forEach(file -> {
            //文件名
            String fileName = file.getOriginalFilename();
            if (!"".equals(fileName)) {
                //文件路径
                assert fileName != null;
                String filePath = filePathBean + IdWorker.getIdStr() + fileName.substring(fileName.lastIndexOf(Constant.POINT));
                boolean b = FtpUtil.uploadFile2Ftp(file, filePath);
                if (b) {
                    result.add(filePath);
                } else {
                    throw new BusinessException(Constant.FILE_UPLOAD_ERROR_CODE, Constant.FILE_UPLOAD_ERROR);
                }
            }
        });
        return result;
    }

    @Override
    public String getNewAnnex(String nowAnnex, List<MultipartFile> annexList, String agoAnnex, String path, String tableName) {
        // 获取传入的文件集合
        List<FileInfo> nowAnnexFileInfos = new ArrayList<>();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(nowAnnex)) {
            nowAnnexFileInfos = JSON.parseArray(nowAnnex,FileInfo.class);
        }
        // 获取之前的文件集合
        List<FileInfo> agoAnnexFileInfos = new ArrayList<>();
        if (org.apache.commons.lang3.StringUtils.isNotBlank(agoAnnex)) {
            agoAnnexFileInfos = JSON.parseArray(agoAnnex,FileInfo.class);
        }
        // 保存文件并获得其文件集合
        List<FileInfo> newAnnexFileInfos = new ArrayList<>();
        if (annexList != null && annexList.size() != 0) {
            newAnnexFileInfos = this.saveFileInfoList(annexList, path, tableName);
        }
        // 获取需要删除的文件集合并删除
        List<FileInfo> finalNowAnnexFileInfos = nowAnnexFileInfos;
        List<FileInfo> reduce = agoAnnexFileInfos.stream().filter(item -> !finalNowAnnexFileInfos.contains(item)).collect(Collectors.toList());
        this.removeFileInfoList(reduce);
        // 获取最新的文件集合
        newAnnexFileInfos.addAll(nowAnnexFileInfos);
        return JSON.toJSONString(newAnnexFileInfos);
    }

    @Override
    public Boolean removeFileList(List<Long> fileIdList) {
        List<File> files = this.listByIds(fileIdList);
        // 删除远程文件
        files.forEach(k -> FtpUtil.deleteFile(k.getFilePath()));
        return true;
    }

    @Override
    public Boolean removeFileInfoList(List<FileInfo> fileInfoList) {
        // 删除远程文件
        if (fileInfoList == null || fileInfoList.size() == 0) {
            return true;
        }
        List<String> filePathList = fileInfoList.stream().map(FileInfo::getFilePath).filter(Objects::nonNull).collect(Collectors.toList());
        filePathList.forEach(FtpUtil::deleteFile);
        return true;
    }

    @Override
    public List<String> getFilePathList(List<Long> fileIdList) {
        List<String> filePathList = new ArrayList<>();
        fileIdList.forEach(fileId -> {
                    filePathList.add(this.getById(fileId).getFilePath());
                }

        );
        return filePathList;
    }

    @Override
    public String updateFileList(List<String> nowFilePath, String newFileIds, String tableName) {
        List<Long> resultFileIDList = new ArrayList<>();
        // 获取当前对象中原有文件路径列表
        Map<String, Long> fileMap = this.list(new QueryWrapper<File>().lambda().eq(File::getTableName, tableName)).stream().collect(Collectors.toMap(File::getFilePath, File::getId, ((k, v) -> v)));
        if (StringUtil.isNotEmpty(nowFilePath)) {
            fileMap.forEach((k, v) -> {
                if (nowFilePath.contains(k)) {
                    resultFileIDList.add(v);
                }
            });
        }
        if (StringUtil.isNotEmpty(newFileIds)) {
            List<Long> addFileId = Arrays.stream(newFileIds.split(Constant.CSV)).map(s -> Long.parseLong(s.trim()))
                    .collect(Collectors.toList());
            resultFileIDList.addAll(addFileId);
        }
        StringBuilder stringBuilder = new StringBuilder("");
        resultFileIDList.forEach(info -> {
            stringBuilder.append(info).append(Constant.CSV);
        });
        if (stringBuilder.length() > 0) {
            return stringBuilder.deleteCharAt(stringBuilder.length() - 1).toString();
        }
        return stringBuilder.toString();

    }


}
