package cn.wisenergy.service.app.impl;

import cn.wisenergy.common.utils.FileException;
import cn.wisenergy.common.utils.FileUtils;
import cn.wisenergy.common.utils.FrameGrabberKit;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import cn.wisenergy.service.app.UploadService;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import cn.wisenergy.mapper.ShopZxMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ClassUtils;


/**
 * Created by m1991 on 2021/2/24 13:42
 */
@Slf4j
@Transactional
@Service
public class UploadServiceImpl implements UploadService {

    @Autowired
    private ShopZxMapper shopZxMapper;

        /**
         * 视频文件上传
         */
        @Override
        public Map<String, Object> uploadVideo(MultipartFile file,HttpServletRequest request,String userId,String zxField,String zxAddress) throws Exception {
            Map<String, Object> resultMap=new HashMap<String, Object>();

            String basePath = request.getScheme() + "://" + request.getServerName()
                    + ":" + request.getServerPort()+"/mimi/upload/video/";

            Long time = System.currentTimeMillis();

            String zxName = file.getOriginalFilename();//文件原始名称
            String suffixName = zxName.substring(zxName.lastIndexOf("."));//从最后一个.开始截取。截取zxName的后缀名
            String newzxName = time+suffixName; //文件新名称
            //设置文件存储路径，可以存放在你想要指定的路径里面
            String rootPath="D:/mimi/"+File.separator+"upload/video/"; //上传视频存放位置

            String filePath = rootPath+newzxName;

            File newFile = new File(filePath);


            //判断目标文件所在目录是否存在
            if(!newFile.getParentFile().exists()){
                //如果目标文件所在的目录不存在，则创建父目录
                newFile.getParentFile().mkdirs();
            }

            //将内存中的数据写入磁盘
            file.transferTo(newFile);
            //视频上传保存url
            String zxUrl = basePath + newzxName;

            //视频封面图处理
            String newImgName = time+".jpg";
            String framefile = rootPath + newImgName;
            String imgUrlSave = basePath+newImgName;//图片最终位置路径


            //视频截取封面图
            String imgUrl=FrameGrabberKit.getVedioImg(zxUrl, framefile, imgUrlSave);


            resultMap.put("zxUrl", zxUrl);
            resultMap.put("imgUrl", imgUrl);
            resultMap.put("returnCode", 0);
            System.out.println("上传的文件名为："+zxName+",后缀名为："+newzxName);

            shopZxMapper.zxadd(zxUrl,userId,zxName,zxField,imgUrl,zxAddress);
            return resultMap;
        }

        /**
         * 图片文件上传
         */
        @Override
        public Map<String, Object> uploadImage(MultipartFile file, HttpServletRequest request,String userId,String zxField, String zxAddress) throws Exception {
            Map<String, Object> resultMap=new HashMap<String, Object>();

            String basePath = request.getScheme() + "://" + request.getServerName()
                    + ":" + request.getServerPort()+"/mimi/upload/images/";

            Long time = System.currentTimeMillis();

            String zxName = file.getOriginalFilename();//文件原始名称
            String suffixName = zxName.substring(zxName.lastIndexOf("."));//从最后一个.开始截取。截取zxName的后缀名
            String newzxName = time+suffixName; //文件新名称
            //设置文件存储路径，可以存放在你想要指定的路径里面
            String rootPath="D:/mimi/"+File.separator+"upload/images/"; //上传图片存放位置

            String filePath = rootPath+newzxName;
            File newFile = new File(filePath);
            //判断目标文件所在目录是否存在
            if(!newFile.getParentFile().exists()){
                //如果目标文件所在的目录不存在，则创建父目录
                newFile.getParentFile().mkdirs();
            }

            //将内存中的数据写入磁盘
            file.transferTo(newFile);
            //图片上传保存url
            String imgUrl = basePath + newzxName;

            resultMap.put("imgUrl", imgUrl);
            resultMap.put("returnCode", 0);
            String zxUrl="";
            shopZxMapper.zxadd(zxUrl,userId,zxName,zxField,imgUrl,zxAddress);
            return resultMap;
        }

        /**
         * 项目目录下的图片文件上传
         */
        @Override
        public Map<String, Object> getImageUrl(HttpServletRequest request) throws Exception {
            Map<String,Object> result = new HashMap<String,Object>();
            //获取图片在项目路径下的地址
            String basePath= ClassUtils.getDefaultClassLoader().getResource("").getPath();
            String oldPath=basePath+"/static/images/animate.png";

            Long res =System.currentTimeMillis();
            //设置文件存储路径，可以存放在你想要指定的路径里面
            String rootPath="D:/mimi/"+File.separator+"upload/images/";
            // 新文件名
            String newzxName =res + oldPath.substring(oldPath.lastIndexOf("."));
            //新文件
            File newFile=new File(rootPath+File.separator+newzxName);
            //判断文件目录是否存在
            if(!newFile.getParentFile().exists()){
                //如果目标文件所在的目录不存在，则创建父目录
                newFile.getParentFile().mkdirs();
            }

            //-------把图片文件写入磁盘 start ----------------
            FileOutputStream fos = new FileOutputStream(newFile);
            //读取本地文件
            File localFile = new File(oldPath);
            //获取本地文件输入流
            InputStream stream=new FileInputStream(localFile);
            //写入目标文件
            byte[] buffer=new byte[1024*1024];
            int byteRead=0;
            //stream.read(buffer) 每次读到的数据存放在 buffer 数组中
            while((byteRead=stream.read(buffer))!=-1){
                //在 buffer 数组中 取出数据 写到 （输出流）磁盘上
                fos.write(buffer, 0, byteRead);
                fos.flush();
            }
            fos.close();
            stream.close();
            //-------把图片文件写入磁盘 end ----------------

            //服务器图片地址
            String baseURL = request.getScheme() + "://" + request.getServerName()
                    + ":" + request.getServerPort()+"/mimi/upload/images/";
            String imgUrl=baseURL+newzxName;

            result.put("imgUrl", imgUrl);
            result.put("returnCode", 0);
            return result;
        }
        //, String userId, String zxField, String zxAddress

