package com.zhangmeng.file.service.impl;


import com.zhangmeng.file.config.FileConfig;
import com.zhangmeng.file.dto.ImageInfo;
import com.zhangmeng.file.service.FileInfoService;
import com.zhangmeng.file.service.UploadService;
import com.zhangmeng.file.utils.FastDfsClient;
import com.zhangmeng.file.utils.FileUtil;
import com.zhangmeng.model.dto.FastDfsFileInfo;
import com.zhangmeng.model.entity.FileInfo;
import com.zhangmeng.model.vo.Result;
import com.zhangmeng.model.vo.StatusCode;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.time.LocalDate;
import java.util.Date;
import java.util.Objects;

/**
 * @author zhengmeng
 * @version 1.0
 * @date 2021年1月7日22:32:25
 */
@Service
public class UploadServiceImpl implements UploadService {

    private final static Logger LOGGER = LoggerFactory.getLogger(UploadServiceImpl.class);

    @Autowired
    private FileInfoService fileInfoService;

    @Autowired
    private FileConfig fileConfig;

    @Override
    public Result uploadFile(FileInfo.UploadType type, MultipartFile file) {
        if (file.isEmpty()) {
            return new Result(false, StatusCode.ERROR, "文件未找到,请上传文件");
        }
        String md5 = fileMd5(file);
        FileInfo fileInfo = this.fileInfoService.findByMd5(md5);

        if (fileInfo == null) {
            //判断是否是fastDFS 上传
            switch (fileConfig.getType()) {
                case localhost:
                    break;
                case vmware:
                    fileInfo = fastDFSUpload(type, file, fileInfo);
                    break;
                case aliyun:
                    break;
            }
        }
        return new Result(true, StatusCode.OK, "上传成功", fileInfo);
    }

    /**
     * fastDfs上传
     */
    private FileInfo fastDFSUpload(FileInfo.UploadType type, MultipartFile file, FileInfo fileInfo) {
        fileInfo = getFileInfoByMultipartFile(type, file);
        FastDfsFileInfo dfsFileInfo = convers(file);
        String[] upload = FastDfsClient.upload(dfsFileInfo);
        if (upload != null) {
            String url = FastDfsClient.getTrackerUrl() + "/" + upload[0] + "/" + upload[1];
            //上传成功 封装文件信息
            fileInfo.setSize(file.getSize());
            fileInfo.setPath(url);
            fileInfo.setName(upload[1]);
            fileInfo.setFileSize(FileUtil.getPrintSize(file.getSize()));//字符展示
            //fileInfo.setUser_id(UserUtil.getLoginUser() == null ? 1L : UserUtil.getLoginUser().getId());
            fileInfo.setUploadType(type);
            this.fileInfoService.save(fileInfo);
        }
        return fileInfo;
    }

    private FileInfo getFileInfoByMultipartFile(FileInfo.UploadType type, MultipartFile file) {
        FileInfo fileInfo = new FileInfo();
        fileInfo.setAddTime(new Date());
        fileInfo.setUpdateTime(new Date());
        fileInfo.setDeleteStatus(false);
        try {
            contentType(Objects.requireNonNull(file.getContentType()), fileInfo);
            switch (fileInfo.getUploadType()) {
                case images:
                    BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
                    int width = bufferedImage.getWidth();
                    int height = bufferedImage.getHeight();
                    fileInfo.setImageWidth(width);
                    fileInfo.setImageHeight(height);
                    break;
                case video:
                    break;
                case audio:
                    break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        fileInfo.setUploadType(type);
        return fileInfo;
    }

    private FastDfsFileInfo convers(MultipartFile file) {
        try {
            //封装上传信息
            FastDfsFileInfo dfsFileInfo = new FastDfsFileInfo();
            dfsFileInfo.setContent(file.getBytes());
            dfsFileInfo.setName(file.getOriginalFilename());
            dfsFileInfo.setExt(StringUtils.getFilenameExtension(file.getOriginalFilename()));
            dfsFileInfo.setAuthor("admin");
            return dfsFileInfo;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }



    private ImageInfo bufferedImage(MultipartFile file, FileInfo fileInfo) {
        //图片扩展信息
        ImageInfo imageInfo = FileUtil.parseImgInfo(file);
        //获取图片的宽高
        try {
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            if (bufferedImage != null) {
                int width = bufferedImage.getWidth();
                int height = bufferedImage.getHeight();
                fileInfo.setImageWidth(width);
                fileInfo.setImageHeight(height);
                imageInfo.setImgWidth(String.valueOf(width));
                imageInfo.setImgHeight(String.valueOf(height));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return imageInfo;
    }

    private FileInfo.UploadType contentType(String contentType, FileInfo fileInfo) {
        FileInfo.UploadType uploadType = null;
        FileInfo.FileType fileType = null;
        String[] split = contentType.split("/");
        String type1 = split[0];
        String type2 = split[1];
        switch (type1) {
            case "video":
                uploadType = FileInfo.UploadType.video;
                break;
            case "audio":
                uploadType = FileInfo.UploadType.audio;
                break;
            default:
                uploadType = FileInfo.UploadType.images;
        }
        switch (type2) {
            case "jpeg":
                fileType = FileInfo.FileType.jpeg;
                break;
            case "png":
                fileType = FileInfo.FileType.png;
                break;
            case "bmp":
                fileType = FileInfo.FileType.bmp;
                break;
            case "gif":
                fileType = FileInfo.FileType.gif;
                break;
            case "svg":
                fileType = FileInfo.FileType.svg;
                break;
            default:
                fileType = FileInfo.FileType.jpg;
        }
        fileInfo.setFileType(fileType);
        fileInfo.setUploadType(uploadType);
        return uploadType;
    }

    private String fileMd5(MultipartFile file) {
        try {
            return DigestUtils.md5Hex(file.getInputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String getPath() {
        return "/" + LocalDate.now().toString().replace("-", "/") + "/";
    }
}
