package cn.estsh.i3plus.ext.mes.apiservice.serviceimpl.busi.bu3;

import cn.estsh.i3plus.ext.mes.api.base.IModuleExcelManageService;
import cn.estsh.i3plus.ext.mes.api.busi.bu3.ISxProdDataPushNotifyStrategyFlagService;
import cn.estsh.i3plus.ext.mes.apiservice.util.FileExtUtil;
import cn.estsh.i3plus.ext.mes.apiservice.util.SxExcelExtUtil;
import cn.estsh.i3plus.ext.mes.pojo.model.bu3.SxPushDataNotifyParamModel;
import cn.estsh.i3plus.ext.mes.pojo.util.MesExtConstWords;
import cn.estsh.i3plus.icloud.core.sdk.ICoreSysFileCloud;
import cn.estsh.i3plus.platform.common.exception.ImppExceptionEnum;
import cn.estsh.i3plus.pojo.base.bean.BaseResultBean;
import cn.estsh.i3plus.pojo.base.codemaker.SnowflakeIdMaker;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.mes.bean.MesFile;
import cn.estsh.i3plus.pojo.model.platform.PushDataNotifyModel;
import cn.estsh.i3plus.pojo.platform.bean.SysFile;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.fileservice.ImppFileService;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.poi.openxml4j.util.ZipSecureFile;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author wangjie
 * @version 1.0
 * @date 2021/1/13 9:28
 **/
@Slf4j
@Service
public class SxProdDataPushNotifyStrategyFileCommonService implements ISxProdDataPushNotifyStrategyFlagService {

    @Autowired
    private IModuleExcelManageService moduleExcelManageService;

    @Autowired
    private SnowflakeIdMaker snowflakeIdMaker;

    @Autowired
    private ImppFileService imppFileService;

    @Autowired
    private ICoreSysFileCloud sysFileCloud;

    @Override
    public PushDataNotifyModel exec(PushDataNotifyModel data, SxPushDataNotifyParamModel pushParam, Object... obj) {

        log.info("生产数据推送通知数据处理 --- SxProdDataPushNotifyStrategyFileCommonService --- START --- DATA:{} --- THREAD:{}", JSONObject.toJSONString(data), Thread.currentThread().getName());

        List dataDbList = (List) obj[0];

        if (CollectionUtils.isEmpty(dataDbList)) return null;

        File fileTemplate = null;
        File excelFile = null;
        FileOutputStream fos = null;

        String reportTemplate = (String) obj[1];
        String title = (String) obj[2];

        try {

            MesFile fileDb = moduleExcelManageService.getTemplateFile(pushParam.getOrganizeCode(), reportTemplate);

            InputStream inputStream = FileExtUtil.getInputStream(fileDb.getFileUrl());
            if(inputStream == null)
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode())
                        .setErrorDetail("导出模板[%s]对应的文件URL[%s]获取文件流异常", reportTemplate, fileDb.getFileUrl())
                        .build();

            fileTemplate= File.createTempFile(String.valueOf(snowflakeIdMaker.nextId()), MesExtConstWords.DECIMAL_POINT_STR + fileDb.getFileType().replaceAll(String.valueOf((char)160), MesExtConstWords.EMPTY).trim());
            FileUtils.copyInputStreamToFile(inputStream, fileTemplate);

            Workbook workbook = SxExcelExtUtil.getWorkbook(fileTemplate);

            fos = new FileOutputStream(fileTemplate);
            workbook.write(fos);
            fos.flush();

            excelFile= File.createTempFile(title, MesExtConstWords.DECIMAL_POINT_STR + fileDb.getFileType().replaceAll(String.valueOf((char)160), MesExtConstWords.EMPTY).trim());

            OutputStream out = new FileOutputStream(excelFile);
            BufferedOutputStream bos = new BufferedOutputStream(out);
            ZipSecureFile.setMinInflateRatio(-1.0d);
            ExcelWriter excelWriter = EasyExcel.write(bos).withTemplate(fileTemplate).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();

            Map<String, Object> excelDataMap = new HashMap<>();
            excelDataMap.put(MesExtConstWords.TITLE, title);
            excelWriter.fill(excelDataMap, writeSheet);
            excelWriter.fill(dataDbList, writeSheet);

            excelWriter.finish();
            bos.flush();

            SysFile file = imppFileService.upload(excelFile, CommonEnumUtil.SOFT_TYPE.MES.getValue());

            BaseResultBean<SysFile> baseResultBean = this.sysFileCloud.insertFile(file);
            if (!baseResultBean.isSuccess()) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                        .setErrorCode(ImppExceptionEnum.BUSINESS_EXCEPTION.getCode())
                        .setErrorDetail(baseResultBean.errorMsg)
                        .build();
            }

            data.fileId(baseResultBean.getResultObject().getId().toString());

            log.info("生产数据推送通知数据处理 --- SxProdDataPushNotifyStrategyFileCommonService --- EXEC --- [{}]URL:[{}] --- THREAD:{}", title, file.getFilePath(), Thread.currentThread().getName());

        } catch (IOException e) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode())
                    .setErrorDetail("创建文件异常" + title + ".xlsx")
                    .build();
        } catch (ImppBusiException e) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode())
                    .setErrorDetail(ExceptionUtils.getStackTrace(e))
                    .build();
        } catch (Exception e) {
            throw ImppExceptionBuilder.newInstance()
                    .setSystemID(CommonEnumUtil.SOFT_TYPE.MES.getCode())
                    .setErrorCode(ImppExceptionEnum.IO_EXCEPTION_FILE.getCode())
                    .setErrorDetail(ExceptionUtils.getStackTrace(e))
                    .build();
        } finally {
            if(fileTemplate != null && fileTemplate.exists()) {
                fileTemplate.delete();
            }
            if(excelFile != null && excelFile.exists()) {
                excelFile.delete();
            }
            if (fos != null){
                try {
                    fos.close();
                } catch (IOException e) {
                    log.info("生产数据推送通知数据处理 --- SxProdDataPushNotifyStrategyFileCommonService --- EXEC IO EXCEPTION --- {} --- THREAD:{}", e.getMessage(), Thread.currentThread().getName());
                }
            }

            log.info("生产数据推送通知数据处理 --- SxProdDataPushNotifyStrategyFileCommonService --- END --- THREAD:{}", Thread.currentThread().getName());

        }

        return data;
    }

}