    @Override
    public List imageUpload(MultipartFile[] files,String userId, String zxField, String zxAddress) {
        //获取上传图片数量，打印在控制台
        System.out.println("上传图片数量" + files.length);
        //创建集合
        List<Map<String, Object>> root = new ArrayList<Map<String, Object>>();

        String imgUrl = null;
        String zxName=null;
        String fileName=null;
        String zxUrl=null;
        // 要上传的目标文件存放的绝对路径
        final String localPath = "d:\\IDEAProject\\imageupload\\target\\classes\\static\\img";
        Map<String, Object> result = new HashMap<String, Object>();//一个文件上传的结果
        String result_msg = "";//上传结果信息
        //遍历图片数据
        for (MultipartFile file : files) {
//            Map<String, Object> result = new HashMap<String, Object>();//一个文件上传的结果

            if (file.isEmpty()) {
                System.out.println("上传图片为空，请重新上传");
            }
            //判断上传文件格式
            String fileType = file.getContentType();
            if (fileType.equals("image/jpeg") || fileType.equals("image/png") || fileType.equals("image/jpeg")) {
                // 要上传的目标文件存放的绝对路径

                //上传后保存的文件名(需要防止图片重名导致的文件覆盖)
                //获取文件名
                fileName = file.getOriginalFilename();
                //获取文件后缀名
                String suffixName = fileName.substring(fileName.lastIndexOf("."));
                //重新生成文件名
                fileName = UUID.randomUUID() + suffixName;

                zxUrl="";
                zxName+=fileName+",";
                imgUrl+=localPath+fileName+",";
               // shopZxMapper.zxadd(zxUrl,userId,zxName,zxField,imgUrl,zxAddress);
                if (FileUtils.upload(file, localPath, fileName)) {
                    //文件存放的相对路径(一般存放在数据库用于img标签的src)
                    String relativePath = "img/" + fileName;
                    result.put("relativePath", relativePath);//前端根据是否存在该字段来判断上传是否成功
                    result_msg = "图片上传成功";
                    result.put("imgUrl", imgUrl);

                } else {
                    result_msg = "图片上传失败";
                }
            } else {
                result_msg = "图片格式不正确";
            }

        }
        result.put("result_msg", result_msg);
        root.add(result);
        String root_json = JSON.toJSONString(root);
        System.out.println(root_json);
        result.put("returnCode", 0);
        System.out.println(zxName);
        System.out.println(imgUrl);
        shopZxMapper.zxadd(zxUrl,userId,zxName,zxField,imgUrl,zxAddress);
        return root;


    }



    /**
     *  获取资讯分页数据
     * @return
  */
//    @Override
    /**
     * 多文件上传 TODO
     */
    private Path fileStorageLocation; // 文件在本地存储的地址

    public UploadServiceImpl(@Value("${file.upload.path}") String path) {
        this.fileStorageLocation = Paths.get(path).toAbsolutePath().normalize();
        try {
            Files.createDirectories(this.fileStorageLocation);
        } catch (IOException e) {
            throw new FileException("Could not create the directory", e);
        }


    }

    /**
     * 存储文件到系统
     * @param file 文件
     * @return 文件名
     */
    @Override
    public String storeFile(MultipartFile file) {
        // Normalize file name
        String fileName = StringUtils.cleanPath(file.getOriginalFilename());

        try {
            // Check if the file's name contains invalid characters
            if(fileName.contains("..")) {
                throw new FileException("Sorry! Filename contains invalid path sequence " + fileName);
            }

            // Copy file to the target location (Replacing existing file with the same name)
            Path targetLocation = this.fileStorageLocation.resolve(fileName);
            Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);

            return fileName;
        } catch (IOException ex) {
            throw new FileException("Could not store file " + fileName + ". Please try again!", ex);
        }
    }

    @Override
    public Resource loadFileAsResource(String fileName) {
        try {
            Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
            Resource resource = new UrlResource(filePath.toUri());
            if(resource.exists()) {
                return resource;
            } else {
                throw new FileException("File not found " + fileName);
            }
        } catch (MalformedURLException  ex) {
            throw new FileException("File not found " + fileName, ex);
        }
    }

}
