package com.qmth.themis.business.templete;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.qmth.themis.business.constant.SpringContextHolder;
import com.qmth.themis.business.constant.SystemConstant;
import com.qmth.themis.business.entity.TBTaskHistory;
import com.qmth.themis.business.enums.FieldUniqueEnum;
import com.qmth.themis.business.enums.TaskStatusEnum;
import com.qmth.themis.business.service.TBTaskHistoryService;
import com.qmth.themis.business.util.OssUtil;
import com.qmth.themis.common.contanst.Constants;
import com.qmth.themis.common.util.GsonUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DuplicateKeyException;

import java.io.*;
import java.util.*;

/**
 * @Description: 导入任务公用
 * @Param:
 * @return:
 * @Author: wangliang
 * @Date: 2020/7/19
 */
public class TaskImportCommon {

    private final static Logger log = LoggerFactory.getLogger(TaskImportCommon.class);

    private String mode = null;//mode

    private Map<String, Object> map = null;

    private Long orgId = null;

    private Long createId = null;

    private Long examId = null;

    private TBTaskHistoryService tbTaskHistoryService = null;

    private String type = null;

    private String path = null;

    private Integer uploadType = null;

    private OssUtil ossUtil = null;

    private Map<String, Object> ossEnv = null;

    private TBTaskHistory tbTaskHistory = null;

    private boolean exception = false;

    private List<String> txtList = null;

    public TaskImportCommon() {

    }

    public TaskImportCommon(Map<String, Object> map) {
        this.map = map;
    }

    /**
     * 初始化
     */
    public void init() {
        OssUtil ossUtil = SpringContextHolder.getBean(OssUtil.class);
        if (Objects.nonNull(this.map.get("mode"))) {
            this.mode = String.valueOf(this.map.get("mode"));
        }
        if (Objects.nonNull(this.map.get(SystemConstant.ORG_ID))) {
            this.orgId = Long.parseLong(String.valueOf(this.map.get(SystemConstant.ORG_ID)));
        }
        this.createId = Long.parseLong(String.valueOf(this.map.get(SystemConstant.CREATE_ID)));
        if (Objects.nonNull(this.map.get(SystemConstant.EXAM_ID))) {
            this.examId = Long.parseLong(String.valueOf(this.map.get(SystemConstant.EXAM_ID)));
        }
        JSONObject remarkJs = JSONObject.parseObject(String.valueOf(this.map.get(SystemConstant.REMARK)));
        this.type = String.valueOf(remarkJs.get(SystemConstant.TYPE));
        this.path = String.valueOf(remarkJs.get(SystemConstant.PATH));
        this.uploadType = Integer.parseInt(String.valueOf(remarkJs.get(SystemConstant.UPLOAD_TYPE)));
        this.ossUtil = SpringContextHolder.getBean(OssUtil.class);
        this.ossEnv = ossUtil.getAliYunOssPrivateDomain().getMap();
        Map tbTaskHistoryMap = (Map) this.map.get("tbTaskHistory");
        this.tbTaskHistory = GsonUtil.fromJson(GsonUtil.toJson(tbTaskHistoryMap), TBTaskHistory.class);
        this.tbTaskHistoryService = SpringContextHolder.getBean(TBTaskHistoryService.class);
        map.put("tbTaskHistory", tbTaskHistory);
    }

    /**
     * 获取上传的文件
     *
     * @return
     */
    public InputStream getUploadFileInputStream() throws IOException {
        File file = null;
        StringJoiner localPath = new StringJoiner("").add(SystemConstant.FILES_DIR).add(File.separator)
                .add(this.path);
        InputStream inputStream = null;
        if (Objects.nonNull(this.type) && Objects.equals(this.type, SystemConstant.LOCAL)) {
            file = new File(localPath.toString());
            inputStream = new FileInputStream(file);
        } else {
            byte[] data = this.ossUtil.download(false, this.path);
            inputStream = new ByteArrayInputStream(data);
        }
        return inputStream;
    }

    /**
     * 获取上传的文件
     *
     * @return
     */
    public File getUploadFile() {
        File file = null;
        StringJoiner localPath = new StringJoiner("").add(SystemConstant.FILES_DIR).add(File.separator)
                .add(this.path);
        if (Objects.nonNull(this.type) && Objects.equals(this.type, SystemConstant.LOCAL)) {
            file = new File(localPath.toString());
        } else {
            file = this.ossUtil.download(false, this.path, localPath.toString());
        }
        return file;
    }

    /**
     * 写入txt文件
     *
     * @param txtStr
     * @throws IOException
     */
    public void writeImportResultTxt(String txtStr) {
        try {
            JSONObject json = SystemConstant.createTxt(this.path, this.type, txtStr);
            this.tbTaskHistory.setReportFilePath(json.toJSONString());
            tbTaskHistoryService.updateById(this.tbTaskHistory);
        } catch (Exception e) {
            log.error(SystemConstant.LOG_ERROR, e);
        }
    }

    /**
     * 异常处理
     *
     * @param line
     * @param e
     * @param txtList
     * @return
     */
    public List<String> exception(int line, Exception e, List<String> txtList) {
        this.exception = true;
        String exceptionStr = "数据处理到第" + (line == 0 ? line + 1 : line) + "条时发生异常，请联系系统管理员处理！";
        String errorMessage = "错误信息:[" + e.getMessage() + "]";
        if (e instanceof DuplicateKeyException) {
            String errorColumn = e.getCause().toString();
            String columnStr = errorColumn.substring(errorColumn.lastIndexOf("key") + 3, errorColumn.length())
                    .replaceAll("'", "");
            errorMessage = "错误信息:[" + FieldUniqueEnum.convertToCode(columnStr) + "数据不允许重复插入]";
        }
        if (Objects.nonNull(this.map.get("dataRemark"))) {
            errorMessage = errorMessage + "->" + this.map.get("dataRemark");
        }
        txtList.add(DateUtil.format(new Date(), Constants.DEFAULT_DATE_PATTERN) + "->" + exceptionStr + errorMessage);
        this.tbTaskHistory.setSummary(exceptionStr);
        this.tbTaskHistory.setStatus(TaskStatusEnum.FINISH);
        return txtList;
    }

    public List<String> getTxtList() {
        return txtList;
    }

    public void setTxtList(List<String> txtList) {
        this.txtList = txtList;
        map.put("txtList", txtList);
    }

    public void setException(boolean exception) {
        this.exception = exception;
    }

    public boolean isException() {
        return exception;
    }

    public String getMode() {
        return mode;
    }

    public Map<String, Object> getMap() {
        return map;
    }

    public Long getOrgId() {
        return orgId;
    }

    public Long getCreateId() {
        return createId;
    }

    public Long getExamId() {
        return examId;
    }

    public TBTaskHistoryService getTbTaskHistoryService() {
        return tbTaskHistoryService;
    }

    public String getType() {
        return type;
    }

    public String getPath() {
        return path;
    }

    public Integer getUploadType() {
        return uploadType;
    }

    public OssUtil getOssUtil() {
        return ossUtil;
    }

    public Map<String, Object> getOssEnv() {
        return ossEnv;
    }

    public TBTaskHistory getTbTaskHistory() {
        return tbTaskHistory;
    }
}

