package com.tofly.feesapi.file.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tofly.common.core.util.StringUtil;
import com.tofly.feesapi.file.entity.File;
import com.tofly.feesapi.file.entity.dto.FileUploadBase64Dto;
import com.tofly.feesapi.file.entity.dto.FileUploadResponse;
import com.tofly.feesapi.file.entity.vo.InfoFile;
import com.tofly.feesapi.file.mapper.FileMapper;
import com.tofly.feesapi.file.fileconfiguration.FileStorageService;

import com.tofly.feesapi.file.service.IFileInfoService;
import com.tofly.feesapi.security.util.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;


@Slf4j
@Service
public class FileInfoServiceImpl extends ServiceImpl<FileMapper, File> implements IFileInfoService {

    @Autowired
    private FileMapper fileMapper;
    @Autowired
    private FileStorageService fileStorageService;

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

    @Override
    public List<File> getFileList(List<BigDecimal> fileIdList) {
        QueryWrapper<File> wrapper = new QueryWrapper();
        wrapper.lambda().in(fileIdList.size() > 0, File::getFileBh, fileIdList);
        return this.list(wrapper);
    }

    @Override
    public List<File> getFileList(LambdaQueryWrapper<File> queryWrapper) {
        return this.list(queryWrapper);
    }

    @Override
    public Page getFileList(Page page, String tableName, String tableIds) {
        return page.setRecords(fileMapper.getFileList(page, tableName, tableIds));
    }

    public StringBuilder savafile(HttpServletRequest servletRequest, String filePathBean, String tableID, String tableName) {
        MultiValueMap<String, MultipartFile> multipartFileMap = ((MultipartHttpServletRequest) servletRequest).getMultiFileMap();
        StringBuilder fileIds = new StringBuilder("");
        if (multipartFileMap.size() > 0) {
            AtomicInteger i = new AtomicInteger();
            multipartFileMap.forEach((k, v) -> {
                v.forEach(f -> {
                    FileUploadResponse fileUploadResponse = fileStorageService.upload(f, filePathBean);
                    File localFile = new File();
                    localFile.setFileNewFn(fileUploadResponse.getFileName());
                    localFile.setFileOldFn(f.getOriginalFilename());
                    //关联表名称
                    localFile.setTableBh(tableID);
                    localFile.setTableName(tableName);
                    localFile.setFileXh(String.valueOf(i.addAndGet(1)));

                    localFile.setFileSize(f.getSize());

                    localFile.setCzsj(new Date());
                    this.save(localFile);
                    fileIds.append(localFile.getFileBh()).append(",");
                });
            });
        }
        return fileIds;
    }


    public String savafileBase64(FileUploadBase64Dto file, String filePathBean, String tableID, String tableName) {
        if (file == null || StringUtil.isBlank(file.getBase64String())) {
            return "";
        }
        FileUploadResponse fileUploadResponse = fileStorageService.uploadFileBase64(file, filePathBean);
        File localFile = new File();
        String fileName = file.getOriginalFilename();
        localFile.setFileNewFn(fileUploadResponse.getFileName());
        localFile.setFileOldFn(fileName);
        //关联表名称
        localFile.setTableBh(tableID);
        localFile.setTableName(tableName);
        localFile.setFileSize(fileUploadResponse.getSize());
        localFile.setCzsj(new Date());
        this.save(localFile);
        return localFile.getFileBh();
    }


    /*
     *工程与地灾使用
     */
    public StringBuilder gcsavafile(HttpServletRequest servletRequest, List<InfoFile> infoFileList) {
        StringBuilder fileIds = new StringBuilder("");
        infoFileList.forEach(r -> {
            fileIds.append(gcsavafile(servletRequest, r));
        });
        return fileIds;
    }


    public StringBuilder gcsavafile(HttpServletRequest servletRequest, InfoFile infoFile) {
        MultiValueMap<String, MultipartFile> multipartFileMap = ((MultipartHttpServletRequest) servletRequest).getMultiFileMap();
        StringBuilder fileIds = new StringBuilder("");
        if (multipartFileMap.size() > 0) {
            AtomicInteger i = new AtomicInteger();
            multipartFileMap.forEach((k, v) -> {
                if (k.equals(infoFile.getName())) {
                    v.forEach(f -> {
                        String fileName = f.getOriginalFilename();
                        FileUploadResponse fileUploadResponse = fileStorageService.upload(f, infoFile.getFilePathBean());
                        File localFile = new File();
                        localFile.setFileNewFn(fileUploadResponse.getFileName());
                        localFile.setFileOldFn(fileName);
                        //关联表名称
                        localFile.setTableBh(infoFile.getTableID());
                        localFile.setTableName(infoFile.getTableName());
                        localFile.setFileXh(String.valueOf(i.addAndGet(1)));

                        localFile.setFileSize(f.getSize());
                        localFile.setCzsj(new Date());
                        this.save(localFile);
                        fileIds.append(localFile.getFileBh()).append(",");
                    });
                }
            });
        }
        return fileIds;
    }

