package com.mortals.xhx.base.system.upload.service.impl;

import cn.hutool.core.io.FileUtil;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.service.IUser;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.base.system.upload.service.UploadService;
import com.mortals.xhx.common.code.UploadFileType;
import lombok.Getter;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;

/**
 * <p>Title: 上传文件</p>
 * <p>Description: UploadServiceImpl service接口 </p>
 * <p>Copyright: Copyright &reg;  </p>
 * <p>Company: </p>
 *
 * @author
 * @version 1.0.0
 */
@Service("uploadfileService")
public class UploadServiceImpl implements UploadService {

    private static Log log = LogFactory.getLog(UploadServiceImpl.class);

    @Value("${upload.path}")
    @Getter
    private String filePath;



    @Override
    public String saveFileUpload(MultipartFile tempFile, String prePath, IUser user) {
        if (tempFile == null || tempFile.getSize() == 0) {
            throw new AppException("没有要上传的文件！");
        }

        String fileName = tempFile.getOriginalFilename();
        String extension = FilenameUtils.getExtension(fileName);
        UploadFileType type = UploadFileType.getFileType(extension);
        if (type.getMaxSize() != 0 && tempFile.getSize() > type.getMaxSize()) {
            log.error("文件上传大小超过限制，当前文件---" + tempFile.getSize() + "，允许大小----------" + type.getMaxSize());
            throw new AppException("文件上传大小超过限制！");
        }
        if (null != fileName && fileName.length() > 120) {
            throw new AppException("文件名称过长，无法上传！");
        }

        String rootPath = this.filePath.endsWith("/") ? this.filePath : this.filePath + "/";
        String filePath = rootPath + (StringUtils.isEmpty(prePath) ? "" : prePath + "/");
        File pathDir = new File(filePath);
        if (!pathDir.exists()) {
            pathDir.mkdirs();
        }
        String newName = new Date().getTime() + "." + extension;
        String filePathAll = filePath + newName;

        File uploadFile = new File(filePathAll);
        try {
            log.info("文件正在储存，filepath:"+filePathAll);
            tempFile.transferTo(uploadFile);
        } catch (Exception e) {
            throw new AppException(e.getMessage());
        }

        return (StringUtils.isEmpty(prePath) ? "" : prePath + "/") + newName;
    }

    @Override
    public String getFilePath(String path) {
        String filePath = this.filePath.endsWith("/") ? this.filePath : this.filePath + "/";
        return filePath + path;
    }

    @Override
    public void fileDownload(String fileName, Boolean delete, HttpServletResponse response) {
        String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
        String filePath = this.filePath + fileName;
        try {
            response.setContentType(MediaType.IMAGE_JPEG_VALUE);
            setAttachmentResponseHeader(response, realFileName);
            FileUtil.writeToStream(filePath, response.getOutputStream());

        } catch (Exception e) {
            log.error("下载文件失败", e);
        }
    }

    @Override
    public void preview(String fileName, HttpServletResponse response) {
        String filePath = this.filePath+"/file/preview/" + fileName;
        try {
            response.setContentType(MediaType.IMAGE_JPEG_VALUE);
            setAttachmentResponseHeader(response, fileName);
            FileUtil.writeToStream(filePath, response.getOutputStream());
        } catch (Exception e) {
            log.error("下载文件失败", e);
        }
    }


    /**
     * 下载文件名重新编码
     *
     * @param response 响应对象
     * @param realFileName 真实文件名
     * @return
     */
    public  void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
    {
        String percentEncodedFileName = percentEncode(realFileName);

        StringBuilder contentDispositionValue = new StringBuilder();
        contentDispositionValue.append("attachment; filename=")
                .append(percentEncodedFileName)
                .append(";")
                .append("filename*=")
                .append("utf-8''")
                .append(percentEncodedFileName);

        response.setHeader("Content-disposition", contentDispositionValue.toString());
    }

    /**
     * 百分号编码工具方法
     *
     * @param s 需要百分号编码的字符串
     * @return 百分号编码后的字符串
     */
    public  String percentEncode(String s) throws UnsupportedEncodingException
    {
        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
        return encode.replaceAll("\\+", "%20");
    }


    @Override
    public void uploadDownload(String fileName, HttpServletResponse response) {
        String filePath = this.filePath+ fileName;
        try {
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            setAttachmentResponseHeader(response, fileName);
            FileUtil.writeToStream(filePath, response.getOutputStream());
        } catch (Exception e) {
            log.error("下载文件失败", e);
        }
    }

    @Override
    public void deleteFile(String fileName) {
        String filePath = this.filePath+ fileName;
        try {
            FileUtil.del(filePath);
        } catch (Exception e) {
            log.error("下载文件失败", e);
        }
    }

}