package nckd.jxccl.sit.hcsi.business.importtaskguide;

import com.google.common.collect.Lists;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.resource.ResManager;
import kd.bos.dataentity.utils.StringUtils;
import nckd.jxccl.base.common.utils.DateTimeUtils;
import kd.bos.exception.ErrorCode;
import kd.bos.exception.KDException;
import kd.bos.form.FormShowParameter;
import kd.bos.form.IFormView;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QFilter;
import kd.bos.orm.util.CollectionUtils;
import nckd.jxccl.base.sit.helper.SITExportDataHelper;
import nckd.jxccl.sit.hcsi.business.importtaskguide.utils.ImportTaskUtils;
import nckd.jxccl.sit.hcsi.common.constant.enums.DataTypeEnum;
import nckd.jxccl.sit.hcsi.common.constant.enums.SITShowType;
import nckd.jxccl.sit.hcsi.formplugin.web.tp.enums.SinsurPresetItemEnum;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.*;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;

import java.text.MessageFormat;
import java.util.*;

/**
 * Tyx 2025-10-21
 * 导出Service，nckd_taskguideimport
 */
public class ImportTaskGuideExportService {

    private static final Log logger = LogFactory.getLog(ImportTaskGuideExportService.class);
    private static final int PAGE_SIZE = 500;
    private static final String TPLERROR = "1";
    private static final String IMPORT_ERROR_TEMPLATE = "外部数据导入任务_数据导入失败结果_{0}";
    private static final String DATA_IMPORT_SHEET = "数据导入模板";
    private static final String ERROR_CODE = "getImportErrorExcelFile_error";
    private static final int COLUMN_WIDTH_MULTIPLIER = 3;
    private static final int FIRST_COLUMN_WIDTH_MULTIPLIER = 4;

    /**
     * 导入模板方法
     *
     * @param view
     */
    public void exportExcelTemplate(IFormView view) {
        logger.info("-------- begin exportExcelTemplate --------");

        try {
            SXSSFWorkbook wb = new SXSSFWorkbook(500);
            Throwable exp = null;
            try {
                FormShowParameter parameter = view.getFormShowParameter();
                // 外部系统数据导入模板
                Long sinsurTplId = (Long) parameter.getCustomParam("sinsurTplId");
                // 导入任务ID
                Long importTaskId = (Long) parameter.getCustomParam("importTaskId");
                String dd = DateTimeUtils.format(new Date(), "yyyyMMdd");
                String exportFileName = MessageFormat.format(ResManager.loadKDString("外部系统数据导入任务_数据导入模板_{0}", "ImportTaskGuideExportService_1", "swc-hsas-business", new Object[0]), dd);
                createImportTaskDataSheet(sinsurTplId, wb, importTaskId);
                flushAllAndDownload(wb, exportFileName, view);
            } catch (Throwable var18) {
                exp = var18;
                throw var18;
            } finally {
                if (wb != null) {
                    if (exp != null) {
                        try {
                            wb.close();
                        } catch (Throwable e1) {
                            exp.addSuppressed(e1);
                        }
                    } else {
                        wb.close();
                    }
                }

            }
        } catch (Exception e2) {
            logger.error("ImportTaskGuideExportService  error : ", e2);
            String str = ResManager.loadKDString("下载导入模板失败。", "ImportTaskGuideExportService_0", "swc-hsas-business", new Object[0]);
            view.showErrorNotification(str);
        }
        logger.info("end exportExcelTemplate");
    }

