package com.nantian.cloud.jljc.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.nantian.cloud.jljc.entity.TModuleFile;
import com.nantian.cloud.jljc.service.TModuleFileService;
import com.nantian.cloud.jljc.tools.FtpUtil;
import com.nantian.cloud.jljc.tools.IDUtils;
import com.nantian.sc.cloud.common.core.util.R;
import com.nantian.sc.cloud.common.log.annotation.SysLog;
import com.nantian.sc.cloud.common.minio.MinioProperties;
import com.nantian.sc.cloud.common.minio.service.MinioTemplate;
import com.nantian.sc.cloud.common.security.annotation.Inner;
import com.nantian.sc.cloud.common.security.service.ScUser;
import com.nantian.sc.cloud.common.security.util.SecurityUtils;
import io.minio.MinioClient;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.Date;
import java.util.UUID;

import static com.nantian.cloud.jljc.vo.util.FileUtil.getFileSize;


/**
 * 模板文件
 *
 * @since 2020-10-23
 */
@CrossOrigin
@RestController
@AllArgsConstructor
@RequestMapping("/tModuleFile")
@Api(value = "TModuleFile", tags = "模板文件")
public class TModuleFileController {
    private final TModuleFileService tModuleFileService;
    private final MinioTemplate minioTemplate;
    private final MinioProperties minioProperties;

    /**
     * 根据编码获取模板文件
     */
    @SneakyThrows
    @Inner(value = false)
    @GetMapping("/getByCode")
    @SysLog("根据编码获取模板文件")
    @ApiOperation(value = "根据编码获取模板文件", notes = "根据编码获取模板文件")
    @ApiImplicitParam(name = "code", value = "编码", required = true, dataType = "int", paramType = "path")
    public R getByCode(String code, HttpServletResponse response) {
        TModuleFile tModuleFile = new TModuleFile();
        tModuleFile.setCode(code);
        tModuleFile.setDelFlag("1");
        TModuleFile moduleFile = tModuleFileService.getOne(Wrappers.query(tModuleFile));
        if (moduleFile == null) {
            return R.failed("文件不存在，下载模板文件失败！");
        } else {
            //testFileController.download2(moduleFile.getUrl(), response);
            //uuidStr   文件名<uuid
            String[] split = moduleFile.getUrl().split("<");

            MinioClient minioClient = new MinioClient(minioProperties.getUrl(), minioProperties.getAccessKey(), minioProperties.getSecretKey());
            InputStream object = minioClient.getObject("jljc", split[1]);
            int length = 0;
            byte buf[] = new byte[1024];

            response.reset();
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(split[0], "UTF-8"));
            response.setContentType("application/octet-stream;charset=utf-8");
            OutputStream outputStream = response.getOutputStream();
            while ((length = object.read(buf)) != -1) {
                outputStream.write(buf, 0, length);
            }
            outputStream.close();
            return R.ok();
        }
    }

    /**
     * 更新模板文件
     */
    @PostMapping("/update")
    @SysLog("更新模板文件")
    @ApiOperation(value = "更新模板文件", notes = "更新模板文件")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "模板文件（文件流）", required = true, dataType = "int", paramType = "path"),
            @ApiImplicitParam(name = "tModuleFile", value = "模板文件信息", required = true, dataType = "int", paramType = "path")
    })
    public R getByAdvancedFileDto(MultipartFile file, TModuleFile tModuleFile) throws Exception {

        if (file == null) {
            return R.failed("模板文件不存在，上传文件失败！");
        }

        ScUser u = SecurityUtils.getUser();
        TModuleFile old = new TModuleFile();
        old.setCode(tModuleFile.getCode());
        old.setDelFlag("1");
        old = tModuleFileService.getOne(Wrappers.query(old));
        if(old!=null){ //code存在，修改
            tModuleFile.setId(old.getId());
        }else{ //新增
            tModuleFile.setDeptId(u.getDeptId());
            tModuleFile.setDelFlag("1");
        }
        tModuleFile.setUserid(u.getId());
        tModuleFile.setUpdateTime(new Date());

        //上传文件
        String uuid = UUID.randomUUID().toString();
        InputStream inputStream = file.getInputStream(); //得到文件流
        String fileName = file.getOriginalFilename();    //文件名（含后缀）
        minioTemplate.putObject("jljc", uuid, inputStream, inputStream.available(), "application/octet-stream");
        tModuleFile.setUrl(fileName + "<" + uuid);

        //文件大小
        tModuleFile.setFileSize(getFileSize(file.getSize()));
        //文件名称（不含文件后缀）
        if(tModuleFile.getName()==null){
            String[] strings = fileName.split("\\.");
            tModuleFile.setName(strings[0]);
        }

        boolean flag = tModuleFileService.saveOrUpdate(tModuleFile);
        return flag ? R.ok(fileName + "<" + uuid) : R.ok(false);
    }

    @GetMapping("/nginxByCode")
    @SysLog("根据code获取nginx文件服务器的文件")
    @ApiOperation(value = "根据code获取nginx文件服务器的文件", notes = "根据code获取nginx文件服务器的文件")
    public R nginxFileByCode(String code) {
        if(StringUtils.isEmpty(code)){
            return R.failed("code不能为空！");
        }
        QueryWrapper<TModuleFile> q = new QueryWrapper<>();
        q.eq("del_flag","1");
        q.eq("type","nginx");
        q.like("code",code);
        return R.ok(tModuleFileService.list(q));
    }

    @GetMapping("/downloadNginxByCode")
    @SysLog("根据code下载nginx文件服务器的文件")
    @ApiOperation(value = "根据code下载nginx文件服务器的文件", notes = "根据code下载nginx文件服务器的文件")
    public R downloadNginxByCode(String code, HttpServletResponse response) throws IOException {
        QueryWrapper<TModuleFile> q = new QueryWrapper<>();
        q.eq("del_flag","1");
        q.eq("code",code);
        TModuleFile moduleFile = tModuleFileService.getOne(q);
        if (moduleFile == null) {
            return R.failed("文件不存在，下载模板文件失败！");
        }
        boolean b = FtpUtil.getImages(moduleFile.getUrl(), moduleFile.getName() ,response);
        return b ? R.ok("文件下载成功！") : R.failed("文件下载失败！");
    }

}
