package com.qmth.distributed.print.business.util;

import com.alibaba.fastjson.JSONObject;
import com.qmth.distributed.print.business.bean.dto.PdfDto;
import com.qmth.distributed.print.business.entity.ExamDetail;
import com.qmth.distributed.print.business.service.PrintCommonService;
import com.qmth.teachcloud.common.config.DictionaryConfig;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.BasicAttachment;
import com.qmth.teachcloud.common.enums.ClassifyEnum;
import com.qmth.teachcloud.common.enums.ExceptionResultEnum;
import com.qmth.teachcloud.common.enums.UploadFileEnum;
import com.qmth.teachcloud.common.util.FileStoreUtil;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.apache.commons.codec.digest.DigestUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.ResourceUtils;

import javax.annotation.Resource;
import java.io.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.StringJoiner;

/**
 * @Description: freemarker util
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/6/11
 */
@Component
public class FreemarkerUtil {
    private final static Logger log = LoggerFactory.getLogger(FreemarkerUtil.class);

    @Resource
    DictionaryConfig dictionaryConfig;

//    @Resource
//    OssUtil ossUtil;

    @Resource
    @Lazy
    PrintCommonService printCommonService;

    @Resource
    FileStoreUtil fileStoreUtil;

    /**
     * 单独生成签到表
     *
     * @param dataMap
     * @throws IOException
     */
    public void createSignBook(Map<String, Object> dataMap) throws IOException {
        if (Objects.isNull(dataMap) || dataMap.size() == 0) {
            throw ExceptionResultEnum.ERROR.exception("签到表数据为空");
        }
        this.createSignBookAndPaperPackageHtml(dataMap);
    }

    /**
     * 单独生成签到表
     *
     * @param dataMap
     * @throws IOException
     */
    public void createPaperPackage(Map<String, Object> dataMap) throws IOException {
        if (Objects.isNull(dataMap) || dataMap.size() == 0) {
            throw ExceptionResultEnum.ERROR.exception("卷袋贴数据为空");
        }
        this.createSignBookAndPaperPackageHtml(dataMap);
    }

    /**
     * 创建签到表
     *
     * @param dataMap
     * @throws IOException
     */
    private void createSignBookAndPaperPackageHtml(Map<String, Object> dataMap) throws IOException {
        Writer out = null;
        try {
            BasicAttachment basicAttachment = (BasicAttachment) dataMap.get("basicAttachment");
            ExamDetail examDetail = (ExamDetail) dataMap.get("examDetail");
            ClassifyEnum classifyEnum = (ClassifyEnum) dataMap.get("printType");
            JSONObject jsonObject = JSONObject.parseObject(basicAttachment.getPath());
            String path = (String) jsonObject.get(SystemConstant.PATH);
            String ftlPath = path.substring(0, path.lastIndexOf("/"));
            String ftlName = path.substring(path.lastIndexOf("/") + 1, path.lastIndexOf("."));

            Configuration configuration = new Configuration(Configuration.VERSION_2_3_29);
            File templates = null;
            if (ftlPath.contains(SystemConstant.TEMP_FILES_DIR)) {
                templates = ResourceUtils.getFile(ftlPath);
            } else {
                templates = ResourceUtils.getFile(SystemConstant.TEMP_FILES_DIR + File.separator + ftlPath);
            }
            configuration.setDirectoryForTemplateLoading(templates);
            // step1 加载模版文件
            Template template = configuration.getTemplate(ftlName + SystemConstant.FTL_PREFIX);
            // step2 生成数据
            boolean oss = dictionaryConfig.sysDomain().isOss();
            LocalDateTime nowTime = LocalDateTime.now();
            StringJoiner stringJoiner = new StringJoiner("");
            stringJoiner.add(SystemConstant.TEMP_FILES_DIR).add(File.separator);
            StringJoiner htmlStringJoiner = new StringJoiner("");
            htmlStringJoiner.add(UploadFileEnum.HTML.getTitle()).add(File.separator);
            htmlStringJoiner.add(String.valueOf(nowTime.getYear())).add(File.separator)
                    .add(String.format("%02d", nowTime.getMonthValue())).add(File.separator)
                    .add(String.format("%02d", nowTime.getDayOfMonth()));
            htmlStringJoiner.add(File.separator).add(SystemConstant.getUuid()).add(SystemConstant.HTML_PREFIX);
            File htmlFile = new File(stringJoiner.toString() + htmlStringJoiner.toString());
            if (!htmlFile.getParentFile().exists()) {
                htmlFile.getParentFile().mkdirs();
                htmlFile.createNewFile();
            }
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(htmlFile)));
            // step3 输出文件
            template.process(dataMap, out);
            out.flush();

            if (oss) {
                String htmlStringJoinerStr = htmlStringJoiner.toString().replace("\\", "/");
                jsonObject.put(SystemConstant.HTML_PATH, htmlStringJoinerStr);
                fileStoreUtil.ossUpload(htmlStringJoinerStr, htmlFile, DigestUtils.md5Hex(new FileInputStream(htmlFile)), fileStoreUtil.getUploadEnumByPath(htmlStringJoinerStr).getFssType());
            } else {
                jsonObject.put(SystemConstant.HTML_PATH, htmlFile.getPath());
            }
            jsonObject.put(SystemConstant.UPLOAD_TYPE, new UploadFileEnum[]{
                    UploadFileEnum.FILE,
                    UploadFileEnum.HTML
            });
            basicAttachment.setPath(jsonObject.toJSONString());
            printCommonService.saveAttachmentPdf(classifyEnum, examDetail, basicAttachment, (List<PdfDto>) dataMap.get("variablePdfList"), (Integer) dataMap.get("printCount"), (Integer) dataMap.get("sequence"));

//            htmlFile.delete();
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
        } finally {
            if (Objects.nonNull(out)) {
                out.close();
            }
        }
    }
}
