package com.xxfc.platform.universal.service;


import com.github.wxiaoqi.security.common.util.process.SystemConfig;
import com.xxfc.platform.universal.constant.RedisKey;
import com.xxfc.platform.universal.dto.UploadImgDTO;
import com.xxfc.platform.universal.utils.ImgBase64Util;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
public class    UploadService {

    public static final DateTimeFormatter DEFAULT_DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");
    @Value("${universal.baseUploadPath}")
    private String baseUploadPath ;
    @Value("${universal.videoUploadPath}")
    private String videoUploadPath ;
    @Value("${universal.avatar}")
    private String avatar ;
    @Value("${universal.url}")
    private String xx_url ;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 写入上传文件，返回相对路径
     * @param file
     * @return
     */
    public String uploadFile(MultipartFile file,String prefix) throws Exception{
        //创建本日存放目录
        DateTime now = DateTime.now();
        String dirPathToday = "/"+prefix+ "/" + now.toString(DEFAULT_DATE_TIME_FORMATTER);
        String redisNoKey = RedisKey.UPLOAD_FILE_NO_PREFIX + now.toString(DEFAULT_DATE_TIME_FORMATTER);
        Long no = redisTemplate.opsForValue().increment(redisNoKey);
        if(no.equals(1l)){
            redisTemplate.expire(redisNoKey,1, TimeUnit.DAYS);
        }
        String fileName = file.getOriginalFilename();
        String realFileRelPath = dirPathToday + "/" + no + fileName.substring(fileName.lastIndexOf("."));
        //文件存放路径
        String filePath = baseUploadPath + realFileRelPath;
        //将文件写入指定位置
        FileUtils.copyInputStreamToFile(file.getInputStream(), new File(filePath));
        realFileRelPath=xx_url+SystemConfig.XXMP_URL+realFileRelPath;
        return realFileRelPath;
    }

    public String uploadFileV2(MultipartFile file,Long userId) throws Exception{
        //创建本日存放目录
        String fileName = file.getOriginalFilename();
        String realFileRelPath = avatar + "/" + userId % 1000 + "/" + userId + ".jpg";
        //文件存放路径
        String filePath = baseUploadPath + realFileRelPath ;
        //将文件写入指定位置
        FileUtils.copyInputStreamToFile(file.getInputStream(), new File(filePath));
        realFileRelPath=xx_url+SystemConfig.XXMP_URL+realFileRelPath;
        return realFileRelPath;
    }

    /**
     * 写入上传文件，返回相对路径
     * @param imgFile
     * @return
     */
    public String uploadImg(String imgFile,String prefix) throws Exception{
        //创建本日存放目录
        DateTime now = DateTime.now();
        String dirPathToday = "/"+prefix+ "/" + now.toString(DEFAULT_DATE_TIME_FORMATTER);
        String redisNoKey = RedisKey.UPLOAD_FILE_NO_PREFIX + now.toString(DEFAULT_DATE_TIME_FORMATTER);
        Long no = redisTemplate.opsForValue().increment(redisNoKey);
        if(no.equals(1l)){
            redisTemplate.expire(redisNoKey,1, TimeUnit.DAYS);
        }

        String realFileRelPath = dirPathToday;
        //文件存放路径
        String filePath = baseUploadPath + realFileRelPath;
        File file=new File(filePath);
        if(!file.exists()){
            file.mkdirs();

        }
        String str="/" + no + ".jpg";
        realFileRelPath = realFileRelPath+str;
        filePath=filePath +str;
        //将文件写入指定位置
        ImgBase64Util.generateImage(imgFile,filePath);
        realFileRelPath=xx_url+SystemConfig.XXMP_URL+realFileRelPath;
        return realFileRelPath;
    }


    /**
     * @Method: makeFileName
     * @Description: 生成上传文件的文件名，文件名以：uuid+"_"+文件的原始名称
     * @param filename 文件的原始名称
     * @return uuid+"_"+文件的原始名称
     */
    private String makeFileName(String filename){  //2.jpg
        //为防止文件覆盖的现象发生，要为上传文件产生一个唯一的文件名
        return UUID.randomUUID().toString() + "_" + filename;
    }

    /**
     * 为防止一个目录下面出现太多文件，要使用hash算法打散存储
     * @Method: makePath
     * @Description:
     *
     * @param filename 文件名，要根据文件名生成存储目录
     * @param savePath 文件存储路径
     * @return 新的存储目录
     */
    private String makePath(String filename,String savePath){
        //得到文件名的hashCode的值，得到的就是filename这个字符串对象在内存中的地址
        int hashcode = filename.hashCode();
        int dir1 = hashcode&0xf;  //0--15
        int dir2 = (hashcode&0xf0)>>4;  //0-15
        //构造新的保存目录
        String dir = savePath + "\\" + dir1 + "\\" + dir2;  //upload\2\3  upload\3\5
        //File既可以代表文件也可以代表目录
        File file = new File(dir);
        //如果目录不存在
        if(!file.exists()){
            //创建目录
            file.mkdirs();
        }
        return dir;
    }