    /**
     * 创建Excel
     *
     * @param sinsurTplId
     * @param wb
     * @param importTaskId
     */
    private void createImportTaskDataSheet(Long sinsurTplId, SXSSFWorkbook wb, Long importTaskId) {
        DynamicObject sinsurData = ImportTaskUtils.getSinsurTplData(sinsurTplId, "id,number,nckd_startline", (QFilter) null);
        int startLine = sinsurData.getInt("nckd_startline");
        String sheetName = ResManager.loadKDString("数据导入模板", "ImportTaskGuideExportService_2", "swc-hsas-business", new Object[0]);
        SXSSFSheet sheet = wb.createSheet(sheetName);
        sheet.setRandomAccessWindowSize(-1);
        SXSSFDrawing drawingPatriarch = sheet.createDrawingPatriarch();
        SXSSFRow headRow = sheet.createRow(startLine - 2);
        CellStyle headDateStyle = getColumnStyle(true, 0, 0, SITShowType.DATE.getCode(), HorizontalAlignment.LEFT, sheet.getWorkbook(), HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex(), true);
        CellStyle headTextStyle = getColumnStyle(true, 0, 0, SITShowType.TEXT.getCode(), HorizontalAlignment.LEFT, sheet.getWorkbook(), HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex(), true);
        CellStyle headRequriedNumStyle = getColumnStyle(true, 0, 0, SITShowType.NUM.getCode(), HorizontalAlignment.LEFT, sheet.getWorkbook(), HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex(), true);
        Font font = sheet.getWorkbook().createFont();
        CellStyle requrriedStyle = getColumnStyle(true, 0, 0, SITShowType.TEXT.getCode(), HorizontalAlignment.LEFT, sheet.getWorkbook(), HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex(), true);
        font.setColor((short) 10);
        requrriedStyle.setFont(font);
        headRequriedNumStyle.setFont(font);
        Map<Long, SinsurPresetItemEnum> itemEnumMap = SinsurPresetItemEnum.getSinsurPresetItemEnumMap();
        List<Map<String, String>> columnHeadList = ImportTaskUtils.getColumnHeadList(sinsurTplId, importTaskId);
        List<Integer> textIndexList = new ArrayList(columnHeadList.size());
        Set<Integer> allIndexSet = new HashSet(columnHeadList.size());
        SinsurPresetItemEnum presetItemEnum = null;
        for (int i = 0; i < columnHeadList.size(); ++i) {
            Map<String, String> columnHead = columnHeadList.get(i);
            String columnIndexStr = (String) columnHead.get("columnIndex");
            String dataTypeIdStr = (String) columnHead.get("datatypeid");
            String name = (String) columnHead.get("name");
            String itemType = (String) columnHead.get("itemType");
            String comment = (String) columnHead.get("comment");
            int columnIndex = Integer.parseInt(columnIndexStr);
            if (allIndexSet.add(columnIndex) && !textIndexList.contains(columnIndex)) {
                if (Long.parseLong(dataTypeIdStr) == DataTypeEnum.STRING.getDbId()) {
                    textIndexList.add(columnIndex);
                }
                if ("0".equals(itemType)) {
                    presetItemEnum = (SinsurPresetItemEnum) itemEnumMap.get(Long.valueOf((String) columnHead.get("id")));
                    CellStyle style = this.getFixCellStyle(presetItemEnum, requrriedStyle, headDateStyle, headTextStyle, headRequriedNumStyle);
                    this.createCell(comment, headRow, columnIndex, presetItemEnum.getImportColumnName(), presetItemEnum.isRequire(), style, this.getDataType(presetItemEnum), drawingPatriarch);
                } else {
                    this.createCell(comment, headRow, columnIndex, name, false, headTextStyle, dataTypeIdStr, drawingPatriarch);
                }
            }
        }

        Iterator<Integer> it = allIndexSet.iterator();
        while (it.hasNext()) {
            int index = (Integer) it.next();
            int columnIndex = sheet.getColumnWidth(index);
            sheet.setColumnWidth(index, columnIndex * 3);
        }

        this.batchSetDefaulColumnStyle(sheet, textIndexList, this.getTextCellStyle(sheet));
    }

    private CellStyle getFixCellStyle(SinsurPresetItemEnum presetItemEnum, CellStyle requrriedStyle, CellStyle headDateStyle, CellStyle headTextStyle, CellStyle headRequriedNumStyle) {
        if (presetItemEnum.isRequire()) {
            return presetItemEnum.getDataTypeId() == DataTypeEnum.NUMBERIC.getDbId() ? headRequriedNumStyle : requrriedStyle;
        } else {
            return presetItemEnum.getDataTypeId() == DataTypeEnum.DATE.getDbId() ? headDateStyle : headTextStyle;
        }
    }