    public List<File> savafile(HttpServletRequest servletRequest, String filePathBean) {
        MultiValueMap<String, MultipartFile> multipartFileMap = ((MultipartHttpServletRequest) servletRequest).getMultiFileMap();
        List<File> fileList = new ArrayList<>();

        if (multipartFileMap.size() > 0) {
            AtomicInteger i = new AtomicInteger();
            multipartFileMap.forEach((k, v) -> {
                //web端所有文件
                v.forEach(f -> {
                    FileUploadResponse fileUploadResponse = fileStorageService.upload(f, filePathBean);
                    File localFile = new File();
                    localFile.setFileNewFn(fileUploadResponse.getFileName());
                    localFile.setFileOldFn(f.getOriginalFilename());
                    //关联表名称
                    localFile.setTableBh("0");
                    localFile.setTableName("other");
                    localFile.setFileXh(String.valueOf(i.addAndGet(1)));
                    localFile.setFileSize(f.getSize());
                    localFile.setCzsj(new Date());
                    //localFile.setCreateUser();
                    this.save(localFile);
                    fileList.add(localFile);
                });
            });
        }
        return fileList;
    }


    public File saveFile(MultipartFile file, String filePathBean, String tableID, String tableName) {
        String fileName = file.getOriginalFilename();
        FileUploadResponse fileUploadResponse = fileStorageService.upload(file, filePathBean);
        File localFile = new File();
        localFile.setFileNewFn(fileUploadResponse.getFileName());
        localFile.setFileOldFn(fileName);
        //关联表名称
        localFile.setTableBh(tableID);
        localFile.setTableName(tableName);
        localFile.setFileSize(fileUploadResponse.getSize());
        localFile.setCzsj(new Date());
        this.save(localFile);

        return localFile;
    }

    public StringBuilder saveFileList(List<MultipartFile> fileList, String filePath, String tableID, String tableName,String notice) {

        StringBuilder fileIds = new StringBuilder("");
        AtomicInteger i = new AtomicInteger();

        fileList.forEach(f -> {
            String fileName = f.getOriginalFilename();
            FileUploadResponse fileUploadResponse = fileStorageService.upload(f, filePath);
            File localFile = new File();
            localFile.setFileNewFn(fileUploadResponse.getFileName());
            localFile.setFileOldFn(fileName);
            //关联表名称
            localFile.setTableBh(tableID);
            localFile.setTableName(tableName);
            localFile.setFileXh(String.valueOf(i.addAndGet(1)));
            localFile.setFileNote(notice);
            localFile.setFileSize(fileUploadResponse.getSize());
            localFile.setCzsj(new Date());
            this.save(localFile);
            fileIds.append(localFile.getTableBh()).append(",");
        });

        return fileIds;
    }

    public StringBuilder saveFileList(List<MultipartFile> fileList, String filePathBean, String tableID, String tableName) {
        return  saveFileList(fileList, filePathBean, tableID, tableName,"");
    }

    public StringBuilder saveFileList(List<MultipartFile> fileList, String filePathBean, String tableID, String tableName, String yhbh, String notice) {

        StringBuilder fileIds = new StringBuilder("");
        AtomicInteger i = new AtomicInteger();

        fileList.forEach(f -> {
            String fileName = f.getOriginalFilename();
            FileUploadResponse fileUploadResponse = fileStorageService.upload(f, filePathBean);
            File localFile = new File();
            localFile.setFileNewFn(fileUploadResponse.getFileName());
            localFile.setFileOldFn(fileName);
            //关联表名称
            localFile.setTableBh(tableID);
            localFile.setTableName(tableName);
            localFile.setFileXh(String.valueOf(i.addAndGet(1)));
            localFile.setFileNote(notice);
            //获取后缀
//        String suffix = fileName.substring(fileName.lastIndexOf("."));
//        localFile.setFileFormat(suffix);
            localFile.setFileSize(fileUploadResponse.getSize());
//        localFile.setOtherName(fileUploadResponse.getFileName().replace(filePathBean, ""));
//        localFile.setStatusFlag("0");
            localFile.setCzsj(new Date());
            localFile.setCzry(SecurityUtils.getUserId().toString());
            localFile.setCzryName(SecurityUtils.getUserName());
            //localFile.setYhbh(yhbh);
            //localFile.setCreateUser();
            this.save(localFile);
            fileIds.append(localFile.getTableBh()).append(",");
        });

        return fileIds;
    }

    @Override
    public Boolean removeFileListById(List<String> fileIdList) {
        if (fileIdList.size() > 0) {
            List<File> files = this.listByIds(fileIdList);
            // 删除远程文件
            files.forEach(k -> {
                try {
                    fileStorageService.removeFile(k.getFileNewFn());
                } catch (IOException e) {
                    log.info(e.getMessage());
                    throw new RuntimeException(e);
                }
            });
            return this.removeByIds(fileIdList);
        }
        return false;
    }

    @Override
    public Boolean removeFileListByFile(List<File> fileList) {
        if (fileList.size() > 0) {
            // 删除远程文件
            List<String> idslist = new ArrayList<>();
            fileList.forEach(k -> {
                try {
                    idslist.add(k.getFileBh());
                    fileStorageService.removeFile(k.getFileNewFn());
                } catch (IOException e) {
                    log.info(e.getMessage());
                    throw new RuntimeException(e);
                }
            });
            return this.removeByIds(idslist);
        }
        return false;
    }

    @Override
    public void removeFileListByTableId(String tableId, String tableName) {
        LambdaQueryWrapper<File> queryWrapper = Wrappers.lambdaQuery(File.class)
                .eq(File::getTableBh, tableId)
                .eq(File::getTableName, tableName);
        List<File> list = this.list(queryWrapper);
        this.removeFileListByFile(list);
    }

    /**
     * file转 MultipartFile
     */
    @Override
    public  MultipartFile convertFileToMultipartFileFile(java.io.File file) throws IOException {
        FileInputStream input = new FileInputStream(file);
        MultipartFile multipartFile = new MockMultipartFile("file",
                file.getName(), "text/plain", input);
        return multipartFile;
    }

}