    /**
     * 下载图片
     * @param realFileRelPath
     * @return
     * @throws Exception
     */
    public ResponseEntity<byte[]> downloadFile(String realFileRelPath) throws Exception{
        String filePath = baseUploadPath + realFileRelPath;
        File file = new File(filePath);//新建一个文件
        HttpHeaders headers = new HttpHeaders();//http头信息
        String downloadFileName = new String(file.getName());//设置编码
        headers.setContentDispositionFormData("attachment", downloadFileName);
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);
    }

    /**
     * 写入上传文件，返回相对路径
     * @param file
     * @return
     */
    public String uploadVideo(MultipartFile file,String prefix) throws Exception{
        //创建本日存放目录
        DateTime now = DateTime.now();
        String dirPathToday = "/"+prefix+ "/" + now.toString(DEFAULT_DATE_TIME_FORMATTER);
        String redisNoKey = RedisKey.UPLOAD_FILE_NO_PREFIX + now.toString(DEFAULT_DATE_TIME_FORMATTER);
        Long no = redisTemplate.opsForValue().increment(redisNoKey);
        if(no.equals(1l)){
            redisTemplate.expire(redisNoKey,1, TimeUnit.DAYS);
        }
        String fileName = file.getOriginalFilename();
        String realFileRelPath = dirPathToday + "/" + no + fileName.substring(fileName.lastIndexOf("."));
        //文件存放路径
        String filePath = videoUploadPath + realFileRelPath;
        //将文件写入指定位置
       FileUtils.copyInputStreamToFile(file.getInputStream(), new File(filePath));
        realFileRelPath=xx_url+SystemConfig.VIDEO_URL+realFileRelPath;
        return realFileRelPath;
    }

    /**
     *
     * @param srcpic //原图片路径
     * @param despic //目的图片路径
     */
    public static void copyPic(String srcpic, String despic){
        File file1 = new File(srcpic);
        File file2 = new File(despic);
        FileInputStream in=null;
        try {
            in=new FileInputStream(file1);
            FileUtils.copyInputStreamToFile(in,file2 );
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public String uploadHead(Integer userId) throws Exception{
        //创建本日存放目录
        String realFileRelPath = avatar + "/" + userId % 1000 + "/" + userId + ".jpg";
        //文件存放路径
        String filePath = baseUploadPath + realFileRelPath ;
        copyPicV2(filePath);
        realFileRelPath=xx_url+SystemConfig.XXMP_URL+realFileRelPath;
        return realFileRelPath;
    }


    public  String getHeadImg(UploadImgDTO uploadImgDTO) throws Exception{
        String prefix = uploadImgDTO.getPrefix();
        Integer userId = uploadImgDTO.getUserId();
        String headImg;
        if (StringUtils.isNotBlank(prefix)) {
            headImg = getImg(prefix,userId);
        }else {
            headImg = uploadHead(userId);
        }

        return  headImg;
    }




    /**
     *
     * @param despic //目的图片路径
     */
    public  void copyPicV2(String despic){
        String srcpic = baseUploadPath+avatar+"default.png";
        File file1 = new File(srcpic);
        File file2 = new File(despic);
        FileInputStream in=null;
        try {
            in=new FileInputStream(file1);
            FileUtils.copyInputStreamToFile(in,file2 );
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public  String  getImg(String imgUrl,Integer userId) throws Exception {
        //new一个URL对象
        URL url = new URL(imgUrl);
        //打开链接
        HttpURLConnection conn = (HttpURLConnection)url.openConnection();
        //设置请求方式为"GET"
        conn.setRequestMethod("GET");
        //超时响应时间为5秒
        conn.setConnectTimeout(5 * 1000);
        //通过输入流获取图片数据
        InputStream inStream = conn.getInputStream();
        //得到图片的二进制数据，以二进制封装得到数据，具有通用性
        byte[] data = readInputStream(inStream);
        //创建本日存放目录
        String filePath =  avatar + userId % 1000;
        File file=new File(baseUploadPath+filePath);
        if(!file.exists()){//如果文件夹不存在
            file.mkdirs();//创建文件夹
        }
        String realFileRelPath= filePath + "/" + userId + ".jpg";
        //文件存放路径
        filePath = baseUploadPath + realFileRelPath ;
        File imageFile = new File(filePath);
        //创建输出流
        FileOutputStream outStream = new FileOutputStream(imageFile);
        //写入数据
        outStream.write(data);
        //关闭输出流
        outStream.close();
        realFileRelPath=xx_url+SystemConfig.XXMP_URL+realFileRelPath;
        return realFileRelPath;
    }



    public static byte[] readInputStream(InputStream inStream) throws Exception{
        ByteArrayOutputStream outStream = new ByteArrayOutputStream();
        //创建一个Buffer字符串
        byte[] buffer = new byte[1024];
        //每次读取的字符串长度，如果为-1，代表全部读取完毕
        int len = 0;
        //使用一个输入流从buffer里把数据读取出来
        while( (len=inStream.read(buffer)) != -1 ){
            //用输出流往buffer里写入数据，中间参数代表从哪个位置开始读，len代表读取的长度
            outStream.write(buffer, 0, len);
        }
        //关闭输入流
        inStream.close();
        //把outStream里的数据写入内存
        return outStream.toByteArray();
    }






}
