package com.sqx.modules.file;

import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.sqx.common.exception.SqxException;
import com.sqx.common.utils.Result;
import com.sqx.config.MinioConfig;
import com.sqx.modules.common.service.CommonInfoService;
import com.sqx.modules.file.utils.FileUploadUtils;
import icu.xuyijie.secureapi.annotation.DecryptParam;
import io.minio.MinioClient;
import io.minio.ObjectWriteResponse;
import io.minio.PutObjectArgs;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.util.IOUtils;
import org.jaudiotagger.audio.AudioFileIO;
import org.jaudiotagger.audio.mp3.MP3AudioHeader;
import org.jaudiotagger.audio.mp3.MP3File;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.util.ClassUtils;
import org.springframework.util.StreamUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.*;
import java.net.URLDecoder;
import java.nio.file.Files;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;

/**
 * 阿里云文件上传
 * @author fang
 * @date 2020/7/13
 */
@Slf4j
@Api(value = "阿里云文件上传", tags = {"阿里云文件上传"})
@RestController
@RequestMapping(value = "/alioss")
@RequiredArgsConstructor
public class AliFileUploadController {

    private final CommonInfoService commonRepository;
    private final MinioClient minioClient;
    private final MinioConfig minioConfig;

    @RequestMapping(value = "/upload", method = RequestMethod.POST)
    @ApiOperation("文件上传")
    @ResponseBody
    public Result upload(@DecryptParam("file") MultipartFile file){
        String value = commonRepository.findOne(234).getValue();
        if("1".equals(value)){
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(commonRepository.findOne(68).getValue(), commonRepository.findOne(69).getValue(), commonRepository.findOne(70).getValue());
            String suffix = file.getOriginalFilename().substring(Objects.requireNonNull(file.getOriginalFilename()).lastIndexOf("."));
            // 上传文件流。
            InputStream inputStream = null;
            try {
                inputStream =new ByteArrayInputStream(file.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
            String completePath=getPath(suffix);
            ossClient.putObject(commonRepository.findOne(71).getValue(), completePath, inputStream);
            // 关闭OSSClient。
            ossClient.shutdown();
            String src = commonRepository.findOne(72).getValue()+"/"+completePath;
            // String src = commonRepository.findOne(19).getValue()+"/img/"+completePath;
            return Result.success().put("data",src);
        } else if (StrUtil.equals(value, "3")) {
            // Minio上传
            String suffix = file.getOriginalFilename().substring(Objects.requireNonNull(file.getOriginalFilename()).lastIndexOf("."));
            String completePath = getPath(suffix);
//            long fileSize =file.getSize();
            try {
                //图片压缩webp
//                InputStream inputStream=file.getInputStream();
//                if(this.isPicture(suffix)&&file.getSize()>1024*1024*2){
//                    completePath=getPath(".webp");
//                    String tmpPath =UUID.randomUUID().toString().replaceAll("-", "")+".webp";
//                    ApplicationHome applicationHome = new ApplicationHome(AliFileUploadController.class);
//                    String pathResouce = applicationHome.getDir().getParentFile().getParentFile().getAbsolutePath();
//                    String decode = URLDecoder.decode(pathResouce, "utf-8");
//                    File newFile = new File(decode + tmpPath);
//                    ImageOutputStream  ios=null;
//                    try {
//                        BufferedImage image = ImageIO.read(inputStream);
//                        ImageWriter writer = ImageIO.getImageWritersByMIMEType("image/webp").next();
//                        WebPWriteParam writeParam = new WebPWriteParam(writer.getLocale());
//                        writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
//                        // 设置有损压缩
//                        writeParam.setCompressionType(writeParam.getCompressionTypes()[WebPWriteParam.LOSSY_COMPRESSION]);
//                        //设置 80% 的质量. 设置范围 0-1
//                        writeParam.setCompressionQuality(0.8f);
//                        // Save the image
//                        ios =ImageIO.createImageOutputStream(newFile);
//                        writer.setOutput(ios);
//                        writer.write(null, new IIOImage(image, null, null), writeParam);
//                        writer.dispose();
//                        ios.close();
//                        minioClient.putObject(PutObjectArgs.builder()
//                                .bucket(minioConfig.getBucket())
//                                .object(completePath)
//                                .stream(Files.newInputStream(newFile.toPath()), newFile.length(), -1)
//                                .build());
//                        inputStream.close();
//                        delteTempFile(newFile);
//                        String src = commonRepository.findOne(72).getValue() + "/" + completePath;
//                        return Result.success().put("data", src);
//                    } catch (IOException e) {
//                        throw new RuntimeException(e);
//                    }finally {
//                        try {
//                            if(inputStream!=null){
//                                inputStream.close();
//                            }
//                            if(ios!=null){
//                                ios.close();
//                            }
//                        } catch (IOException e) {
//                            log.info(e.getMessage());
//                        }
//                    }
//                }
                minioClient.putObject(PutObjectArgs.builder()
                        .bucket(minioConfig.getBucket())
                        .object(completePath)
                        .stream(file.getInputStream(), file.getSize(), -1)
                        .build());

                String src = commonRepository.findOne(72).getValue() + "/" + completePath;
                return Result.success().put("data", src);
            } catch (Exception e) {
                throw new SqxException("文件上传失败!");
            }
        } else{
            try
            {
                String http = commonRepository.findOne(19).getValue();
                String[] split = http.split("://");
                // 上传文件路径
                String filePath ="/mydata/project/media/"+split[1]+"/file/uploadPath";
                // 上传并返回新文件名称
                String fileName = FileUploadUtils.upload(filePath, file);
                String url = http +fileName;
                return Result.success().put("data",url);
            }
            catch (Exception e)
            {
                log.error("本地上传失败："+e.getMessage(),e);
                return Result.error(-100,"文件上传失败！");
            }
        }

    }

    @RequestMapping(value = "/uploadUniApp", method = RequestMethod.POST)
    @ApiOperation("文件上传")
    @ResponseBody
    public String uploadUniApp(@DecryptParam("file") MultipartFile file){
        String value = commonRepository.findOne(234).getValue();
        if("1".equals(value)){
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(commonRepository.findOne(68).getValue(), commonRepository.findOne(69).getValue(), commonRepository.findOne(70).getValue());
            String suffix = file.getOriginalFilename().substring(Objects.requireNonNull(file.getOriginalFilename()).lastIndexOf("."));
            // 上传文件流。
            InputStream inputStream = null;
            try {
                inputStream =new ByteArrayInputStream(file.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
            String completePath=getPath(suffix);
            ossClient.putObject(commonRepository.findOne(71).getValue(), completePath, inputStream);
            // 关闭OSSClient。
            ossClient.shutdown();

            String src = commonRepository.findOne(72).getValue()+"/"+completePath;
            // String src = commonRepository.findOne(19).getValue()+"/img/"+completePath;

            return src;
        }else{
            try
            {
                String http = commonRepository.findOne(19).getValue();
                String[] split = http.split("://");
                // 上传文件路径
                String filePath ="/mydata/project/media/"+split[1]+"/file/uploadPath";
                // 上传并返回新文件名称
                String fileName = FileUploadUtils.upload(filePath, file);
                String url = http +fileName;
                return url;
            }
            catch (Exception e)
            {
                log.error("本地上传失败："+e.getMessage(),e);
                return null;
            }
        }

    }

    @RequestMapping(value = "/uploadMusic", method = RequestMethod.POST)
    @ApiOperation("文件上传")
    @ResponseBody
    public Result uploadMusic(@DecryptParam("file") MultipartFile file) {
        String url="";
        String value = commonRepository.findOne(234).getValue();
        if("1".equals(value)){
            // 创建OSSClient实例。
            OSS ossClient = new OSSClientBuilder().build(commonRepository.findOne(68).getValue(), commonRepository.findOne(69).getValue(), commonRepository.findOne(70).getValue());
            String suffix = file.getOriginalFilename().substring(Objects.requireNonNull(file.getOriginalFilename()).lastIndexOf("."));
            // 上传文件流。
            InputStream inputStream = null;
            try {
                inputStream =new ByteArrayInputStream(file.getBytes());
            } catch (IOException e) {
                e.printStackTrace();
            }
            String completePath=getPath(suffix);
            ossClient.putObject(commonRepository.findOne(71).getValue(), completePath, inputStream);
            // 关闭OSSClient。
            ossClient.shutdown();

            url = commonRepository.findOne(72).getValue()+"/"+completePath;
            // url = commonRepository.findOne(19).getValue()+"/img/"+completePath;
        }else{
            try
            {
                String http = commonRepository.findOne(19).getValue();
                String[] split = http.split("://");
                // 上传文件路径
                String filePath ="/mydata/project/media/"+split[1]+"/file/uploadPath";
                // 上传并返回新文件名称
                String fileName = FileUploadUtils.upload(filePath, file);
                url = http +fileName;
            }
            catch (Exception e)
            {
                log.error("本地上传失败："+e.getMessage(),e);
                return null;
            }
        }
        if("/".equals(url.substring(url.length()-1,url.length()))){
            url=url.substring(0,url.length()-1);
        }
        int trackLength=0;
        try {
            File file1 = multipartFileToFile(file);
            MP3File f = (MP3File) AudioFileIO.read(file1);
            MP3AudioHeader audioHeader = (MP3AudioHeader)f.getAudioHeader();
            trackLength = audioHeader.getTrackLength();
            delteTempFile(file1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        Map<String,Object> result=new HashMap<>();
        result.put("url",url);
        result.put("sec",trackLength);
        return Result.success().put("data",result );
    }


    /**
     * MultipartFile 转 File
     *
     * @param file
     * @throws Exception
     */
    public static File multipartFileToFile(MultipartFile file) throws Exception {

        File toFile = null;
        if (file.equals("") || file.getSize() <= 0) {
            file = null;
        } else {
            InputStream ins = null;
            ins = file.getInputStream();
            toFile = new File(file.getOriginalFilename());
            inputStreamToFile(ins, toFile);
            ins.close();
        }
        return toFile;
    }

    //获取流文件
    private static void inputStreamToFile(InputStream ins, File file) {
        try {
            OutputStream os = new FileOutputStream(file);
            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            ins.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除本地临时文件
     * @param file
     */
    public static void delteTempFile(File file) {
        if (file != null) {
            File del = new File(file.toURI());
            del.delete();
        }
    }

    private String getPath(String suffix) {
        //生成uuid
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        //文件路径
        String path =format(new Date()) + "/" + uuid;
        return path + suffix;
    }


    private String format(Date date) {
        if(date != null){
            SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
            return df.format(date);
        }
        return null;
    }
    /**
     * 判断文件是否为图片
     */
    public boolean isPicture(String imgName) {
        boolean flag = false;
        if (StringUtils.isBlank(imgName)) {
            return false;
        }
        String[] arr = {".bmp", ".dib", ".gif", ".jfif", ".jpe", ".jpeg", ".jpg", ".png", ".tif", ".tiff", ".ico"};
        for (String item : arr) {
            if (item.equals(imgName)) {
                flag = true;
                break;
            }
        }
        return flag;
    }


}