package com.xjrsoft.module.system.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.exif.ExifIFD0Directory;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.xjrsoft.common.exception.MyException;
import com.xjrsoft.common.utils.FileZipUtil;
import com.xjrsoft.common.utils.ImageUtil;
import com.xjrsoft.common.utils.PictureUtil;
import com.xjrsoft.module.oss.factory.OssFactory;
import com.xjrsoft.module.system.entity.File;
import com.xjrsoft.module.system.mapper.FileMapper;
import com.xjrsoft.module.system.service.IFileService;
import com.xjrsoft.module.system.vo.ImageVo;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * <p>
 * 文件关联关系表 服务实现类
 * </p>
 *
 * @author tzx
 * @since 2022-03-08
 */
@Service
public class FileServiceImpl extends MPJBaseServiceImpl<FileMapper, File> implements IFileService {
    private static final Long BYTE_SIZE = 1024 * 200L;

    @Autowired
    private ResourceLoader resourceLoader;

    @Override
    public boolean deleteFile(String encode) {
        return false;
    }

    @Override
    public byte[] downloadFileByZip(Long folderId) {
        List<File> fileList = this.list(Wrappers.<File>query().lambda().eq(File::getFolderId, folderId));

        //声明一个Map，将所有文件装进去，map的key是完整的文件名
        Map<String, byte[]> byteAryMap = new HashMap<>();

        for (int i = 0; i < fileList.size(); i++) {
//            String localFilePath = "C:\\Users\\大数据与最优化研究所\\Downloads\\" + fileList.get(i).getFileName() + fileList.get(i).getFileType();
//            System.err.println(localFilePath);
            try {
                URL url = new URL(fileList.get(i).getFileUrl());
                URLConnection conn = url.openConnection();
                InputStream in = conn.getInputStream();
//                        FileOutputStream fos = new FileOutputStream(localFilePath)
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                byte[] byteArray = outputStream.toByteArray();
                byteAryMap.put(fileList.get(i).getFileName() + fileList.get(i).getFileType(), byteArray);
//                    System.err.println(byteArray.length);
//                    outputStream.writeTo(fos);

//                System.out.println("File downloaded successfully.");
                in.close();
                outputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        //执行下面这段代码就可以拿到压缩之后的byte数组
        return FileZipUtil.byteAryMap2Zip(byteAryMap);
    }

    @Override
    public byte[] downloadFileByZip(List<Long> folderIds) {
        List<File> fileList = this.list(Wrappers.<File>query().lambda().in(File::getFolderId, folderIds));

        //声明一个Map，将所有文件装进去，map的key是完整的文件名
        Map<String, byte[]> byteAryMap = new HashMap<>();

        for (int i = 0; i < fileList.size(); i++) {
//            String localFilePath = "C:\\Users\\大数据与最优化研究所\\Downloads\\" + fileList.get(i).getFileName() + fileList.get(i).getFileType();
//            System.err.println(localFilePath);
            try {
                URL url = new URL(fileList.get(i).getFileUrl());
                URLConnection conn = url.openConnection();
                InputStream in = conn.getInputStream();
//                        FileOutputStream fos = new FileOutputStream(localFilePath)
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = in.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, bytesRead);
                }
                byte[] byteArray = outputStream.toByteArray();
                byteAryMap.put(fileList.get(i).getFileName() + fileList.get(i).getFileType(), byteArray);
//                    System.err.println(byteArray.length);
//                    outputStream.writeTo(fos);

//                System.out.println("File downloaded successfully.");
                in.close();
                outputStream.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        //执行下面这段代码就可以拿到压缩之后的byte数组
        return FileZipUtil.byteAryMap2Zip(byteAryMap);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ImageVo addRubAndHand(MultipartFile file) {
        int anInt = 1;
        try {
            // 读取图片的元数据
            Metadata metadata = ImageMetadataReader.readMetadata(file.getInputStream());
            Directory exifDirectory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
            if (exifDirectory != null) {
                anInt = exifDirectory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
            }
        } catch (Exception e) {
            log.error("读取图片的元数据异常", e);
        }

        // 处理图片，压缩，调转方向
        byte[] fileByte = dealPicture(file, anInt);

        // 上传到服务器
        File savaFile = upLoadPicture(file, fileByte);

        // 将图片转换为base64
        String base64 = ImageUtil.bytesEncode2Base64(fileByte);

        return new ImageVo(){{
            setFolderId(savaFile.getFolderId());
            setBase64(base64);
        }};
    }

    private byte[] dealPicture(MultipartFile file, Integer anInt) {
        byte[] fileByte;
        try {
            byte[] imageBytes = file.getBytes();
            fileByte = ImageUtil.compressUnderSize(imageBytes, BYTE_SIZE);
            InputStream input = new ByteArrayInputStream(fileByte);
            BufferedImage image = ImageIO.read(input);
            BufferedImage rotatedImage = PictureUtil.rotatePhonePhoto(image, anInt);

            fileByte = PictureUtil.convertBufferedImageToByteArray(rotatedImage);
        } catch (Exception e) {
            throw new MyException("图片格式不符");
        }

        if (ObjectUtils.isEmpty(fileByte) || fileByte.length == 0) {
            throw new MyException("图片格式不符");
        }

        return fileByte;
    }

    // 将图片放到服务器上
    private File upLoadPicture(MultipartFile file, byte[] fileByte) {
        Long folderId = IdWorker.getId();
        Long fileId = IdWorker.getId();
        try {
            return uploadFile(file, folderId, fileId, fileByte);
        } catch (Exception e) {
            throw new MyException("图片服务器异常，稍后重试。");
        }
    }

    private File uploadFile(MultipartFile file, Long folderId, Long fileId, byte[] fileByte) throws Exception {
        String filename = file.getOriginalFilename();
        String suffix = filename.substring(filename.lastIndexOf("."));// StringUtils.substringAfterLast(filename, StringPool.DOT);
        //保存到云服务器
        String filePath;
        if (fileByte.length <= 0) {
            throw new RuntimeException("上传文件不能为空");
        } else {
            filePath = Objects.requireNonNull(OssFactory.build()).uploadSuffix(fileByte, suffix);
        }
//        String filePath = UploadUtil.uploadFile(file);

        File fileEntity = new File();
        fileEntity.setId(fileId);
        fileEntity.setFolderId(folderId);
        fileEntity.setFileName(filename);
        fileEntity.setFileUrl(filePath);
        fileEntity.setFileSize(file.getSize());
        fileEntity.setFileSuffiex(StringPool.DOT + suffix);
        fileEntity.setFileType(suffix);

//        if (GlobalConstant.imageType.contains(StringUtils.lowerCase(suffix.replace(StringPool.DOT, StringPool.EMPTY)))) {
//            String thSuffix = StringPool.DOT + ImgUtil.IMAGE_TYPE_JPEG;
//
//            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//            ImgUtil.scale(file.getInputStream(), outputStream, 200, 200, null);
//
//            byte[] thBytes = outputStream.toByteArray();
//
//            String thUrl = Objects.requireNonNull(OssFactory.build()).uploadSuffix(thBytes, StringPool.DOT + ImgUtil.IMAGE_TYPE_JPEG);
//            outputStream.close();
//
//            fileEntity.setThUrl(thUrl);
//            fileEntity.setThType(thSuffix);
//            fileEntity.setThName(file.getOriginalFilename().replace(suffix, StringPool.EMPTY) + "-缩略图");
//            fileEntity.setThSize(Convert.toLong(thBytes.length));
//        }
        this.baseMapper.insert(fileEntity);
        return fileEntity;
    }

}
