package weaver.interfaces.workflow.action;

import com.api.doc.detail.service.DocAccService;
import com.api.doc.detail.util.ImageConvertUtil;
import com.api.doc.detail.util.PdfConvertUtil;
import com.api.doc.util.DocWKNonStandardUtil;
import weaver.conn.RecordSet;
import weaver.docs.docs.util.PdfWaterMarkUtil;
import weaver.file.FileSecurityUtil;
import weaver.file.ImageFileManager;
import weaver.general.BaseBean;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.soa.workflow.request.MainTableInfo;
import weaver.soa.workflow.request.Property;
import weaver.soa.workflow.request.RequestInfo;
import weaver.wps.doccenter.impl.DocWaterMark;
import weaver.wps.doccenter.utils.Tools;
import weaver.wps.officed.OfficedWatermark;

import java.io.*;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Month;
import java.time.format.TextStyle;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.*;

/**
 * @Description 给印章添加日期水印，再为pdf文件添加 盖章 水印
 * @Author b-r
 * @Date 2022/11/14 16:44
 * @Version 1.0
 **/
public class PdfAddDocwaterAction extends BaseBean implements Action {

    private String docid;

    private String picType;

    private String date;   //盖章的日期

    @Override
    public String execute(RequestInfo requestInfo) {
//        if(!DocWKNonStandardUtil.open()){
//            return Action.FAILURE_AND_CONTINUE;
//        }

        int requestid = Util.getIntValue(requestInfo.getRequestid());
//        int workflowid = Util.getIntValue(requestInfo.getWorkflowid());
        User user = requestInfo.getRequestManager().getUser();
        MainTableInfo mainTableInfo = requestInfo.getMainTableInfo();
        Property[] property = mainTableInfo.getProperty();
        int docid = -1;
        int picType = -1;
        String date = "";
        for (Property pro : property) {
            String name = pro.getName();
            if(name.equalsIgnoreCase(this.docid)){ //文件
                docid = Util.getIntValue(pro.getValue());
            }else if(name.equalsIgnoreCase(this.picType)){ //盖章类型
                picType = Util.getIntValue(pro.getValue());
            }else if(name.equalsIgnoreCase(this.date)){ //表单上的盖章日期
                date = Util.null2String(pro.getValue());
            }
        }

        writeLog("PdfAddDocwaterAction------->流程参数--->requestid:"+requestid+"----->docid:" + docid+"--->picType:"+picType+"---->date:"+date);
        if(docid <= 0 || picType <=0 ){
            writeLog("PdfAddDocwaterAction------->流程参数错误--->docid:" + docid+"--->picType:"+picType);
            return Action.FAILURE_AND_CONTINUE;
        }

        int fileid = -1;
        RecordSet rs = new RecordSet();
        boolean isExtFile = false;
        //根据文档id获取附件id
        rs.executeQuery("select imagefileid from docimagefile where (isextfile = '0' or isextfile ='' or isextfile is null) and docid="+docid + " order by versionid desc");
        if(rs.next()){
            fileid = Util.getIntValue(rs.getString(1));
        }
        writeLog("PdfAddDocwaterAction------->正文--->fileid:" + fileid);
        if(fileid <= 0){
            rs.executeQuery("select imagefileid from docimagefile where isextfile = '1' and docid=? order by versionid desc",docid);
            if(rs.next()){
                fileid = Util.getIntValue(rs.getString(1));
                isExtFile = true;
            }
        }
        writeLog("PdfAddDocwaterAction------->附件--->fileid:" + fileid);
        ImageFileManager ifm = new ImageFileManager();
        ifm.resetParameter();
        ifm.getImageFileInfoById(fileid);
        String imageFileName = ifm.getImageFileName();
        String extName = imageFileName.contains(".") ? imageFileName.substring(imageFileName.lastIndexOf(".") + 1) : "";
        writeLog("PdfAddDocwaterAction------->附件格式--->extName:" + extName+"---->原附件fileid:"+fileid);
        int convertPdfId = -1;
        //判断附件是否为pdf格式，如果不是，需要转为pdf再盖章
        if (!"pdf".equals(extName.toLowerCase()) && ImageConvertUtil.canConvertType(extName)) {
            PdfConvertUtil pcu = new PdfConvertUtil();
            convertPdfId = pcu.convertPdf(fileid);
        }else {
            convertPdfId = fileid;
        }

        writeLog("PdfAddDocwaterAction------->pdf附件--->convertPdfId:" + convertPdfId);
        if(convertPdfId <= 0){
            return Action.FAILURE_AND_CONTINUE;
        }

        int picDocid = -1;
        int picid = -1;
        int rqgs = -1;
        int size = 16;
        String color = "";
        //根据盖章类型获取建模表中的盖章图片
        rs.executeQuery("select skztp,rqgs,fontsize,color from uf_docwkskz where id ="+picType);
        if(rs.next()){
            picDocid = Util.getIntValue(rs.getString("skztp"));
            rqgs = Util.getIntValue(rs.getString("rqgs"));
            size = Util.getIntValue(rs.getString("fontsize"));
            color = Util.null2String(rs.getString("color"));
            //根据建模存储的docid获取imagefileid
            if(picDocid > 0) {
                rs.executeQuery("select imagefileid from docimagefile where  docid=" + picDocid);
                if (rs.next()) {
                    picid = Util.getIntValue(rs.getString(1));
                }
            }else {
                writeLog("PdfAddDocwaterAction------->建模存储的盖章图片为空--->picDocid:" + picDocid);
                return Action.FAILURE_AND_CONTINUE;
            }
        }

        DocWaterMark docWaterMark = new DocWaterMark(user);
        int newPicId = ImageFileManager.copyImageFile(picid);  //复制一个单独的附件，不关联文档
        //int newPicId = picid;
        //日期格式，是否需要日期
        if(rqgs > 0) {
            /**先给图片添加日期水印*/
            ifm.resetParameter();
            ifm.getImageFileInfoById(picid);
            String picName = ifm.getImageFileName();

            //日期水印字体
            Map<String, Object> waterParams = new HashMap<String, Object>();
            waterParams.put("size", size);
            waterParams.put("color", color);
            waterParams.put("position", "CENTER");
            waterParams.put("tiled", false);  //是否平铺
            waterParams.put("rotate", 360);  //旋转角度
            //waterParams.put("font_name", "mock");
            waterParams.put("bold", true); //加粗

            Map<String, Object> paramsMap = new HashMap<>();

            //水印内容
            String waterContent = "";
            if(!"".equals(date)){
                waterContent = date;
            }else {
                waterContent = getWaterContent(rqgs);
            }

            paramsMap.put("imagefileId", picid);
            paramsMap.put("filename", picName);
            paramsMap.put("waterType", OfficedWatermark.WATER_TYPE_IMG);  //给图片加水印
            paramsMap.put("waterContent", waterContent);
            paramsMap.put("waterParams", waterParams);
            paramsMap.put("user", user);
            paramsMap.put("fromMould", "ecology");
            paramsMap.put("fromAction", "1");

            //添加了日期水印的盖章图片
            newPicId = docWaterMark.addWordsWaterMark(paramsMap);

            writeLog("PdfAddDocwaterAction------->添加日期水印生成盖章附件--->newPicId:" + newPicId);
            if (newPicId <= 0) {
                return Action.FAILURE_AND_CONTINUE;
            }
        }


        /**再给pdf文件添加章子图片水印*/
        ifm.resetParameter();
        ifm.getImageFileInfoById(convertPdfId);
        String filename = ifm.getImageFileName();
        InputStream inputStream = ImageFileManager.getInputStreamById(convertPdfId);

        //水印参数
//        Map<String, Object> waterParams2 = new HashMap<String, Object>();
//        waterParams2.put("position", "BOTTOM_RIGHT");
//        waterParams2.put("tiled", false);
//        waterParams2.put("tilt", false);  //是否倾斜45度
//        waterParams2.put("transparent", transparent);  //透明度
//
//        Map<String, Object> paramsMap2 = new HashMap<>();
//        paramsMap2.put("imagefileId",fileid);
//        paramsMap2.put("filename",filename);
//        paramsMap2.put("waterType", OfficedWatermark.WATER_TYPE_PDF); //给pdf文件加水印
//        paramsMap2.put("picid",newPicId);
//        paramsMap2.put("waterParams",waterParams2);
//        paramsMap2.put("user",user);
//        paramsMap2.put("fromMould","ecology");
//
//        int newFileid = docWaterMark.addImageWaterMark(paramsMap2);  //添加了日期水印的盖章图片
        //使用开源方式给pdf添加图片水印
        InputStream waterIs = pdfAddImgWater(inputStream, user, filename, newPicId, "");
        Tools tools = new Tools();
        int newFileid = tools.saveToImageFile(waterIs, filename, "AddImageWaterMark");

        writeLog("PdfAddDocwaterAction------->添加盖章水印生成附件--->newFileid:"+newFileid);
        if(newFileid <= 0){
            return Action.FAILURE_AND_CONTINUE;
        }
        //word和pdf关联
        rs.executeQuery("select * from uf_wkwordpdf where docid=?",docid);
        if(rs.next()){
            rs.executeUpdate("update uf_wkwordpdf set pdfid=? where docid=?", fileid, docid);
        }else {
            rs.executeUpdate("insert into uf_wkwordpdf(docid,wordid,pdfid) values(?,?,?)", docid, fileid, newFileid);
        }

        //取消word绑定
        rs.executeUpdate("delete from DocImageFile where docid=? and imagefileid=?",docid,fileid);

        DocAccService accService = new DocAccService();
        if(isExtFile) {
            accService.buildRelForDoc(newFileid, docid, true, 0, "1");
        }else {
            //将新附件id绑定在原文档下作为正文
            accService.buildRelForDoc(newFileid, docid, false, 0, "1");
            //转为pdf后，更新文件类型
            rs.executeUpdate("update docdetail set docextendname='pdf' where id=?", docid);
        }

        //替换流程表单字段上的原有值
        //updateField(workflowid,requestid,this.pdf,0);

        return Action.SUCCESS;
    }

