package cn.keking.web.controller;

import cn.keking.exception.KkFileException;
import cn.keking.service.ContractService;
import cn.keking.utils.Consts;
import cn.keking.utils.ServiceResponse;
import com.alibaba.fastjson2.JSON;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.util.*;

/**
 * @author Hikaru
 * 合同管理
 */
@RestController
@RequestMapping("/contract")
@Slf4j
@Api(tags = "合同模板操作")
public class ContractController {


    @Resource
    private ContractService contractService;


    /**
     * 合同生成
     * listTemplate
     *
     * @param templateName 模板名称
     * @param dataMap      模板数据
     * @return 成功
     */
    @ApiOperation("根据模板生成合同")
    @PostMapping("/gen/{templateName}")
    public ServiceResponse<String> contractGen(
            @ApiParam(value = "模板名称: 销售合同: sellContract ; 销售框架合同: frameContract", required = true) @PathVariable String templateName,
            @io.swagger.v3.oas.annotations.parameters.RequestBody()
            @RequestBody Map<String, Object> dataMap) {
        try {
            log.info("templateName:{},dataMap:{}", templateName, dataMap);
            return new ServiceResponse<>(contractService.gen(templateName, dataMap), "success",
                    ServiceResponse.RESULT_CODE_SUCCESS_CODE);
        } catch (Exception e) {
            log.error("生成错误:", e);
            if (e instanceof KkFileException) {
                KkFileException kkFileException = (KkFileException) e;
                return new ServiceResponse<>(null, kkFileException.getMessage(), ServiceResponse.RESULT_CODE_ERROR_CODE);
            }
            return new ServiceResponse<>(null, e.getMessage(), ServiceResponse.RESULT_SERVER_ERR_CODE);
        }
    }
    @ApiOperation("根据模板渲染excel")
    @PostMapping("/excel/{templateName}")
    public ServiceResponse<String> excel(
            @PathVariable String templateName,
            @RequestBody Map<String, Object> dataMap) {
        try {
            log.info("templateName:{},dataMap:{}", templateName, dataMap);
            return new ServiceResponse<>(contractService.excel(templateName, dataMap), "success",
                    ServiceResponse.RESULT_CODE_SUCCESS_CODE);
        } catch (Exception e) {
            log.error("生成错误:", e);
            if (e instanceof KkFileException) {
                KkFileException kkFileException = (KkFileException) e;
                return new ServiceResponse<>(null, kkFileException.getMessage(), ServiceResponse.RESULT_CODE_ERROR_CODE);
            }
            return new ServiceResponse<>(null, e.getMessage(), ServiceResponse.RESULT_SERVER_ERR_CODE);
        }
    }

    /**
     * 合同模板上传
     *
     * @param multipartFile 模板文件
     * @return 文件url
     */
    @ApiOperation("合同模板上传")
    @PostMapping("/upload")
    public ServiceResponse<String> contractUpload(
            @ApiParam(value = "模板文件", required = true, allowMultiple = true) @RequestPart(name = "file") MultipartFile multipartFile
    ) {
        String templateName = multipartFile.getOriginalFilename().split("\\.")[0];
        try {
            String url = this.contractService.upload(templateName, multipartFile);
            return new ServiceResponse<>(url, "成功", ServiceResponse.RESULT_CODE_SUCCESS_CODE);
        } catch (Exception e) {
            log.error("上传错误:", e);
            if (e instanceof KkFileException) {
                KkFileException kkFileException = (KkFileException) e;
                return new ServiceResponse<>(null, kkFileException.getMessage(), ServiceResponse.RESULT_CODE_ERROR_CODE);
            }
            return new ServiceResponse<>(null, "fail", ServiceResponse.RESULT_SERVER_ERR_CODE);
        }
    }

    /**
     * 查询模板列表
     *
     * @param templateNames 模板列表
     * @return 查询的模板url
     */
    @ApiOperation("查询模板列表")
    @PostMapping("/list/template")
    public ServiceResponse<List<String>> listTemplate(@ApiParam(value = "默认列表: 销售合同: sellContract ; 销售框架合同: frameContract。 传空返回所有模板列表") @RequestBody(required = false) List<String> templateNames) {
        try {
            templateNames = Optional.ofNullable(templateNames).orElse(Arrays.asList(Consts.FRAME_CONTRACT, Consts.SELL_CONTRACT));
            List<String> urls = this.contractService.listTemplate(templateNames);
            return new ServiceResponse<>(urls, "成功", ServiceResponse.RESULT_CODE_SUCCESS_CODE);
        } catch (Exception e) {
            log.error("获取列表错误:", e);
            if (e instanceof KkFileException) {
                KkFileException kkFileException = (KkFileException) e;
                return new ServiceResponse<>(null, kkFileException.getMessage(), ServiceResponse.RESULT_CODE_ERROR_CODE);
            }

            return new ServiceResponse<>(new ArrayList<>(), "fail", ServiceResponse.RESULT_SERVER_ERR_CODE);
        }
    }

