package com.qmth.distributed.print.business.templete.importData;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.qmth.boot.api.exception.ApiException;
import com.qmth.teachcloud.common.config.DictionaryConfig;
import com.qmth.teachcloud.common.contant.SpringContextHolder;
import com.qmth.teachcloud.common.contant.SystemConstant;
import com.qmth.teachcloud.common.entity.TBTask;
import com.qmth.teachcloud.common.enums.*;
import com.qmth.teachcloud.common.service.TBTaskService;
import com.qmth.teachcloud.common.util.ExcelUtil;
import com.qmth.teachcloud.common.util.FileStoreUtil;
import com.qmth.teachcloud.common.util.Result;
import com.qmth.teachcloud.common.util.ResultUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.MessageFormat;
import java.util.*;

/**
 * @Description: 异步导入模版
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2021/3/29
 */
public abstract class AsyncImportTaskTemplete {
    private final static Logger log = LoggerFactory.getLogger(AsyncImportTaskTemplete.class);
    public static final String BEGIN_TITLE = "->开始准备处理导入的";
    public static final String EXCEPTION_TITLE = "->数据处理发生异常!";
    public static final String EXCEPTION_DATA = "错误信息:";
    public static final String FINISH_TITLE = "->数据处理结束，共处理了";
    public static final String FINISH_TOTAL_SIZE = "条数据，成功";
    public static final String FINISH_SUCCESS_SIZE = "条数据，失败";
    public static final String FINISH_ERROR_SIZE = "条数据";
    public static final String EXCEPTION_CREATE_TXT_TITLE = "->创建导出日志时发生异常!";

    /**
     * 异步导入任务
     *
     * @param map
     * @return
     * @throws IOException
     */
    @Async
    public abstract Result importTask(Map<String, Object> map) throws IOException, Exception;

    /**
     * 获取上传的文件
     *
     * @param tbTask
     * @return
     * @throws IOException
     */
    public InputStream getUploadFileInputStream(TBTask tbTask) throws Exception {
        FileStoreUtil fileStoreUtil = SpringContextHolder.getBean(FileStoreUtil.class);
        JSONObject jsonObject = JSONObject.parseObject(tbTask.getImportFilePath());
        String path = (String) jsonObject.get(SystemConstant.PATH);
        String type = (String) jsonObject.get(SystemConstant.TYPE);
        UploadFileEnum uploadType = Enum.valueOf(UploadFileEnum.class, (String) jsonObject.get(SystemConstant.UPLOAD_TYPE));
        InputStream inputStream = null;
        if (Objects.equals(type, SystemConstant.OSS)) {
            inputStream = fileStoreUtil.ossDownloadIs(path, uploadType.getFssType());
        } else {
            inputStream = new FileInputStream(new File(path));
        }
        return inputStream;
    }

    /**
     * 创建txt文件
     *
     * @param tbTask
     */
    public void createTxt(TBTask tbTask) throws IOException {
        try {
            JSONObject json = SystemConstant.createTxt(tbTask.getSummary());
            tbTask.setReportFilePath(json.toJSONString());
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
            StringJoiner stringJoinerSummary = new StringJoiner("").add(tbTask.getSummary()).add("\n");
            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), EXCEPTION_CREATE_TXT_TITLE, EXCEPTION_DATA, e.getMessage()));

            String summary = stringJoinerSummary.toString();
            if (summary.length() >= 65535) {
                summary = "Data too long : " + summary.substring(0, 100) + "......" + summary.substring(summary.length() - 100);
            }

            tbTask.setSummary(summary);
            tbTask.setResult(TaskResultEnum.ERROR);
