package shkd.repc.repmd.template;

import kd.bos.context.RequestContext;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.dataentity.utils.StringUtils;
import kd.bos.entity.ExtendedDataEntity;
import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
import kd.bos.entity.plugin.AddValidatorsEventArgs;
import kd.bos.entity.plugin.args.AfterOperationArgs;
import kd.bos.entity.validate.AbstractValidator;
import kd.bos.form.*;
import kd.bos.form.control.Control;
import kd.bos.form.control.EntryGrid;
import kd.bos.form.control.events.ItemClickEvent;
import kd.bos.form.events.MessageBoxClosedEvent;
import kd.bos.form.plugin.AbstractFormPlugin;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.sdk.plugin.Plugin;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import shkd.repc.repmd.template.util.ExportTemplateUtil;
import shkd.repc.repmd.template.util.Template;

import java.math.BigDecimal;
import java.util.*;

/**
 * 面积数据导出-二开插件
 */
public class AreaDataExportPlugin extends AbstractFormPlugin implements Plugin {


    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        this.addItemClickListeners("qeug_advcontoolbarap");
    }

    @Override
    public void itemClick(ItemClickEvent evt) {
        super.itemClick(evt);
        if (StringUtils.equals("qeug_areadataexport", evt.getItemKey())) {
            DynamicObjectCollection productEntry = this.getModel().getEntryEntity("productentry");
            if (null==productEntry||productEntry.size()==0){
                this.getView().showMessage("暂无可导出数据!");
                return;
            }
            EntryGrid entryGrid = this.getControl("productentry");
            int[] selectRows = entryGrid.getSelectRows();
            String top="导出确认提示";
            String body;
            //默认导出
            if (selectRows.length==0){
                body = "默认导出所有【产品构成】数据?";
                this.showExportMessage(top,body,"default");
            }else {
                body = "导出 " + selectRows.length + " 行【产品构成】数据?";
                this.showExportMessage(top,body,"select");
            }
        }
    }

    @Override
    public void confirmCallBack(MessageBoxClosedEvent evt) {
        super.confirmCallBack(evt);
        String callBackId = evt.getCallBackId();
        StringBuilder tipsBuffer = new StringBuilder();

        if (StringUtils.equalsIgnoreCase("export_area", callBackId) && evt.getResult().getValue() == 6) {
            String customValue = evt.getCustomVaule();
            boolean isDefaultExport = "default".equals(customValue);

            // 获取模板
            DynamicObject templateObj = getTemplate();
            if (templateObj == null) {
                return;
            }

            // 读取系统模板
            Control productView = this.getView().getControl("productentry");
            Control areaView = this.getView().getControl("qeug_subentryentity");
            List<Template> templateList = ExportTemplateUtil.readSysTemplate(templateObj, productView, areaView, tipsBuffer);
            if (templateList.isEmpty()) {
                return;
            }

            // 创建 Excel
            XSSFWorkbook workbook = new XSSFWorkbook();
            XSSFSheet sheet = createExcelSheet(workbook, templateList, areaView);

            // 获取表头信息(第三行)
            List<String> columnHeaders = getColumnHeaders(sheet);

            // 获取数据
            DynamicObjectCollection productEntry = this.getModel().getEntryEntity("productentry");
            List<DynamicObject> exportData = isDefaultExport ? new ArrayList<>(productEntry) : getSelectedData(productEntry);

            // 填充数据
            fillExcelData(sheet, exportData, columnHeaders);

            // 上传文件并提供下载链接
            exportAndDownload(workbook, customValue);

            tipsBuffer.append("导出成功");
            this.getView().showSuccessNotification(tipsBuffer.toString());
        }
    }

    /**
     * 获取模板对象
     */
    private DynamicObject getTemplate() {
        QFilter numberFilter = new QFilter("number", QCP.equals, "repmd_projectbill_IMPT_ENTRY");
        return BusinessDataServiceHelper.loadSingle("bos_importentry_template", numberFilter.toArray());
    }

    /**
     * 创建 Excel Sheet 并填充标题、描述、表头等
     */
    private XSSFSheet createExcelSheet(XSSFWorkbook workbook, List<Template> templateList, Control areaView) {
        XSSFSheet sheet = workbook.createSheet("产品构成 # productentry");
        ExportTemplateUtil.createTitleRow(sheet, workbook);
        ExportTemplateUtil.createDescriptionRow(sheet, workbook);
        ExportTemplateUtil.createTemplateHeaders(sheet, workbook, templateList);
        ExportTemplateUtil.otherStyleSet(sheet, areaView);
        return sheet;
    }

    /**
     * 获取第三行的表头信息
     */
    private List<String> getColumnHeaders(XSSFSheet sheet) {
        List<String> columnHeaders = new ArrayList<>();
        XSSFRow thirdRow = sheet.getRow(2);
        if (thirdRow != null) {
            for (int cellIndex = 0; cellIndex < thirdRow.getLastCellNum(); cellIndex++) {
                XSSFCell cell = thirdRow.getCell(cellIndex);
                columnHeaders.add(cell != null ? cell.getStringCellValue().trim() : ""); // 避免 null
            }
        }
        return columnHeaders;
    }

    /**
     * 获取选中的数据
     */
    private List<DynamicObject> getSelectedData(DynamicObjectCollection productEntry) {
        List<DynamicObject> selectedData = new ArrayList<>();
        EntryGrid entryGrid = this.getControl("productentry");
        int[] selectedRows = entryGrid.getSelectRows();
        for (int row : selectedRows) {
            selectedData.add(productEntry.get(row));
        }
        return selectedData;
    }

    /**
     * 填充 Excel 数据
     */
    private void fillExcelData(XSSFSheet sheet, List<DynamicObject> productEntries, List<String> columnHeaders) {
        int rowIndex = 4; // 从 Excel 第 5 行开始填充
        for (DynamicObject productObj : productEntries) {
            if (productObj == null) continue;

            String productTypeNumber = productObj.getString("productentry_producttype.number");
            String productTypeName = productObj.getString("productentry_producttype.name");
            DynamicObjectCollection areaEntries = productObj.getDynamicObjectCollection("qeug_subentryentity");

            if (areaEntries != null && !areaEntries.isEmpty()) {
                for (DynamicObject areaObj : areaEntries) {
                    XSSFRow dataRow = sheet.createRow(rowIndex);
                    int cellIndex = 0;

                    for (String header : columnHeaders) {
                        XSSFCell cell = dataRow.createCell(cellIndex);

                        if ("productentry_producttype.number".equals(header)) {
                            cell.setCellValue(productTypeNumber);
                        } else if ("productentry_producttype.name".equals(header)) {
                            cell.setCellValue(productTypeName);
                        } else {
                            Object value = areaObj.get(header);
                            setCellValue(cell, value);
                        }
                        cellIndex++;
                    }
                    rowIndex++;
                }
            }
        }
    }

    /**
     * 设置 Excel 单元格值
     */
    private void setCellValue(XSSFCell cell, Object value) {
        if (value instanceof String) {
            cell.setCellValue((String) value);
        } else if (value instanceof BigDecimal) {
            cell.setCellValue(((BigDecimal) value).doubleValue());
        } else if (value instanceof Integer) {
            cell.setCellValue((Integer) value);
        } else if (value instanceof Double) {
            cell.setCellValue((Double) value);
        } else if (value != null) {
            cell.setCellValue(value.toString());
        }
    }

    /**
     * 导出 Excel 并提供下载链接
     */
    private void exportAndDownload(XSSFWorkbook workbook, String fileName) {
        String uploadedFilePath = ExportTemplateUtil.uploadExcel(workbook, fileName);
        String url = RequestContext.get().getClientFullContextPath() + "/attachment/download.do?path=" + uploadedFilePath;
        this.getView().openUrl(url);
    }

    private void showExportMessage(String top,String body,String customValue){
        // 基本信息
        // 备注: \r\n 可换行
        //String msg = "消息头\r\n message header...";
        // 详细消息
        //String detail = "消息体\r\nmessage body...";
        // 消息框按钮类型
        // None:不启用  Toast:简短提示,几秒后消失
        MessageBoxOptions options = MessageBoxOptions.OKCancel;
        // 确认提示类型
        // Default:默认提示  Save:保存提交类提示  Delete:删除类提示  Wait:等待类提示  Fail:失败类提示
        ConfirmTypes confirmTypes = ConfirmTypes.Default;
        // 确认框回调
        ConfirmCallBackListener callBack = new ConfirmCallBackListener("export_area", this);
        // 按钮名称
        // 注意: 按钮名称参数Map的key值必须和 options 参数相对应, 否则按钮名称修改不生效!
        // 例: options 使用 MessageBoxOptions.OKCancel, 则 按钮名称参数Map的key必须为2 or 6
        //    options 使用 MessageBoxOptions.AbortRetryIgnore, 则 按钮名称参数Map的key必须为3 or 4 or 5
        // none-0; ok-1; cancel-2; abort-3; retry-4; ignore-5; yes-6; no-7; custom-8
        // -----------------------------------------------------------------
        //             options                   |    btnNameMaps的key的取值
        //   MessageBoxOptions.None              |           2
        //   MessageBoxOptions.OK                |           2
        //   MessageBoxOptions.OKCancel          |         2 & 6
        //   MessageBoxOptions.AbortRetryIgnore  |       3 & 4 & 5
        //   MessageBoxOptions.YesNoCancel       |       6 & 7 & 2
        //   MessageBoxOptions.YesNo             |         6 & 7
        //   MessageBoxOptions.RetryCancel       |         4 & 2
        //   MessageBoxOptions.Toast             |           2
        // -----------------------------------------------------------------
        Map<Integer, String> btnNameMaps = new HashMap<>();
        btnNameMaps.put(2, "取消");
        btnNameMaps.put(6, "确认");
        // 用户自定义参数,前端会在afterConfirm中返回
        //String customValue = "allowExport";
        this.getView().showConfirm(top, body, options, confirmTypes, callBack, btnNameMaps,customValue);
    }
}