package com.yihu.jw.base.endpoint.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.yihu.fastdfs.FastDFSUtil;
import com.yihu.jw.base.util.ErrorCodeUtil;
import com.yihu.jw.exception.code.BaseErrorCode;
import com.yihu.jw.file_upload.FileManageService;
import com.yihu.jw.file_upload.FileUploadService;
import com.yihu.jw.restmodel.MutilFileInfo;
import com.yihu.jw.restmodel.iot.common.UploadVO;
import com.yihu.jw.restmodel.web.ObjEnvelop;
import com.yihu.jw.restmodel.web.endpoint.EnvelopRestEndpoint;
import com.yihu.jw.rm.base.BaseRequestMapping;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.entity.ContentType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.util.*;

/**
 * 文件上传不在微服务中处理
 * @author yeshijie on 2017/12/7.
 */
@RestController
@RequestMapping(BaseRequestMapping.FileUpload.PREFIX)
@Api(tags = "文件上传相关操作", description = "文件上传相关操作")
public class FileUploadController extends EnvelopRestEndpoint {

    private static final Logger logger = LoggerFactory.getLogger(EnvelopRestEndpoint.class);


    @Value("${fastDFS.fastdfs_file_url}")
    private String fastdfs_file_url;
    @Autowired
    FileUploadService fileUploadService;

    @Value("${testPattern.sign}")
    private String isClose;
    @Value("${testPattern.remote_inner_url}")
    private String remote_inner_url;

    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private FileManageService fileManageService;


    @PostMapping(value = BaseRequestMapping.FileUpload.UPLOAD_STREAM_IMG)
    @ApiOperation(value = "文件流上传图片", notes = "文件流上传图片")
    public ObjEnvelop<UploadVO> uploadImg(@ApiParam(value = "文件", required = true)
                                       @RequestParam(value = "file", required = true) MultipartFile file) throws Exception{
        // 得到文件的完整名称  xxx.txt
//        String originalFilename = file.getOriginalFilename();
//        InputStream inputStream = file.getInputStream();
//        UploadVO uploadVO = fileUploadService.uploadImg(inputStream,originalFilename,file.getSize(),fastdfs_file_url);
//        return success("上传成功", uploadVO);
        UploadVO uploadVO = new UploadVO();
        if (isClose.equalsIgnoreCase("1")){
            Map<String, Object> map = fileUploadService.uploadImg(file);
            uploadVO.setFullUri(map.get("accessory").toString());
        }else if(isClose.equals("2")){
            String originalFilename = file.getOriginalFilename();
            String[] fs = originalFilename.split("\\.");
            String type = fs[1];
            //内网上传
            String rs = fileUploadService.request(remote_inner_url,file,type);
            logger.info(rs);
            JSONObject json = JSON.parseObject(rs);
            uploadVO = objectMapper.readValue(json.getJSONObject("obj").toJSONString(),UploadVO.class);

        }else {
            // 得到文件的完整名称  xxx.txt
            String originalFilename = file.getOriginalFilename();
            InputStream inputStream = file.getInputStream();
            uploadVO = fileUploadService.uploadStream(inputStream,originalFilename,fastdfs_file_url);
        }
        return success("上传成功", uploadVO);
    }