    private void createCell(String comment, SXSSFRow headRow, int cellIndex, String name, boolean isRequried, CellStyle cellStyle, String dataType, SXSSFDrawing drawingPatriarch) {
        SXSSFCell cell = headRow.createCell(cellIndex);
        String value = "";
        if (isRequried) {
            value = "*" + name;
        } else {
            value = name;
        }
        cell.setCellValue(value);
        cell.setCellStyle(cellStyle);
        if (dataType != null) {
            cell.setCellComment(this.getComment(comment, drawingPatriarch, cell));
        }
    }

    private Comment getComment(String commentStr, SXSSFDrawing drawingPatriarch, SXSSFCell cell) {
        Comment comment = drawingPatriarch.createCellComment(new XSSFClientAnchor(cell.getColumnIndex(), cell.getRowIndex(), cell.getColumnIndex() + 1, cell.getRowIndex() + 2, cell.getColumnIndex(), cell.getRowIndex(), cell.getColumnIndex() + 1, cell.getRowIndex() + 2));
        comment.setString(new XSSFRichTextString(commentStr));
        return comment;
    }

    private void batchSetDefaulColumnStyle(SXSSFSheet sheet, List<Integer> indexList, CellStyle cellStyle) {
        Iterator var4 = indexList.iterator();
        while (var4.hasNext()) {
            int index = (Integer) var4.next();
            sheet.setDefaultColumnStyle(index, cellStyle);
        }
    }

    private CellStyle getTextCellStyle(SXSSFSheet sheet) {
        CellStyle textCellStyle = sheet.getWorkbook().createCellStyle();
        textCellStyle.setDataFormat((short) 49);
        return textCellStyle;
    }

    private String getDataType(SinsurPresetItemEnum presetItemEnum) {
        if (presetItemEnum.getDataTypeId() == DataTypeEnum.DATE.getDbId()) {
            return SITShowType.DATE.getCode();
        } else {
            return presetItemEnum.getDataTypeId() == DataTypeEnum.NUMBERIC.getDbId() ? SITShowType.NUM.getCode() : SITShowType.TEXT.getCode();
        }
    }

    private void flushAllAndDownload(SXSSFWorkbook wb, String fileName, IFormView view) {
        String url = SITExportDataHelper.storeFile(wb, fileName);
        if (StringUtils.isNotEmpty(url)) {
            view.download(url);
        }
    }

    public String getImportErrorExcelFile(List<Map<Integer, String>> dataHeadList, List<Map<Integer, String>> dataRowList, List<Map<String, String>> errDataList,
                                          int headIndex, String writeTaskType, Map<Integer, List<Map<String, String>>> columnIndexMap, boolean hasWorkStartDate) {
        logger.info("getImportErrorExcelFile begin");
        String url = "";
        int rowNum = headIndex + dataRowList.size() + 2;

        try {
            SXSSFWorkbook wb = new SXSSFWorkbook(rowNum);

            try {
                String dd = DateTimeUtils.format(new Date(), "yyyyMMdd");
                String exportFileName = MessageFormat.format(ResManager.loadKDString("外部数据导入任务_数据导入失败结果_{0}", "ImportTaskGuideExportService_3", "swc-hsas-business", new Object[0]), dd);
                String sheetName = ResManager.loadKDString("数据导入模板", "ImportTaskGuideExportService_2", "swc-hsas-business", new Object[0]);
                SXSSFSheet sheet = wb.createSheet(sheetName);
                sheet.setRandomAccessWindowSize(-1);
                SXSSFDrawing drawingPatriarch = sheet.createDrawingPatriarch();
                this.createHeadRow(dataHeadList, headIndex, sheet, drawingPatriarch, writeTaskType);
                this.batchSetDefaulColumnStyle(sheet, this.getTextColumnIndexList(columnIndexMap), this.getTextCellStyle(sheet));
                Set<Integer> allIndexSet = new HashSet(columnIndexMap.size() + 12);
                Iterator var18 = columnIndexMap.keySet().iterator();

                while (true) {
                    int index;
                    if (!var18.hasNext()) {
                        allIndexSet.addAll(Lists.newArrayList(new Integer[]{1, 2, 3, 4}));
                        sheet.setColumnWidth(0, sheet.getColumnWidth(0) * 4);
                        var18 = allIndexSet.iterator();

                        while (var18.hasNext()) {
                            index = (Integer) var18.next();
                            int columnWidth = sheet.getColumnWidth(index);
                            sheet.setColumnWidth(index, columnWidth * 3);
                        }

                        this.addDataRow(dataRowList, errDataList, headIndex, wb, sheet);
                        url = SITExportDataHelper.storeFile(wb, exportFileName);
                        break;
                    }

                    index = (Integer) var18.next();
                    allIndexSet.add(index + 1);
                }
            } catch (Throwable e) {
                throw e;
            }
        } catch (Exception e) {
            logger.error("getImportErrorExcelFile  error : ", e);
            throw new KDException(e, new ErrorCode("getImportErrorExcelFile_error", e.getMessage()), new Object[0]);
        }

        logger.info("getImportErrorExcelFile end");
        return url;
    }