    /**
     * @return 下载合同excel文件
     */
    @ApiParam("下载excel文件")
    @PostMapping("/downloadExcel/{templateName}")
    public ServiceResponse downloadExcel(
        @PathVariable String templateName,
            @RequestBody Map<String, Object> dataMap,
            HttpServletResponse response
    ) {
        try {
            log.error(JSON.toJSONString(dataMap));
            OutputStream outstream = null;
            File file = contractService.downloadExcel(templateName, dataMap);
            outstream = response.getOutputStream();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/octet-stream");
            String filename =file.getName();
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            // 刷新缓冲
            response.flushBuffer();
            FileInputStream fileInputStream = new FileInputStream(file);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
            byte[] b = new byte[bufferedInputStream.available()];
            bufferedInputStream.read(b);
            outstream.write(b);
            bufferedInputStream.close();
            outstream.flush();
            outstream.close();
            return new ServiceResponse<>("success",
                    ServiceResponse.RESULT_CODE_SUCCESS_CODE);
        } catch (Exception e) {
            log.error("生成错误:", e);
            if (e instanceof KkFileException) {
                KkFileException kkFileException = (KkFileException) e;
                return new ServiceResponse<>(null, kkFileException.getMessage(), ServiceResponse.RESULT_CODE_ERROR_CODE);
            }
            return new ServiceResponse<>(null, "fail", ServiceResponse.RESULT_SERVER_ERR_CODE);
        }
    }
    /**
     * @return 下载合同pdf文件
     */
    @ApiParam("下载合同pdf文件")
    @PostMapping("/download/{templateName}")
    public ServiceResponse downloadcontract(
            @ApiParam(value = "模板名称: 销售合同: sellContract ; 销售框架合同: frameContract", required = true) @PathVariable String templateName,
            @io.swagger.v3.oas.annotations.parameters.RequestBody()
            @RequestBody Map<String, Object> dataMap,
            HttpServletResponse response,
            @RequestParam(value = "type", required = false) String type
    ) {
        try {
            log.error(JSON.toJSONString(dataMap));
            OutputStream outstream = null;
            if (type == null) {
                type="pdf";
            }

            File file = contractService.download(templateName, dataMap,type);
            outstream = response.getOutputStream();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/octet-stream");
            String filename = dataMap.get("conCode") + "."+type;
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            // 刷新缓冲
            response.flushBuffer();
            FileInputStream fileInputStream = new FileInputStream(file);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
            byte[] b = new byte[bufferedInputStream.available()];
            bufferedInputStream.read(b);
            outstream.write(b);
            bufferedInputStream.close();
            outstream.flush();
            outstream.close();
            return new ServiceResponse<>("success",
                    ServiceResponse.RESULT_CODE_SUCCESS_CODE);
        } catch (Exception e) {
            log.error("生成错误:", e);
            if (e instanceof KkFileException) {
                KkFileException kkFileException = (KkFileException) e;
                return new ServiceResponse<>(null, kkFileException.getMessage(), ServiceResponse.RESULT_CODE_ERROR_CODE);
            }
            return new ServiceResponse<>(null, "fail", ServiceResponse.RESULT_SERVER_ERR_CODE);
        }
    }

    /**
     * 下载 word 文件
     */
    @ApiParam("下载word文件")
    @PostMapping("/downloadWord/{templateName}")
    public ServiceResponse downloadWord(
            @PathVariable String templateName,
            @RequestBody Map<String, Object> dataMap,
            HttpServletResponse response
    ) {
        try {
            log.error(JSON.toJSONString(dataMap));
            OutputStream outstream = null;

            File file = contractService.downloadWord(templateName, dataMap);
            outstream = response.getOutputStream();
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/octet-stream");
            String filename = dataMap.get("conCode") + ".docx";
            response.reset();
            // 设置response的Header
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(filename.getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            // 刷新缓冲
            response.flushBuffer();
            FileInputStream fileInputStream = new FileInputStream(file);
            BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
            byte[] b = new byte[bufferedInputStream.available()];
            bufferedInputStream.read(b);
            outstream.write(b);
            bufferedInputStream.close();
            outstream.flush();
            outstream.close();
            return new ServiceResponse<>("success",
                    ServiceResponse.RESULT_CODE_SUCCESS_CODE);
        } catch (Exception e) {
            log.error("生成错误:", e);
            if (e instanceof KkFileException) {
                KkFileException kkFileException = (KkFileException) e;
                return new ServiceResponse<>(null, kkFileException.getMessage(), ServiceResponse.RESULT_CODE_ERROR_CODE);
            }
            return new ServiceResponse<>(null, "fail", ServiceResponse.RESULT_SERVER_ERR_CODE);
        }
    }
}
