package com.yiboshi.science.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yiboshi.arch.exception.BusinessException;
import com.yiboshi.science.base.BaseServiceImpl;
import com.yiboshi.science.base.Pagination;
import com.yiboshi.science.dao.ComDownloadDAO;
import com.yiboshi.science.entity.ComDownload;
import com.yiboshi.science.enumeration.CommonEnum;
import com.yiboshi.science.param.dto.ComDownloadDTO;
import com.yiboshi.science.param.query.ComDownloadQueryVO;
import com.yiboshi.science.service.ComDownloadService;
import com.yiboshi.science.service.SystemSetService;
import com.yiboshi.science.utils.SystemSetKey;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * 附件表 Service 实现类
 *
 * @author lkl
 * @version 2021-08-25
 */
@Service
public class ComDownloadServiceImpl extends BaseServiceImpl<ComDownloadDAO, ComDownloadQueryVO, ComDownloadDTO, ComDownload> implements ComDownloadService {

    @Autowired
    private ComDownloadDAO comDownloadDAO;

    @Autowired
    private SystemSetService systemSetService;

    @Override
    protected void setCriteriaForQuery(ComDownloadQueryVO vo, QueryWrapper<ComDownloadQueryVO> criteria) {
        if (Objects.nonNull(vo.getAppNo())) {
            criteria.eq("app_no", vo.getAppNo());
        }
        if (Objects.nonNull(vo.getProjNo())) {
            criteria.like("proj_no", vo.getProjNo());
        }
        if (Objects.nonNull(vo.getProjName())) {
            criteria.like("proj_name", vo.getProjName());
        }
        if (Objects.nonNull(vo.getReportYear())) {
            criteria.eq("report_year", vo.getReportYear());
        }
        if (Objects.nonNull(vo.getProjState())) {
            switch (vo.getProjState()) {
                case 1:
                    criteria.in("proj_state",
                            CommonEnum.projState.draft.getCode(),
                            CommonEnum.projState.waitSubmit.getCode());
                    break;
                case 2:
                    criteria.eq("proj_state", CommonEnum.projState.returnModify.getCode());
                    break;
                case 3:
                    criteria.in("proj_state",
                            CommonEnum.projState.toAudit.getCode(),
                            CommonEnum.projState.failed.getCode(),
                            CommonEnum.projState.pass.getCode(),
                            CommonEnum.projState.report.getCode(),
                            CommonEnum.projState.conclusion.getCode());
                    break;
                case 4:
                    break;
                case 5:
                    criteria.ge("proj_state", CommonEnum.projState.pass.getCode());
                    break;
                case 6:
                    criteria.ge("proj_state", CommonEnum.projState.report.getCode());
                    break;
                default:
                    criteria.eq("proj_state", vo.getProjState());
                    break;
            }
        }
        if (Objects.nonNull(vo.getDownloadUrl())) {
            criteria.eq("download_url", vo.getDownloadUrl());
        }
        if (Objects.nonNull(vo.getFileName())) {
            criteria.eq("file_name", vo.getFileName());
        }
        if (Objects.nonNull(vo.getExtension())) {
            criteria.eq("extension", vo.getExtension());
        }
    }

    public ComDownload asyncUpload(MultipartFile file) {
        if (null == file) {
            throw new BusinessException("文件不能为空");
        }
        if (!file.isEmpty()) {
            String filename = file.getOriginalFilename();
            try {
                //处理获取到的上传文件的文件名的路径部分，只保留文件名部分
                filename = filename.substring(filename.lastIndexOf("\\") + 1);
                //得到上传文件的扩展名
                String fileExtName = filename.substring(filename.lastIndexOf(".") + 1);
                String filePath = getFilePath(systemSetService.getByKey(SystemSetKey.SysUploadFilePath));
                //判断文件目录是否存在，否则自动生成
                File savePath = new File(getPhysicalPath(filePath));
                if (!savePath.exists()) {
                    savePath.mkdirs();
                }
                String newFileName = UUID.randomUUID().toString() + "." + fileExtName;
                InputStream in = file.getInputStream();
                FileOutputStream out = new FileOutputStream(savePath + "/" + newFileName);
                //创建一个缓冲区
                byte buffer[] = new byte[1024];
                //判断输入流中的数据是否已经读完的标识
                int len = 0;
                //循环将输入流读入到缓冲区当中，(len=in.read(buffer))>0就表示in里面还有数据
                while ((len = in.read(buffer)) > 0) {
                    //使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
                    out.write(buffer, 0, len);
                }
                //关闭输入流
                in.close();
                //关闭输出流
                out.close();
                ComDownload comDownload = new ComDownload();
                comDownload.setDownloadUrl(filePath + newFileName);
                comDownload.setFileName(filename);
                comDownload.setExtension(fileExtName);
                this.insert(comDownload);
                return comDownload;
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException(e);
            }
        }
        throw new BusinessException("文件上传失败！");
    }

    public ComDownload asyncApplyBookUpload(MultipartFile file) {
        ComDownload entity = this.asyncUpload(file);

        ComDownload applyBookFile = this.getDownloadByFileName(file.getOriginalFilename().replace(".pdf", ".doc"));
        if (null != applyBookFile) {
            applyBookFile.setConvertUrl(entity.getDownloadUrl());
            this.update(applyBookFile);
        }
        return applyBookFile;
    }

    public ComDownload getDownloadByFileName(String fileName) {
        return comDownloadDAO.getDownloadByFileName(fileName);
    }

    public String delete(String id) {
        ComDownload comDownload =this.getById(id);
        if(null!=comDownload){
            String path=getPhysicalPath(comDownload.getDownloadUrl());
            File file = new File(path);
            if(file.exists()){
                file.delete();
            }
            this.deleteById(id);
        }
        return id;
    }

    public String getDirectorySize(){
        String property = System.getProperty("user.dir").replace("\\", "/");
        String basePath = systemSetService.getByKey(SystemSetKey.SysUploadFilePath);
        long size = FileUtils.sizeOfDirectory(new File( property + basePath));
        return formatSize(size);
    }

    private String formatSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    /**
     * 获取相对路劲
     *
     * @param basePath
     * @return
     */
    public String getFilePath(String basePath) {
        if (null != basePath && "" != basePath) {
            Calendar rightNow = Calendar.getInstance();
            Integer year = rightNow.get(Calendar.YEAR);
            //第一个月从0开始，所以得到月份＋1
            Integer month = rightNow.get(Calendar.MONTH) + 1;
            // Integer day = rightNow.get(rightNow.DAY_OF_MONTH);
            return basePath + year + "/" + month + "/";
        }
        return "";
    }

    /**
     * 获取物理路劲
     *
     * @param filePath
     * @return
     */
    public String getPhysicalPath(String filePath) {
        String savePath = System.getProperty("user.dir") + filePath;
        return savePath;
    }

    public ComDownloadDTO convertEntity2DTO(ComDownload entity) {
        return this.convert2DTO(entity);
    }

    public Pagination<ComDownloadDTO> getAllListByPage(ComDownloadQueryVO vo) {
        QueryWrapper criteria = new QueryWrapper();
        setCriteriaForQuery(vo, criteria);
        Page<ComDownloadQueryVO> page = new Page<>(vo.getPageIndex(), vo.getPageSize());
        List<ComDownloadDTO> dtoList = comDownloadDAO.getAllListByPage(page, criteria).getRecords();
        return new Pagination<>(dtoList, page.getTotal(), vo.getPageSize());
    }
}