    private void createHeadRow(List<Map<Integer, String>> dataHeadList, int headIndex, SXSSFSheet sheet, SXSSFDrawing drawingPatriarch, String writeTaskType) {
        SXSSFRow headRow = sheet.createRow(headIndex);
        CellStyle headTextStyle = getColumnStyle(true, 0, 0, SITShowType.TEXT.getCode(), HorizontalAlignment.LEFT, sheet.getWorkbook(), HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex(), true);
        SXSSFCell errMsgCell = headRow.createCell(0);
        errMsgCell.setCellValue(ResManager.loadKDString("失败原因", "CalResultCoverImportService_58", "swc-hsas-business", new Object[0]));
        errMsgCell.setCellStyle(headTextStyle);
        Font font = sheet.getWorkbook().createFont();
        CellStyle requrriedStyle = getColumnStyle(true, 0, 0, SITShowType.TEXT.getCode(), HorizontalAlignment.LEFT, sheet.getWorkbook(), HSSFColor.HSSFColorPredefined.GREY_25_PERCENT.getIndex(), true);
        font.setColor((short)10);
        requrriedStyle.setFont(font);
        Set<Integer> requireFixColumnSet = ImportTaskUtils.getExportTplRequireColumnSet();
        Map<Integer, String> headMap = (Map)dataHeadList.get(0);
        CellStyle style = null;

        Map.Entry entry;
        for(Iterator var15 = headMap.entrySet().iterator(); var15.hasNext(); this.createCell("", headRow, (Integer)entry.getKey() + 1, (String)entry.getValue(), false, style, (String)null, drawingPatriarch)) {
            entry = (Map.Entry)var15.next();
            if (requireFixColumnSet.contains(entry.getKey())) {
                style = requrriedStyle;
            } else {
                style = headTextStyle;
            }
        }
    }

    private List<Integer> getTextColumnIndexList(Map<Integer, List<Map<String, String>>> columnIndexMap) {
        List<Integer> textIndexList = new ArrayList(columnIndexMap.size() + 12);
        textIndexList.addAll(Lists.newArrayList(new Integer[]{1, 2, 3, 4}));
        Iterator var5 = columnIndexMap.entrySet().iterator();
        while(var5.hasNext()) {
            Map.Entry<Integer, List<Map<String, String>>> entry = (Map.Entry)var5.next();
            List<Map<String, String>> paramMapList = (List)entry.getValue();
            if (!CollectionUtils.isEmpty(paramMapList)) {
                String dataTypeIdStr = (String)((Map)paramMapList.get(0)).get("datatypeid");
                if (!StringUtils.isEmpty(dataTypeIdStr) && Long.parseLong(dataTypeIdStr) == DataTypeEnum.STRING.getDbId()) {
                    textIndexList.add((Integer)entry.getKey() + 1);
                }
            }
        }
        return textIndexList;
    }

