package com.tykj.dev.device.file.Controller;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.tykj.dev.config.swagger.AutoDocument;
import com.tykj.dev.device.file.entity.*;
import com.tykj.dev.device.file.service.UseReportFIleService;
import com.tykj.dev.device.file.util.JavaToPdfHtmlFreeMarker;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * @author zjm
 * @version 1.0.0
 * @ClassName FileController.java
 * @Description TODO
 * @createTime 2020年08月03日 18:05:00
 */
@RestController
@AutoDocument
@Api(tags = "文件模块", description = "提供文件相关的接口")
@Slf4j
public class FileController {
    @Value("${file.path}")
    public String url;
    @Value("${preview.path}")
    public String preview;

    @Autowired
    UseReportFIleService useReportFIleService;

    /**
     * 生成单据
     */
    @ApiOperation(value = "生成单据")
    @PostMapping("/printDocuments")
    public ResponseEntity printDocuments(@RequestBody Documents documents) throws IOException, DocumentException {
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRender(documents,url+"htmlModel/");
        log.info("[file] 调用了生成出入单据对接口 出入库单据");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf(content,url,preview,"documents/"));
    }

    /**
     * 生成维修单据
     */
    @ApiOperation(value = "生成维修单据")
    @PostMapping("/printRepair")
    public ResponseEntity printRepair(@RequestBody Documents documents) throws IOException, DocumentException {
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRenderRepair(documents,url+"htmlModel/");
        log.info("[file] 调用了生成出入单据对接口 出入库单据");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf(content,url,preview,"documents/"));
    }



    /**
     * 生成单据 多个单据生成
     */
    @ApiOperation(value = "生成单据 多个单据生成")
    @PostMapping("/printDocuments/more")
    public ResponseEntity printDocuments(@RequestBody List<Documents> documents){
        List<String> list=new ArrayList<>();
        documents.forEach(
                documents1 -> list.addAll(Objects.requireNonNull(JavaToPdfHtmlFreeMarker.freeMarkerRenderList(documents1, url + "htmlModel/")))
        );
        log.info("[file] 调用了生成出入单据对接口 documents");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf(list.toArray(new String[0]),url,preview,"documents/"));
    }

    /**
     * 生成工作交接的单据
     */
    @ApiOperation(value = "生成工作交接的单据")
    @PostMapping("/wordHandover")
    public ResponseEntity wordHandover(@RequestBody WorkHandoverDoc workHandoverDoc) {
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRenderWorkHandover2(workHandoverDoc,url+"htmlModel/");
        log.info("[file] 生成工作交接的单据");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf(content,url,preview,"workHandover/"));
    }


    /**
     * 生成决算清单
     */
    @ApiOperation(value = "生成决算清单")
    @PostMapping("/revenue")
    public ResponseEntity wordHandover(@RequestBody RevenueEntity revenueEntity) {
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRenderRevenue(revenueEntity,url+"htmlModel/");
        log.info("[file] 生成决算清单");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf(content,url,preview,"workHandover/"));
    }

    /**
     * 生成单据 确认单据
     * @return
     */
    @ApiOperation(value = "生成单据 确认单据")
    @PostMapping("/printConfirm")
    public ResponseEntity printConfirm(@RequestBody Confirm confirm) {
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRenderConfirm(confirm,url+"htmlModel/");
        log.info("[file] 调用了生成确认单据对接口 confirm");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf90(content,url,preview,"confirm/"));
    }


    /**
     * 生成单据 核查确认单
     * @return
     */
    @ApiOperation(value = "生成单据 核查确认单")
    @PostMapping("/printCheck")
    public ResponseEntity printCheck(@RequestBody Confirm confirm) {
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRenderVerification2(confirm,url+"htmlModel/");
        log.info("[file] 调用了生成核查确认单对接口 confirm");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf90(content,url,preview,"confirm/"));
    }


    /**
     * 生成单据 导出设备相关信息 核查的模版
     * @return
     */
    @ApiOperation(value = "生成单据 导出设备相关信息 核查的模版")
    @PostMapping("/exportDdevice")
    public ResponseEntity exportDdevice(@RequestBody Confirm confirm) {
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRenderExportDevice(confirm,url+"htmlModel/");
        log.info("[file] 调用了生成设备相关信息单据对接口 核查模版");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf90(content,url,preview,"confirm/"));
    }

    /**
     * 生成单据 导出设备相关信息 出入库类模版
     */
    @ApiOperation(value = "生成单据")
    @PostMapping("/exportDdevice1")
    public ResponseEntity exportDdevice1(@RequestBody Documents documents) throws IOException, DocumentException {
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRender(documents,url+"htmlModel/");
        log.info("[file] 调用了生成出入单据对接口 出入库单据");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf(content,url,preview,"documents/"));
    }


    /**
     * 生成单据 确认单据合并
     * @return
     */
    @ApiOperation(value = "生成单据 确认单据合并")
    @PostMapping("/printConfirmMerge")
    public ResponseEntity printConfirmMerge(@RequestBody Confirm confirm) {
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRenderConfirmMerge(confirm,url+"htmlModel/");
        log.info("[file] 调用了生成确认单据对接口 confirm");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf90(content,url,preview,"confirm/"));
    }

    /**
     * 生成单据 核查确认单据
     * @return
     */
    @ApiOperation(value = "生成单据 核查确认单据")
    @PostMapping("/printVerification")
    public ResponseEntity printVerification(@RequestBody Confirm confirm) {
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRenderVerification(confirm,url+"htmlModel/");
        log.info("[file] 调用了生成核查确认单据对接口 confirm");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf(content,url,preview,"confirm/"));
    }

    /**
     * 生成单据 销毁单据
     * @return
     */
    @ApiOperation(value = "生成单据 销毁单据")
    @PostMapping("/printDestruction")
    public ResponseEntity printDestruction(@RequestBody Destruction destruction){
        String[] content = JavaToPdfHtmlFreeMarker.freeMarkerRenderDestruction(destruction,url+"htmlModel/");
        log.info("[file] 调用了生成销毁单据对接口");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf(content,url,preview,"destruction/"));
    }

    /**
     * 生成单据
     * @return
     */
    @ApiOperation(value = "生成单据1")
    @GetMapping("/printDocuments1")
    public ResponseEntity printDocuments(HttpServletResponse response,HttpServletRequest request) throws IOException, DocumentException {
        int interval = request.getSession().getMaxInactiveInterval();
        System.out.println("-------"+interval);
       List<Documents> documentsList=new ArrayList<>();
        Documents documents=new Documents();
        documents.setNumber("NO:第221321134号");
        documents.setReceiveUnit("杭州机要");
        documents.setReplyNum("123123123131");
        documents.setSenderUnit("浙江省");
        documents.setTitle("密码装备清退单");
        List<DocumentDevice> documentDevices=new ArrayList<>();
        for (int i=0;i<20;i++){
            DocumentDevice documentDevice=new DocumentDevice();
            documentDevice.setCount(i);
            documentDevice.setModel("MM001");
            documentDevice.setRemark("备注");
            documentDevice.setApplicationField("省一级");
            documentDevice.setDeviceSerialNumber("asdq1231232");
//            documentDevice.setProductionSerialNumber("12312312312");
            documentDevice.setParts("密码机");
//            documentDevice.setCategory("装备");
            documentDevice.setSecurityClassification("机密");
            documentDevices.add(documentDevice);
        }
        documents.setDocumentDevices(documentDevices);
        documentsList.add(documents);
        List<String> list=new ArrayList<>();
        documentsList.forEach(
                documents1 -> list.addAll(Objects.requireNonNull(JavaToPdfHtmlFreeMarker.freeMarkerRenderList(documents1, url + "htmlModel/")))
        );

        log.info("[file] 调用了生成出入单据对接口 documents");
        return ResponseEntity.ok(JavaToPdfHtmlFreeMarker.createPdf(list.toArray(new String[0]),url,preview,"documents/"));
    }


    /**
     * 文件上传
     */
    @ApiOperation(value = "单文件上传")
    @PostMapping("/upload")
    public ResponseEntity upload(HttpServletRequest request) {
        MultipartRequest multiRequest = (MultipartRequest) request;
        MultipartFile file = multiRequest.getFile("file");
        return ResponseEntity.ok(fileUpload(file));
    }


    /**
     * 文件下载
     */
    @PostMapping("/download")
    public void download(@RequestBody FileRet fileRet, HttpServletResponse response, HttpServletRequest httpServletRequest){
        useReportFIleService.download(fileRet.getFilePath(),fileRet.getName(),response,httpServletRequest);
    }



    /**
     * 文件下载
     */
    @PostMapping("/download/preview")
    public void downloadPreview(@RequestBody FileRet fileRet, HttpServletResponse response, HttpServletRequest httpServletRequest){
        useReportFIleService.download(fileRet.getFilePath(),fileRet.getName(),response,httpServletRequest);
    }

    @ApiOperation(value = "多文件上传")
    @PostMapping(value = "/many/upload")
    public ResponseEntity<List<FileRet>> manyFileUpload(HttpServletRequest request) {
        List<FileRet> fileRets = new ArrayList<>();
        List<MultipartFile> multipartFiles = ((MultipartHttpServletRequest) request).getFiles("file");
        for (MultipartFile file : multipartFiles) {
            fileRets.add(fileUpload(file));
        }
        return ResponseEntity.ok(fileRets);
    }

    @ApiOperation(value = "上传图片转pdf")
    @PostMapping("/print/pdf/{type}")
    public ResponseEntity fileUpload(HttpServletRequest request, @PathVariable int type) throws IOException, DocumentException {
        log.info("{}触发图片转pdf的接口");
        List<MultipartFile> multipartFiles = ((MultipartHttpServletRequest) request).getFiles("file");
        log.info("数量{}",multipartFiles.size());
        File file1 = new File(url + "print/");
        if (!file1.exists()) {
            file1.mkdirs();
        }
        String fileName = UUID.randomUUID().toString().replace("-", "")+ ".pdf";
        File file = new File(url + "print/" + fileName);

        // 第一步：创建一个document对象。
        Document document;
        if (type==1) {
            document = new Document();
        }
        else {
            document = new Document(PageSize.A4.rotate());
        }
        document.setMargins(0, 0, 0, 0);
        // 第二步：
        // 创建一个PdfWriter实例，
        PdfWriter.getInstance(document, new FileOutputStream(file));
        // 第三步：打开文档。
        document.open();
        for (MultipartFile multipartFile : multipartFiles) {
            fileUpload1(multipartFile);
            Image img = Image.getInstance(multipartFile.getBytes());
            //转成
//            Image.byte()
            //多文件上传 图片专程byte 2进制
//            img.setAlignment(Image.ALIGN_CENTER);
            // 根据图片大小设置页面，一定要先设置页面，再newPage（），否则无效
//            document.setPageSize(new Rectangle(PageSize.A4.getWidth(), PageSize.A4.getHeight()));
            document.newPage();
            float height = img.getHeight();
            float width = img.getWidth();
//            int percent;
            img.setAlignment(Image.MIDDLE);
            if (width>=height) {
                img.scaleToFit(PageSize.A4.getHeight(),PageSize.A4.getWidth());
//                percent = getPercent(height, width);
            }
            else {
                img.scaleToFit(PageSize.A4.getWidth(),PageSize.A4.getHeight());
//                percent = getPercent2(height,width);
            }
//            img.setAlignment(Image.MIDDLE);
//            img.scalePercent(percent);
            document.add(img);
        }
        document.close();
        return ResponseEntity.ok(new FileRet("", url + "print/" + fileName + fileName, preview + "print/" + fileName));
    }


    private FileRet fileUpload(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        File file1 = new File(url);
        if (!file1.exists()) {
            file1.mkdirs();
        }
        FileOutputStream fos = null;
        InputStream inputStream = null;
        OutputStream os = null;

        String[] split = originalFilename.split("\\.");
        String newName = UUID.randomUUID().toString().replace("-", "") + "." + split[split.length - 1];
        byte[] typeByte = new byte[1024 * 1024 * 10];
        try {
            inputStream = file.getInputStream();
            fos = new FileOutputStream(url + newName);
            int i = 0;
            while ((i = inputStream.read(typeByte)) != -1) {
                fos.write(typeByte, 0, i);
            }
            fos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                inputStream = null;
            }
        }

        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                fos = null;
            }
        }

        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                os = null;
            }
        }

        return new FileRet(originalFilename, url + newName, preview + newName);
    }

    private FileRet fileUpload1(MultipartFile file) {
        String originalFilename = file.getOriginalFilename();
        File file1 = new File(url);
        if (!file1.exists()) {
            file1.mkdirs();
        }
        FileOutputStream fos = null;
        InputStream inputStream = null;
        OutputStream os = null;

        String[] split = originalFilename.split("\\.");
        String newName = UUID.randomUUID().toString().replace("-", "") + ".jpg" ;
        byte[] typeByte = new byte[1024 * 1024 * 10];
        try {
            inputStream = file.getInputStream();
            fos = new FileOutputStream(url + newName);
            int i = 0;
            while ((i = inputStream.read(typeByte)) != -1) {
                fos.write(typeByte, 0, i);
            }
            fos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                inputStream = null;
            }
        }

        if (fos != null) {
            try {
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                fos = null;
            }
        }

        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                os = null;
            }
        }

        return new FileRet(originalFilename, url + newName, preview + newName);
    }

    private static void showPdf( HttpServletResponse response, String fileName) throws IOException{
        response.setContentType("application/pdf");
        FileInputStream in = new FileInputStream(new File(fileName));
        OutputStream out = response.getOutputStream();
        byte[] b = new byte[1024];
        while ((in.read(b))!=-1) {
            out.write(b);
        }
        out.flush();
        in.close();
        out.close();
    }

    /**
     * 生成决算的单据
     */
    @ApiOperation(value = "生成决算的单据")
    @PostMapping("/pdfRevenue")
    public ResponseEntity pdfRevenue(@RequestBody RevenueEntity revenueEntity) {
        return ResponseEntity.ok("");
    }

}
