package com.izouma.wenlvju.web;

import com.izouma.wenlvju.exception.BusinessException;
import com.izouma.wenlvju.service.storage.StorageService;
import com.izouma.wenlvju.utils.VideoUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.TempFile;
import org.bytedeco.javacv.FFmpegFrameGrabber;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.Java2DFrameConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@RestController
@RequestMapping("/upload")
@Slf4j
public class FileUploadController {

    @Autowired
    private StorageService storageService;

    @PostMapping("/file")
    public String uploadFile(@RequestParam("file") MultipartFile file,
                             @RequestParam(value = "   ", required = false) String path) {
        if (path == null) {
            String basePath = "application";
            try {
                basePath = file.getContentType().split("/")[0];
            } catch (Exception ignored) {
            }
            path = basePath + "/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
                    + RandomStringUtils.randomAlphabetic(8)
                    + "." + FilenameUtils.getExtension(file.getOriginalFilename());
        }
        InputStream is;
        try {
            is = file.getInputStream();
        } catch (IOException e) {
            log.error("上传失败", e);
            throw new BusinessException("上传失败", e.getMessage());
        }
        return storageService.uploadFromInputStream(is, path);
    }

    @PostMapping("/base64")
    public String uploadImage(@RequestParam("base64") String base64,
                              @RequestParam(value = "path", required = false) String path) {
        base64 = base64.substring(base64.indexOf(',') + 1);
        Base64.Decoder decoder = Base64.getDecoder();
        if (path == null) {
            String ext = ".jpg";
            try {
                InputStream is = new ByteArrayInputStream(decoder.decode(base64.getBytes()));
                String type = URLConnection.guessContentTypeFromStream(is);
                ext = type.replace("image/", ".").replace("jpeg", "jpg");
            } catch (Exception ignored) {
            }
            path = "image/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
                    + RandomStringUtils.randomAlphabetic(8) + ext;
        }
        InputStream is;
        try {
            is = new ByteArrayInputStream(decoder.decode(base64.getBytes()));
        } catch (Exception e) {
            log.error("上传失败", e);
            throw new BusinessException("上传失败", e.getMessage());
        }
        return storageService.uploadFromInputStream(is, path);
    }

    @PostMapping("/video")
    public Map<String, String> uploadVideo(@RequestParam("file") MultipartFile file) {
        String basePath = "application";
        try {
            basePath = file.getContentType().split("/")[0];
        } catch (Exception ignored) {
        }
        String videoPath = basePath + "/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
                + RandomStringUtils.randomAlphabetic(8)
                + "." + FilenameUtils.getExtension(file.getOriginalFilename());

        InputStream originInputstream;
        try {
            originInputstream = file.getInputStream();
            if (StringUtils.isEmpty(file.getContentType()) || !file.getContentType().startsWith("video")) {
                throw new BusinessException(file.getContentType() + " 非视频文件");
            }

            File destDir = TempFile.createTempDirectory("import." + FilenameUtils.getExtension(file.getOriginalFilename()));
            file.transferTo(destDir);
            Long videoTime = VideoUtils.getVideoTime(destDir);
            log.info("视频长度：" + videoTime);

            ByteArrayOutputStream baos = new ByteArrayOutputStream();

            byte[] buffer = new byte[1024];
            int len;
            while ((len = originInputstream.read(buffer)) > -1) {
                baos.write(buffer, 0, len);
            }
            baos.flush();

            InputStream is1 = new ByteArrayInputStream(baos.toByteArray());

            String videoUrl = storageService.uploadFromInputStream(is1, videoPath);

            InputStream is2 = new ByteArrayInputStream(baos.toByteArray());

            FFmpegFrameGrabber g = new FFmpegFrameGrabber(is2);
            g.start();

            Frame frame = g.grabKeyFrame();
            Java2DFrameConverter converter = new Java2DFrameConverter();
            BufferedImage image = converter.convert(frame);
            ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
            ImageIO.write(image, "jpeg", baos1);
            String posterPath = String.format("application/image/%s.jpg",
                    new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date())
                            + RandomStringUtils.randomAlphabetic(8));
            String posterUrl = storageService
                    .uploadFromInputStream(new ByteArrayInputStream(baos1.toByteArray()), posterPath);
            g.stop();

            return new HashMap<String, String>() {{
                put("src", videoUrl);
                put("poster", posterUrl);
            }};
        } catch (IOException e) {
            log.error("上传失败", e);
            throw new BusinessException("上传失败", e.getMessage());
        }
    }
}