//            TBTask dbTask = tbTaskService.getById(tbTask.getId());
//            if (tbTask.getVersion() == dbTask.getVersion()) {
//                tbTask.setResetCount(new AtomicInteger(tbTask.getResetCount()).incrementAndGet());
//            }
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        } finally {
            TBTaskService tbTaskService = SpringContextHolder.getBean(TBTaskService.class);
            tbTask.setStatus(TaskStatusEnum.FINISH);
            if (tbTask.getType() == TaskTypeEnum.CREATE_PDF) {
                tbTask.setResultFilePath(tbTask.getImportFilePath());
                tbTask.setImportFileName(null);
                tbTask.setImportFilePath(null);
                tbTask.setErrorMessage(null);
            }
            tbTaskService.updateById(tbTask);
        }
    }


    /**
     * 创建txt文件
     *
     * @param tbTask
     */
    public void createErrorFile(TBTask tbTask, Class clazz, List list) {
        File excelFileTemp = null;
        try {
            FileStoreUtil fileStoreUtil = SpringContextHolder.getBean(FileStoreUtil.class);
            DictionaryConfig dictionaryConfig = SpringContextHolder.getBean(DictionaryConfig.class);
            boolean oss = dictionaryConfig.sysDomain().isOss();
            String ossStr = null;
            StringJoiner stringJoiner = new StringJoiner("");
            if (!oss && Objects.nonNull(dictionaryConfig.fssPublicDomain()) && !StringUtils.isBlank(dictionaryConfig.fssPublicDomain().getConfig()) && !dictionaryConfig.fssPublicDomain().getConfig().startsWith(SystemConstant.START_PARENT)) {
                stringJoiner.add(dictionaryConfig.fssPublicDomain().getConfig()).add(File.separator);
            }
            stringJoiner = SystemConstant.getDirName(stringJoiner, UploadFileEnum.FILE, true);
            stringJoiner.add(SystemConstant.getNanoId()).add(SystemConstant.EXCEL_PREFIX);

            String txtDirName = stringJoiner.toString();
            excelFileTemp = SystemConstant.getFileTempVar(SystemConstant.EXCEL_PREFIX);
            ExcelUtil.excelExportLocal(excelFileTemp, clazz, list);

            String txtFileMd5 = DigestUtils.md5Hex(new FileInputStream(excelFileTemp));
            if (oss || (!oss && dictionaryConfig.fssPrivateDomain().getConfig().startsWith(SystemConstant.START_PARENT))) {
                ossStr = oss ? SystemConstant.OSS : SystemConstant.LOCAL;
                fileStoreUtil.ossUpload(txtDirName, excelFileTemp, txtFileMd5, fileStoreUtil.getUploadEnumByPath(txtDirName).getFssType());
            } else {
                ossStr = SystemConstant.LOCAL;
                fileStoreUtil.localUpload(txtDirName, new FileInputStream(excelFileTemp), txtFileMd5, LocalCatalogEnum.LOCAL_FILE);
            }
            JSONObject json = new JSONObject();
            json.put(SystemConstant.PATH, stringJoiner.toString());
            json.put(SystemConstant.TYPE, ossStr);
            json.put(SystemConstant.UPLOAD_TYPE, UploadFileEnum.FILE);
            tbTask.setErrorFilePath(json.toJSONString());

        } catch (Exception e) {
            StringJoiner stringJoinerSummary = new StringJoiner("").add(tbTask.getSummary()).add("\n");
            stringJoinerSummary.add(MessageFormat.format("{0}{1}{2}{3}", DateUtil.format(new Date(), SystemConstant.DEFAULT_DATE_PATTERN), EXCEPTION_CREATE_TXT_TITLE, EXCEPTION_DATA, e.getMessage()));

            String summary = stringJoinerSummary.toString();
            tbTask.setSummary(summary);
            tbTask.setResult(TaskResultEnum.ERROR);
            if (e instanceof ApiException) {
                ResultUtil.error((ApiException) e, e.getMessage());
            } else {
                ResultUtil.error(e.getMessage());
            }
        } finally {
            if (Objects.nonNull(excelFileTemp)) {
                excelFileTemp.delete();
            }
            TBTaskService tbTaskService = SpringContextHolder.getBean(TBTaskService.class);
            tbTask.setStatus(TaskStatusEnum.FINISH);
            tbTaskService.updateById(tbTask);
        }
    }
}