    private String getWaterContent(int type) {
        String waterMarkContent = "";
        if(type == 1) {
            String format = "yyyy'.'MM'.'dd";
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            Calendar calendar = Calendar.getInstance();
            waterMarkContent = sdf.format(calendar.getTime());
        }else if(type == 2){
            String format = "yyyy'-'MM'-'dd" ;
            SimpleDateFormat sdf = new SimpleDateFormat(format) ;
            Calendar calendar = Calendar.getInstance() ;
            waterMarkContent = sdf.format(calendar.getTime()) ;
        }else if(type == 3){
            LocalDate localDate = LocalDate.now();
            Month month = localDate.getMonth();
            SimpleDateFormat sdf = new SimpleDateFormat("dd yyyy") ;
            Calendar calendar = Calendar.getInstance() ;
            waterMarkContent = month.getDisplayName(TextStyle.SHORT, Locale.ENGLISH) + " "+ sdf.format(calendar.getTime()) ;
        }else if(type == 4){
            LocalDate localDate = LocalDate.now();
            Month month = localDate.getMonth();
            String displayName = month.getDisplayName(TextStyle.SHORT, Locale.ENGLISH);

            SimpleDateFormat sdf = new SimpleDateFormat("dd") ;
            Calendar calendar = Calendar.getInstance() ;
            String day = sdf.format(calendar.getTime()) ;

            SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy") ;
            String year = sdf2.format(calendar.getTime()) ;
            waterMarkContent = day + " " +  displayName + " "+year;
        }

        return waterMarkContent;
    }