    @PostMapping(value = BaseRequestMapping.FileUpload.UPLOAD_STREAM_ATTACHMENT)
    @ApiOperation(value = "文件流上传附件", notes = "文件流上传附件")
    public ObjEnvelop<UploadVO> uploadAttachment(@ApiParam(value = "文件", required = true)
                                       @RequestParam(value = "file", required = true) MultipartFile file) throws Exception{
//        String originalFilename = file.getOriginalFilename();
//        InputStream inputStream = file.getInputStream();
//
//    UploadVO uploadVO = fileUploadService.uploadAttachment(inputStream,originalFilename,file.getSize(),fastdfs_file_url);
//        return success("上传成功", uploadVO);
        UploadVO uploadVO = new UploadVO();
        if (isClose.equalsIgnoreCase("1")){
            Map<String, Object> map = fileUploadService.uploadImg(file);
            uploadVO.setFullUri(map.get("accessory").toString());
        }else if(isClose.equals("2")){
            String originalFilename = file.getOriginalFilename();
            String[] fs = originalFilename.split("\\.");
            String type = fs[1];
            //内网上传
            String rs = fileUploadService.request(remote_inner_url,file,type);
            logger.info(rs);
            JSONObject json = JSON.parseObject(rs);
            uploadVO = objectMapper.readValue(json.getJSONObject("obj").toJSONString(),UploadVO.class);

        }else {
            // 得到文件的完整名称  xxx.txt
            String originalFilename = file.getOriginalFilename();
            InputStream inputStream = file.getInputStream();
            uploadVO = fileUploadService.uploadStream(inputStream,originalFilename,fastdfs_file_url);
        }
        return success("上传成功", uploadVO);
//        return uploadStream(file);
    }

//    @PostMapping(value = BaseRequestMapping.FileUpload.UPLOAD_STREAM)
//    @ApiOperation(value = "文件流上传文件", notes = "文件流上传文件")
//    public ObjEnvelop<UploadVO> uploadStream(@ApiParam(value = "文件", required = true)
//                                                 @RequestParam(value = "file", required = true) MultipartFile file) throws Exception{
//
//        // 得到文件的完整名称  xxx.txt
//        String originalFilename = file.getOriginalFilename();
//        InputStream inputStream = file.getInputStream();
//        UploadVO uploadVO = fileUploadService.uploadStream(inputStream,originalFilename,fastdfs_file_url);
//        return success("上传成功", uploadVO);
//    }

    @PostMapping(value = BaseRequestMapping.FileUpload.UPLOAD_STRING)
    @ApiOperation(value = "base64上传图片",notes = "base64上传图片")
    public ObjEnvelop<UploadVO> uploadImages(@ApiParam(name = "jsonData", value = "头像转化后的输入流")
                                                 @RequestBody String jsonData) throws Exception {
        UploadVO uploadVO = fileUploadService.uploadImages(jsonData,fastdfs_file_url);
        return success("上传成功", uploadVO);
    }

    @PostMapping(value = BaseRequestMapping.FileUpload.UPLOAD_STREAM)
    @ApiOperation(value = "文件流上传文件", notes = "文件流上传文件")
    public ObjEnvelop<UploadVO> uploadStream(@ApiParam(value = "文件", required = true)
                                             @RequestParam(value = "file", required = true) MultipartFile file
            /*@ApiParam(value = "jsonData", required = true)
            @RequestBody MutilFileInfo param, HttpServletResponse response, HttpServletRequest request*/) throws Exception{
        UploadVO uploadVO = new UploadVO();
            if (isClose.equalsIgnoreCase("1")){
                Map<String, Object> map = fileUploadService.uploadImg(file);
                uploadVO.setFullUri(map.get("accessory").toString());
                uploadVO.setFileName(file.getOriginalFilename());
            }else if(isClose.equals("2")){
                String originalFilename = file.getOriginalFilename();
                String[] fs = originalFilename.split("\\.");
                String type = fs[1];
                //内网上传
                String rs = fileUploadService.request(remote_inner_url,file,type);
                logger.info(rs);
                JSONObject json = JSON.parseObject(rs);
                uploadVO = objectMapper.readValue(json.getJSONObject("obj").toJSONString(),UploadVO.class);

            }else {
                // 得到文件的完整名称  xxx.txt
                String originalFilename = file.getOriginalFilename();
                InputStream inputStream = file.getInputStream();
                uploadVO = fileUploadService.uploadStream(inputStream,originalFilename,fastdfs_file_url);
            }
            return success("上传成功", uploadVO);
        }