    private void addDataRow(List<Map<Integer, String>> dataRowList, List<Map<String, String>> errDataList, int headIndex, SXSSFWorkbook wb, SXSSFSheet sheet) {
        Map<Integer, List<String>> errorMap = this.getErrorMap(errDataList);
        boolean isTplError = "1".equals(((Map)errDataList.get(0)).get("isAll"));
        int tplIndex = headIndex++;
        CellStyle errColumnStyle = getColumnStyle(true, 0, 0, "text", HorizontalAlignment.LEFT, wb, (short)9, true);
        Font font = wb.createFont();
        font.setColor((short)10);
        errColumnStyle.setFont(font);
        CellStyle columnStyle = getColumnStyle(true, 0, 0, "text", HorizontalAlignment.LEFT, wb, (short)9, true);
        List<String> errorList = null;
        Map<Integer, String> rowMap = null;
        SXSSFRow dataRow = null;
        SXSSFCell cell = null;
        int index = 0;

        for(int length = dataRowList.size(); index < length; ++index) {
            errorList = (List)errorMap.get(index);
            if (isTplError) {
                errorList = (List)errorMap.get(tplIndex);
            }

            if (errorList != null) {
                rowMap = (Map)dataRowList.get(index);
                dataRow = sheet.createRow(headIndex);
                ++headIndex;
                cell = dataRow.createCell(0);
                cell.setCellStyle(errColumnStyle);
                cell.setCellValue(this.getErrorMsg(errorList));
                Iterator var18 = rowMap.entrySet().iterator();

                while(var18.hasNext()) {
                    Map.Entry<Integer, String> entry = (Map.Entry)var18.next();
                    cell = dataRow.createCell((Integer)entry.getKey() + 1);
                    cell.setCellStyle(columnStyle);
                    cell.setCellValue((String)entry.getValue());
                }
            }
        }
    }

    private Map<Integer, List<String>> getErrorMap(List<Map<String, String>> errDataList) {
        Map<Integer, List<String>> errorMap = new HashMap(16);
        List<String> tempList = null;
        Iterator var4 = errDataList.iterator();

        while(var4.hasNext()) {
            Map<String, String> tempMap = (Map)var4.next();
            tempList = (List)errorMap.getOrDefault(Integer.valueOf((String)tempMap.get("dataIndex")), new ArrayList());
            tempList.add(tempMap.get("errMsg"));
            errorMap.put(Integer.valueOf((String)tempMap.get("dataIndex")), tempList);
        }

        return errorMap;
    }

    private String getErrorMsg(List<String> errorList) {
        StringBuilder key = new StringBuilder();
        int index = 1;

        for(Iterator var4 = errorList.iterator(); var4.hasNext(); ++index) {
            String msg = (String)var4.next();
            key.append(index).append('.').append(' ').append(msg).append(' ');
        }

        return key.toString();
    }


    public static CellStyle getColumnStyle(boolean isTmpl, int precision, int scale, String columnType, HorizontalAlignment alignment, SXSSFWorkbook wb, short colorIndex, boolean needBoard) {
        CellStyle headColumnStyle = wb.createCellStyle();
        DataFormat dataFormat = wb.createDataFormat();
        short format;
        if (!isTmpl) {
            if (StringUtils.equals(SITShowType.DATE.getCode(), columnType)) {
                format = dataFormat.getFormat("yyyy-MM-dd");
            } else {
                String amountFormat;
                if (StringUtils.equals(SITShowType.AMOUNT.getCode(), columnType)) {
                    amountFormat = getAmountFormat(precision);
                    format = dataFormat.getFormat(amountFormat);
                } else if (StringUtils.equals(SITShowType.NUM.getCode(), columnType)) {
                    amountFormat = getAmountFormat(scale);
                    format = dataFormat.getFormat(amountFormat);
                } else {
                    format = dataFormat.getFormat("text");
                }
            }
        } else if (StringUtils.equals(SITShowType.DATE.getCode(), columnType)) {
            format = dataFormat.getFormat("yyyy-MM-dd");
        } else {
            format = dataFormat.getFormat("text");
        }

        headColumnStyle.setDataFormat(format);
        if (needBoard) {
            headColumnStyle.setBorderBottom(BorderStyle.HAIR);
            headColumnStyle.setBorderTop(BorderStyle.HAIR);
            headColumnStyle.setBorderLeft(BorderStyle.HAIR);
            headColumnStyle.setBorderRight(BorderStyle.HAIR);
        }

        headColumnStyle.setFillForegroundColor(colorIndex);
        headColumnStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        headColumnStyle.setAlignment(alignment);
        headColumnStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        headColumnStyle.setHidden(true);
        return headColumnStyle;
    }

    private static String getAmountFormat(int precision) {
        StringBuilder format = new StringBuilder("0");
        if (precision > 0) {
            format.append('.');

            for(int i = 0; i < precision; ++i) {
                format.append('0');
            }
        }

        return format.toString();
    }


}