    /**
    * @Desc  更新流程表单上的某个字段的值
    * @Author b-r
    * @Date 2022/11/16 17:05
    **/
    public void updateField(int workflowId,int requestId,String fieldName,int fieldValue){
        RecordSet rs = new RecordSet();
        String isBill="0";
        int formId=0;
        rs.executeUpdate("select formid,isbill from workflow_base where id="+workflowId);
        if(rs.next()){
            formId= Util.getIntValue(rs.getString("formid"), 0);
            isBill=rs.getString("isbill");
            if(!isBill.equals("1")){
                isBill="0";
            }
        }
        String tableName="workflow_form";
        if(isBill.equals("1")){
            rs.executeUpdate("select tablename from workflow_bill where id = " + formId);
            if (rs.next()){
                tableName = rs.getString("tablename");
            }
        }

        rs.executeUpdate("update "+tableName+" set "+fieldName+"="+fieldValue+" where requestid="+ requestId);
    }

    public InputStream pdfAddImgWater(InputStream inputStream, User user, String filename, int imgid, String position) {
        writeLog("PdfAddDocwaterAction---pdfAddImgWater--start--->inputStream:"+inputStream+"-->filename:"+filename+"---->imgid:"+imgid);
        InputStream imagefile = null;
        PdfWaterMarkUtil pdfWaterMarkUtil = null;
        String ext = "";
        String docsourcepath = "";
        String doctargetpath = "";
        try {
            pdfWaterMarkUtil = new PdfWaterMarkUtil();
            ext = getFileExt(filename);
            docsourcepath = pdfWaterMarkUtil.getWaterPdfPath("." + ext);
            doctargetpath = pdfWaterMarkUtil.getWaterPdfPath("." + ext);
            String imagepath = pdfWaterMarkUtil.getWaterPdfPath(".png");
            InputStream imgis = ImageFileManager.getInputStreamById(imgid);
            writeLog("PdfAddDocwaterAction---pdfAddImgWater--imgis:"+imgis);
            pdfWaterMarkUtil.writeToLocal(docsourcepath, inputStream);
            pdfWaterMarkUtil.writeToLocal(imagepath, imgis);
            writeLog("PdfAddDocwaterAction--------------filename=" + filename);
            writeLog("PdfAddDocwaterAction--------------docsourcepath=" + docsourcepath);
            writeLog("PdfAddDocwaterAction--------------doctargetpath=" + doctargetpath);
            writeLog("PdfAddDocwaterAction--------------imagepath=" + imagepath);
            try {
                addimgWatermark(docsourcepath, doctargetpath, imagepath, position);
                imagefile = new FileInputStream(new File(doctargetpath));
            } catch (Exception e) {
                imagefile = new FileInputStream(new File(docsourcepath));
            }
        } catch (Exception e) {
            writeLog("PdfAddDocwaterAction--------------error=" + e.getMessage());
            e.printStackTrace();
        }
        File file = new File(doctargetpath);
        FileSecurityUtil.deleteFile(file);
        writeLog("PdfAddDocwaterAction---pdfAddImgWater--end");
        return imagefile;
    }