    @PostMapping(value = BaseRequestMapping.FileUpload.UPLOAD_STRINGBASE64)
    @ApiOperation(value = "base64上传图片Xz",notes = "base64上传图片Xz")
    public ObjEnvelop<UploadVO> uploadBase64(@ApiParam(name = "jsonData", value = "头像转化后的输入流")
                                             @RequestBody String jsonData) throws Exception {
        UploadVO uploadVO = fileUploadService.uploadImagesBase64(jsonData,fastdfs_file_url);
        return success("上传成功", uploadVO);
    }


    @PostMapping(value = BaseRequestMapping.FileUpload.UPLOAD_STREAM_video)
    @ApiOperation(value = "文件流上传文件", notes = "文件流上传文件")
    public ObjEnvelop<UploadVO> uploadStreamVideo(@ApiParam(value = "文件", required = true)
                                                  @RequestParam(value = "file", required = true) MultipartFile file,
                                                  @ApiParam(value = "文件", required = false)
                                                  @RequestParam(value = "filename", required = false) String filename,
                                                  @ApiParam(value = "taskId", required = false)
                                                  @RequestParam(value = "taskId", required = false) String taskId,
                                                  @ApiParam(value = "chunk", required = false)
                                                  @RequestParam(value = "chunk", required = false) Integer chunk,
                                                  @ApiParam(value = "文件", required = false)
                                                  @RequestParam(value = "sizesize", required = false) Long size,
                                                  @ApiParam(value = "chunkTotal", required = false)
                                                  @RequestParam(value = "chunkTotal", required = false) Integer chunkTotal,
                                                  @ApiParam(value = "objectType", required = false)
                                                  @RequestParam(value = "objectType", required = false) Integer objectType,
                                                  @ApiParam(value = "chunkSize", required = false)
                                                      @RequestParam(value = "chunkSize", required = false) Integer  chunkSize
    ) throws Exception{
        UploadVO uploadVO = new UploadVO();
        MutilFileInfo files = new MutilFileInfo();
        files.setChunk(chunk);
        files.setChunkTotal(chunkTotal);
        files.setFile(file);
        files.setObjectType(objectType);
        files.setSize(file.getSize());
        logger.info("file size"+file.getSize());
        files.setTaskId(taskId);
        String taskid = fileManageService.chunkUploadByMappedByteBuffer(files,chunkSize);
        logger.info("taskid"+taskid);
        if ("unCompelete".equalsIgnoreCase(taskid)){
            System.out.println("第"+files.getChunk());
            return success("未传完",uploadVO);
        }else {

            File file1 = new File(taskid);
            logger.info("size:"+file1.getTotalSpace());
            FileInputStream input = new FileInputStream(file1);
            MultipartFile multipartFile = new MockMultipartFile("file", file1.getName(), "text/plain", IOUtils.toByteArray(input));
            if (isClose.equalsIgnoreCase("1")){
                Map<String, Object> map = fileUploadService.uploadImg(multipartFile);
                uploadVO.setFullUri(map.get("accessory").toString());
            }else if(isClose.equals("2")){
                String originalFilename = multipartFile.getOriginalFilename();
                String[] fs = originalFilename.split("\\.");
                String type = fs[1];
                //内网上传
                String rs = fileUploadService.request(remote_inner_url,multipartFile,type);
                logger.info(rs);
                JSONObject json = JSON.parseObject(rs);
                uploadVO = objectMapper.readValue(json.getJSONObject("obj").toJSONString(),UploadVO.class);

            }else {
                // 得到文件的完整名称  xxx.txt
                String originalFilename = multipartFile.getOriginalFilename();

                //判断文件名称是否有包含后缀，及前端是否有传后缀名称，有的话拼接图片后缀
                if(originalFilename.lastIndexOf(".") == 0 && StringUtils.isNotEmpty(filename)){
                    originalFilename = originalFilename +"."+filename;
                }

                InputStream inputStream = multipartFile.getInputStream();
                uploadVO = fileUploadService.uploadStream(inputStream,originalFilename,fastdfs_file_url);
                file1.delete();
            }
            return success("上传成功", uploadVO);
        }

    }

}
