package cn.com.capcloud.api.action.service;

import cn.com.capcloud.api.action.service.util.DictUtil;
import cn.com.capcloud.api.action.service.util.FileUtil;
import cn.com.capcloud.ccui.core.common.json.JackJSONArray;
import cn.com.capcloud.ccui.core.common.json.JackJSONObject;
import cn.com.capcloud.ccui.core.common.utils.StringUtil;
import cn.com.capcloud.ccui.core.common.utils.UUIDUtils;
import cn.com.capcloud.core.cache.BaseConfigStaticCache;
import cn.com.capcloud.core.execl.xlsx.ExcelOneUtil;
import cn.com.capcloud.core.system.user.User;
import cn.com.capcloud.core.system.user.UserService;
import cn.com.capcloud.core.util.*;
import com.deepoove.poi.XWPFTemplate;
import com.deepoove.poi.config.Configure;
import com.lowagie.text.pdf.BaseFont;
import org.joda.time.DateTime;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import org.springframework.beans.factory.annotation.Autowired;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class FileService {

    //PDF默认模板
    private static final String SYSTEM_SETTINGS_DS_FORM_PDF_TEMPLATE="system.settings.ds.form.pdf.template";
    @Autowired
    private ApiService apiService;
    @Autowired
    private DataSourceService dsService;
    @Autowired
    private UserService userService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private MinioService minioService;
    @Autowired
    private ReadProperty readProperty;

    /**
     * 文件上传本地服务器
     */
    public Map<String,Object> uploadToService(JackJSONObject retJson, HttpServletRequest request) {
        Map<String,Object>  returnMap=new HashMap<>();
        Map<String,Object> fileInfo= FileUtil.uploadToService(readProperty.getTempFilePath(), request);
        returnMap.put("fileInfo",fileInfo);
        return returnMap;
    }
    /**
     * 文件上传Minio
     */
    public Map<String,Object> uploadToMinio(JackJSONObject retJson,HttpServletRequest request) {
        Map<String,Object>  returnMap=new HashMap<>();
        Map<String,Object> fileInfo=FileUtil.uploadToMinio(retJson,minioService, request);
        if(fileInfo.size()==0){
            return new HashMap<>();
        }
        returnMap.put("fileInfo",fileInfo);
        return returnMap;
    }
    public Map<String,Object> createOnePdf(String jsonStr,JackJSONObject retJson,HttpServletRequest request) {
        User user=userService.getUser(request);
        Map<String,Object>  returnMap=new HashMap<>();
        List<Map<String,Object>> fieldList=dsService.getFormInfo(jsonStr);
        Map<String, Object> dsMap=dsService.findDataSourceByJsonStr(jsonStr);
        Map<String, Object> formMap=dsService.getForm(jsonStr);
        //todo-hui 这里应该加个before方便扩展，暂时写死 page_parent_uuid
        String pageParentUuid=String.valueOf(formMap.get("uuid"));
        String queryTemplateSql="SELECT * FROM tbl_data_pdf_template where page_parent_uuid='"+pageParentUuid+"'";
        List<Map<String,Object>> pdfTemplateList=jdbcTemplate.queryForList(queryTemplateSql);
        String pkId=apiService.getJsonValueByKey(jsonStr,retJson,"pkId");
        String querySql="SELECT * FROM "+dsMap.get("ds_table_name")+" where id='"+pkId+"'";
        List<Map<String,Object>> dataList=jdbcTemplate.queryForList(querySql);
        Map<String,Object> pdfTemplate;
        if(pdfTemplateList.size()==0){
            retJson.putAll(JackJSONObject.fromObject(apiService.getReturnDataByCode("6050")));
            retJson.put("message",retJson.get("message"));
            return new HashMap<>();
        }else{
            pdfTemplate=pdfTemplateList.get(0);
        }
        dataList= DictUtil.changeFormDict(fieldList,dataList,jdbcTemplate);
        String pdfTemplateHTML="";
        String pdfTemplateType=String.valueOf(pdfTemplate.get("pdf_template_type"));
        if(!"null".equals(pdfTemplateType)&&pdfTemplateType.equals("default")){//默认模板
            pdfTemplateHTML= BaseConfigStaticCache.get(SYSTEM_SETTINGS_DS_FORM_PDF_TEMPLATE);
            pdfTemplateHTML=pdfTemplateHTML.replaceAll("&nbsp;"," ");
            String defaultValue=ApiDao.createOnePdfDefaultHtml(fieldList,dataList,jdbcTemplate);
            pdfTemplateHTML=pdfTemplateHTML.replaceAll("\\$\\{defaultTemplate\\}",defaultValue);
            for (String key : pdfTemplate.keySet()) {
                String oldStr="\\$\\{"+key+"\\}";
                String newStr=pdfTemplate.get(key)+"";
                pdfTemplateHTML=pdfTemplateHTML.replaceAll(oldStr,newStr);
            }
        }else{//自定义模板
            pdfTemplateHTML=String.valueOf(pdfTemplate.get("pdf_template"));
            if(StringUtil.isEmpty(pdfTemplateHTML)){
                retJson.putAll(JackJSONObject.fromObject(apiService.getReturnDataByCode("6050")));
                retJson.put("message",retJson.get("message"));
                return new HashMap<>();
            }
            pdfTemplateHTML=pdfTemplateHTML.replaceAll("&nbsp;"," ");
            pdfTemplateHTML=pdfTemplateHTML.replaceAll("&quot;","'");
            for (int i = 0; i < fieldList.size(); i++) {
                String oldStr="\\$\\{"+fieldList.get(i).get("name")+"\\}";
                String newStr=dataList.get(0).get(fieldList.get(i).get("name"))+"";
                pdfTemplateHTML=pdfTemplateHTML.replaceAll(oldStr,newStr);
            }
            pdfTemplateHTML= TemplateReplace.renderTemplate(pdfTemplateHTML,dataList.get(0));
            for (String key : pdfTemplate.keySet()) {
                String oldStr="\\$\\{"+key+"\\}";
                String newStr=pdfTemplate.get(key)+"";
                pdfTemplateHTML=pdfTemplateHTML.replaceAll(oldStr,newStr);
            }
        }
        //替换内容后 再次处理一下空格和单引号
        pdfTemplateHTML=pdfTemplateHTML.replaceAll("&nbsp;"," ");
        pdfTemplateHTML=pdfTemplateHTML.replaceAll("&quot;","'");
        String suffix = ".pdf";
        DateTime d=new DateTime();
        String preffix = d.toString("yyyyMM")+"/pdf_"+UUIDUtils.randomUuidWithoutHyphen();
        String fileDir=readProperty.getTempFilePath()+d.toString("yyyyMM");
        File folder = new File(fileDir);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        File f=new File(readProperty.getTempFilePath()+preffix+suffix);
        try {
            OutputStream os = new FileOutputStream(f);
            ITextRenderer renderer = new ITextRenderer();
            ITextFontResolver fontResolver = renderer.getFontResolver();
            fontResolver.addFont(readProperty.getFontFilePath(), BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            renderer.setDocumentFromString(pdfTemplateHTML);
            renderer.layout();
            renderer.createPDF(os);
            os.flush();
            os.close();
            FileInputStream inputStream = new FileInputStream(f);
            byte[] data = new byte[(int) f.length()];
            inputStream.read(data);
            inputStream.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        String fileNameDate="";
        String pattern=String.valueOf(pdfTemplate.get("file_name_date"));
        String waterMark=String.valueOf(pdfTemplate.get("water_mark"));
        if(StringUtil.isNotEmpty(pattern)){
            fileNameDate=d.toString(pattern);
        }
        if(StringUtil.isNotEmpty(waterMark)){
            try {
                waterMark=waterMark.replace("${user_name}",user.getUserName());
                PdfAddWaterMarkUtil.addPDFWaterMark(readProperty.getTempFilePath()+preffix+suffix,readProperty.getTempFilePath()+preffix +"_water_mark"+suffix,waterMark);
                returnMap.put("diskFileName", pdfTemplate.get("file_name")+ fileNameDate +"_water_mark"+ suffix);
                returnMap.put("realFileName", preffix +"_water_mark"+ suffix);
            } catch (Exception e) {
                returnMap.put("realFileName", preffix + suffix);
                returnMap.put("diskFileName", pdfTemplate.get("file_name")+ fileNameDate + suffix);
            }
        }else{
            returnMap.put("realFileName", preffix + suffix);
            returnMap.put("diskFileName", pdfTemplate.get("file_name")+ fileNameDate + suffix);
        }
        returnMap.put("suffix",  suffix);
        returnMap.put("exportNum",  "导出成功");
        return returnMap;
    }
    public Map<String,Object> createWord(String jsonStr,JackJSONObject retJson, HttpServletRequest request,Map<String,Object> dataMap) {
        User user=userService.getUser(request);
        Map<String,Object> returnMap=new HashMap<>();
        Map<String,Object> queryMap=dsService.getQuery(jsonStr);
        String wordTemplate=String.valueOf(queryMap.get("word_template"));
        JackJSONArray jsonArray=JackJSONArray.fromObject(wordTemplate);
        if(jsonArray.size()>0){
            String realFileName =String.valueOf(jsonArray.getJackJSONObject(0).get("realFileName"));
            String suffix =String.valueOf(jsonArray.getJackJSONObject(0).get("suffix"));
            String diskFileName =String.valueOf(jsonArray.getJackJSONObject(0).get("diskFileName"));
            String oldTemplatePath= readProperty.getUploadFilePath()+diskFileName;//最初的模板，不可在此模板基础上做任何修改，只能拷贝出一个副本来修改
            String uuid=UUIDUtils.randomUuidWithoutHyphen();
            String newTemplatePath=readProperty.getTempFilePath()+uuid+"."+suffix;//拷贝出来后的模板
            try {
                FileInputStream fis = new FileInputStream(new File(oldTemplatePath));
                File newFile=new File(newTemplatePath);
                //判断文件是否存在
                if (!newFile.exists()) {
                    //创建文件
                    newFile.createNewFile();
                }
                FileOutputStream fos = new FileOutputStream(newFile);
                byte b[] = new byte[1024];
                int len=0;
                while((len=fis.read(b))!=-1){
                    fos.write(b);
                }
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            /**
             * 前后缀 官方使用 {{}} 的方式来致敬Google CTemplate，如果你更偏爱freemarker ${} 的方式：
             * Configure config=Configure.builder().buildGramer("${", "}").build();
             */
            String poiConfigureStr=String.valueOf(dataMap.get("poiConfigure"));
            XWPFTemplate template;
            if(StringUtil.isNotEmpty(poiConfigureStr)){
                Configure config = (Configure) dataMap.get("poiConfigure");
                template = XWPFTemplate.compile(newTemplatePath,config).render(dataMap);
            }else{
                template = XWPFTemplate.compile(newTemplatePath).render(dataMap);
            }
            String tempPath=readProperty.getUploadFilePath();
            String outTempFileName=UUIDUtils.randomUuidWithoutHyphen();
            returnMap.put("uuid", outTempFileName);
            try {
                template.writeToFile(tempPath+outTempFileName+"."+suffix);
                returnMap.put("source", "service");
                String wordWaterMark=String.valueOf(queryMap.get("word_template_water_mark"));
                if(StringUtil.isNotEmpty(wordWaterMark)){
                    wordWaterMark=wordWaterMark.replace("${user_name}",user.getUserName());
                    WordAddWaterMarkUtil.addWordWaterMark(tempPath+outTempFileName+"."+suffix,tempPath+outTempFileName+"_word_template_water_mark"+"."+suffix,wordWaterMark);
                    returnMap.put("diskFileName", outTempFileName+"_word_template_water_mark"+"."+suffix);
                }else{
                    returnMap.put("diskFileName", outTempFileName+"."+suffix);
                }
                returnMap.put("realFileName", realFileName);
                returnMap.put("suffix",  suffix);
                returnMap.put("exportNum",  "导出成功");
            } catch (IOException e) {
                //异常处理
                e.printStackTrace();
            }
        }else{
            retJson.put("status","no_code");
            retJson.put("message","未上传word模板");
            return new HashMap<>();
        }

        return returnMap;
    }
    public Map<String,Object> createExcel(String jsonStr,JackJSONObject retJson, HttpServletRequest request,Map<String,Object> dataMap) {
        User user=userService.getUser(request);
        Map<String,Object> returnMap=new HashMap<>();
        Map<String,Object> queryMap=dsService.getQuery(jsonStr);
        String excelOneTemplate=String.valueOf(queryMap.get("excel_one_template"));
        JackJSONArray jsonArray=JackJSONArray.fromObject(excelOneTemplate);
        if(jsonArray.size()>0){
            String realFileName =String.valueOf(jsonArray.getJackJSONObject(0).get("realFileName"));
            String suffix =String.valueOf(jsonArray.getJackJSONObject(0).get("suffix"));
            String diskFileName =String.valueOf(jsonArray.getJackJSONObject(0).get("diskFileName"));
            String oldTemplatePath= readProperty.getUploadFilePath()+diskFileName;//最初的模板，不可在此模板基础上做任何修改，只能拷贝出一个副本来修改
            String uuid=UUIDUtils.randomUuidWithoutHyphen();
            String newTemplatePath=readProperty.getTempFilePath()+uuid+"."+suffix;//拷贝出来后的模板
            try {
                FileInputStream fis = new FileInputStream(new File(oldTemplatePath));
                File newFile=new File(newTemplatePath);
                //判断文件是否存在
                if (!newFile.exists()) {
                    //创建文件
                    newFile.createNewFile();
                }
                FileOutputStream fos = new FileOutputStream(newFile);
                byte b[] = new byte[1024];
                int len=0;
                while((len=fis.read(b))!=-1){
                    fos.write(b);
                }
                fos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            String tempPath=readProperty.getUploadFilePath();
            String fileName= UUIDUtils.randomUuidWithoutHyphen();
            returnMap.put("uuid", fileName);
            String outTempFileName=fileName+"."+suffix;
            String outTempPathFileName=tempPath+outTempFileName ;
            ExcelOneUtil.exportExcel(newTemplatePath,outTempPathFileName,dataMap);
            String excelWaterMark=String.valueOf(queryMap.get("excel_template_water_mark"));
            if(StringUtil.isNotEmpty(excelWaterMark)){
                excelWaterMark=excelWaterMark.replace("${user_name}",user.getUserName());
                ExcelWaterRemarkUtils.addExcelWaterMark(outTempPathFileName,tempPath+fileName+"excel_template_water_mark"+"."+suffix,excelWaterMark);
                returnMap.put("diskFileName", fileName+"excel_template_water_mark"+"."+suffix);
            }else{
                returnMap.put("diskFileName", outTempFileName);
            }
            returnMap.put("source", "service");
            returnMap.put("realFileName", realFileName);
            returnMap.put("suffix",  suffix);
            returnMap.put("exportNum",  "导出成功");
        }else{
            retJson.put("status","no_code");
            retJson.put("message","未上传Excel-one模板");
            return new HashMap<>();
        }

        return returnMap;
    }

}