    public void addimgWatermark(String pdfsourcepath, String pdftargetpath, String imagePath, String position) throws DocumentException, IOException, IOException {
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(pdftargetpath)));
        PdfReader reader = new PdfReader(pdfsourcepath);
        PdfStamper stamper = new PdfStamper(reader, bos);
        int total = reader.getNumberOfPages() + 1;
        PdfContentByte content;
        Map<String, Object> skzSetting = getSkzSetting();
        String waterPicShowLevel = Util.null2String(skzSetting.get("waterPicShowLevel"));//图片在文字上方还是下方 1上方
        int picxposition = Util.getIntValue(Util.null2String(skzSetting.get("xposition")),500);
        int picyposition = Util.getIntValue(Util.null2String(skzSetting.get("yposition")),100);
        int opacity = Util.getIntValue(Util.null2String(skzSetting.get("opacity")),50);
        if (!"".equals(Util.null2String(imagePath))) {
            File docwaterpicPathAllFile = new File(imagePath);
            if (docwaterpicPathAllFile.exists() && docwaterpicPathAllFile.isFile()) {
                com.lowagie.text.Image image = com.lowagie.text.Image.getInstance(imagePath);
                image.setAlignment(1);
                image.scaleAbsolute(image.getWidth(), image.getHeight());
                for (int i = 1; i < total; i++) {
                    if ("1".equals(waterPicShowLevel)) {
                        content = stamper.getOverContent(i);
                    } else {
                        content = stamper.getUnderContent(i);
                    }

                    PdfGState gs = new PdfGState();
                    float opacity_f = (float)  opacity / 100F;  //水印透明度
                    gs.setFillOpacity(opacity_f);
                    gs.setStrokeOpacity(opacity_f);
                    content.setGState(gs);

                    if (!"".equals(position)) {
                        if ("topleft".equals(position)) {
                            image.setAbsolutePosition(0, (reader.getPageSize(i).getHeight() - image.getHeight()));
                        } else if ("topright".equals(position)) {
                            image.setAbsolutePosition((reader.getPageSize(i).getWidth() - image.getWidth()), (reader.getPageSize(i).getHeight() - image.getHeight()));
                        } else if ("bottomleft".equals(position)) {
                            image.setAbsolutePosition(0, 0);
                        } else if ("bottomright".equals(position)) {
                            image.setAbsolutePosition((reader.getPageSize(i).getWidth() - image.getWidth()),0);
                        } else {
                            image.setAbsolutePosition(reader.getPageSize(i).getWidth() / 2, ((reader.getPageSize(i).getHeight()) / 2));//居中
                        }
                    } else if (picxposition > 0 && picyposition > 0) {
                        image.setAbsolutePosition(picxposition, picyposition);
                    } else {
                        image.setAbsolutePosition(reader.getPageSize(i).getWidth() / 2, ((reader.getPageSize(i).getHeight()) / 2));//居中
                    }
                    content.addImage(image);
                }
            }

        }
        stamper.close();
        bos.close();
        File file = new File(pdfsourcepath);
        File file1 = new File(imagePath);
        FileSecurityUtil.deleteFile(file);
        FileSecurityUtil.deleteFile(file1);
    }

    public String getFileExt(String file) {
        if (file == null || file.trim().equals("")) {
            return "";
        } else {
            int idx = file.lastIndexOf(".");
            if (idx == -1) {
                return "";
            } else {
                if (idx + 1 >= file.length()) {
                    return "";
                } else {
                    return file.substring(idx + 1);
                }
            }
        }
    }

    /**
    * @Desc  文控受控章水印位置
    * @Author b-r
    * @Date 2023/7/3 10:33
    **/
    public Map<String,Object> getSkzSetting(){
        Map<String, Object> map = new HashMap<>();
        RecordSet rs = new RecordSet();
        rs.executeQuery("select * from uf_docwkskzwater");
        if(rs.next()){
            map.put("waterPicShowLevel",Util.getIntValue(rs.getString("waterPicShowLevel"),1));
            map.put("xposition",Util.getIntValue(rs.getString("xposition")));
            map.put("yposition",Util.getIntValue(rs.getString("yposition")));
            map.put("opacity",Util.getIntValue(rs.getString("opacity")));
        }
        return map;
    }
}
