package hw.tagApi.service.utils;

import hw.tagApi.common.constant.HttpStatus;
import hw.tagApi.common.core.domain.AjaxResult;
import hw.tagApi.common.utils.poi.ExcelUtil;
import hw.tagApi.common.utils.spring.SpringUtils;
import hw.tagApi.common.utils.uuid.UUID;
import hw.tagApi.service.constant.ApiConstants;
import hw.tagApi.service.domain.HwTagRecord;
import hw.tagApi.service.domain.ImportParams;
import hw.tagApi.system.domain.SysAttachInfo;
import hw.tagApi.system.service.ISysAttachInfoService;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 标签Excel工具类
 */
@Component
public class TagExcelUtil {
    private static final Logger log = LoggerFactory.getLogger(TagExcelUtil.class);

    /**
     * 解析标签数据Excel
     *
     * @param is Excel文件输入流
     * @return 解析结果，包含订单信息、标签数据列表和文件名
     */
    public static Map<String, Object> parseTagExcel(InputStream is) {
        Map<String, Object> result = new HashMap<>();
        try (Workbook workbook = WorkbookFactory.create(is)) {
            Sheet sheet = workbook.getSheetAt(0);

            Row row = sheet.getRow(0);
            String exportTemplate = getCellStringValue(row.getCell(0));//导出再导入模板
            boolean exportTemplateFlag = StringUtils.hasText(exportTemplate) && exportTemplate.equals("RID");
            boolean isInventoryFlag = validateCells(row.getCell(8), row.getCell(9));//桌面读写器盘点模板
            boolean codeWriterFlag = validateCells(row.getCell(2), row.getCell(5));//写码机写读盘点模板

            if (exportTemplateFlag) {
                result.put("tagList", new ArrayList<>());
                result.put("orderInfo", new HashMap<>());
                result.put("templateType", ApiConstants.IMPORT_TEMPLATE_ONE);
            } else if (isInventoryFlag) {
                List<Map<String, String>> tagList = parseTagList(sheet, 1);
                result.put("tagList", tagList);
                result.put("orderInfo", new HashMap<>());
                result.put("templateType", ApiConstants.IMPORT_TEMPLATE_TWO);
            } else if (codeWriterFlag) {
                List<Map<String, String>> tagList = parseTagList(sheet, 1);
                result.put("tagList", tagList);
                result.put("orderInfo", new HashMap<>());
                result.put("templateType", ApiConstants.IMPORT_TEMPLATE_FOUR);
            } else {
                // 解析订单信息
                Map<String, String> orderInfo = parseOrderInfo(sheet);
                result.put("orderInfo", orderInfo);
                // 解析标签数据
                List<Map<String, String>> tagList = parseTagList(sheet, 7);
                result.put("tagList", tagList);
                result.put("templateType", ApiConstants.IMPORT_TEMPLATE_THREE);
            }

            return result;
        } catch (Exception e) {
            log.error("解析Excel文件失败", e);
            throw new RuntimeException("解析Excel文件失败: " + e.getMessage());
        }
    }

    /**
     * 校验单元格值是否符合要求
     *
     * @param epcCell epc
     * @param tidCell tid
     * @return 校验结果
     */
    private static boolean validateCells(Cell epcCell, Cell tidCell) {
        // 获取单元格值并转换为字符串
        String valueI1 = getCellStringValue(epcCell);
        String valueJ1 = getCellStringValue(tidCell);

        // 校验是否满足条件
        return "EPC".equalsIgnoreCase(valueI1) && "TID".equalsIgnoreCase(valueJ1);
    }

    /**
     * 解析订单信息（前5行）
     */
    private static Map<String, String> parseOrderInfo(Sheet sheet) {
        Map<String, String> orderInfo = new HashMap<>();
        try {
            // 订单号 - 格式: 订单号：Lot20250109
            Row orderRow = sheet.getRow(0);
            String orderNoCell = getCellStringValue(orderRow.getCell(0));
            orderInfo.put("orderNo", orderNoCell.substring(orderNoCell.indexOf("：") + 1).trim());

            // 批次号 - 格式: 批次号：002
            Row batchRow = sheet.getRow(1);
            String batchNoCell = getCellStringValue(batchRow.getCell(0));
            orderInfo.put("batchNo", batchNoCell.substring(batchNoCell.indexOf("：") + 1).trim());

            // 操作人员号 - 格式: 操作人员号：WJL
            Row operatorRow = sheet.getRow(2);
            String operatorIdCell = getCellStringValue(operatorRow.getCell(0));
            orderInfo.put("operatorId", operatorIdCell.substring(operatorIdCell.indexOf("：") + 1).trim());

            // 加工时间 - 格式: 加工时间：2025/1/9 14:00:19
            Row timeRow = sheet.getRow(3);
            String processTimeCell = getCellStringValue(timeRow.getCell(0));
            String processTime = processTimeCell.substring(processTimeCell.indexOf("：") + 1).trim();
            if (processTime.contains("/")) {
                // 转换日期格式为标准格式
                String[] parts = processTime.split(" ");
                if (parts.length == 2) {
                    String datePart = parts[0].replace("/", "-");
                    processTime = datePart + " " + parts[1];
                }
            }
            orderInfo.put("processTime", processTime);

            // 数量信息 - 格式: 合格数量：2500，不合格数量：0，总数量：2500
            Row quantityRow = sheet.getRow(4);
            String quantityCell = getCellStringValue(quantityRow.getCell(0));
            String[] quantities = quantityCell.split("，");
            for (String quantity : quantities) {
                String[] parts = quantity.split("：");
                if (parts.length == 2) {
                    String value = parts[1].trim();
                    if (quantity.contains("合格数量") && !quantity.contains("不合格数量")) {
                        orderInfo.put("qualifiedCount", value);
                    } else if (quantity.contains("不合格数量")) {
                        orderInfo.put("unqualifiedCount", value);
                    } else if (quantity.contains("总数量")) {
                        orderInfo.put("totalCount", value);
                    }
                }
            }

            log.info("解析到的订单信息: {}", orderInfo);
        } catch (Exception e) {
            log.error("解析订单信息失败", e);
            throw new RuntimeException("解析订单信息失败: " + e.getMessage());
        }
        return orderInfo;
    }

    /**
     * 解析标签数据列表（从第8行开始）
     *
     * @param sheet    sheet
     * @param startRow （从第8行开始）
     * @return ArrayList
     */
    private static List<Map<String, String>> parseTagList(Sheet sheet, int startRow) {
        List<Map<String, String>> tagList = new ArrayList<>();
        try {
            // 获取表头
            Row headerRow = sheet.getRow(startRow - 1);
            List<String> headers = new ArrayList<>();
            // 获取最后一列的索引
            int lastColumn = headerRow.getLastCellNum();

            // 处理表头
            for (int i = 0; i < lastColumn; i++) {
                Cell cell = headerRow.getCell(i);
                String headerValue = getCellStringValue(cell);
                // 如果表头为空，使用列索引作为键
                if (!StringUtils.hasText(headerValue)) {
                    headerValue = "Column_" + i;
                }
                headers.add(headerValue);
            }

            // 解析数据行
            Row row;
            int thisStartRow = startRow;
            while ((row = sheet.getRow(thisStartRow)) != null) {
                Map<String, String> tagData = new HashMap<>();
                boolean hasData = false;

                // 使用lastColumn而不是headers.size()
                for (int i = 0; i < lastColumn; i++) {
                    String value = getCellStringValue(row.getCell(i));
                    if (StringUtils.hasText(value)) {
                        hasData = true;
                        tagData.put(headers.get(i), value);
                    }
                }

                if (hasData) {
                    tagList.add(tagData);
                } else {
                    break;
                }
                thisStartRow++;
            }
        } catch (Exception e) {
            log.error("解析标签数据失败", e);
            throw new RuntimeException("解析标签数据失败: " + e.getMessage());
        }
        return tagList;
    }

    /**
     * 获取单元格的字符串值
     */
    private static String getCellStringValue(Cell cell) {
        if (cell == null) {
            return "";
        }

        String value = "";
        switch (cell.getCellType()) {
            case STRING:
                value = cell.getStringCellValue();
                break;
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    value = sdf.format(cell.getDateCellValue());
                } else {
                    value = String.valueOf((long) cell.getNumericCellValue());
                }
                break;
            case BOOLEAN:
                value = String.valueOf(cell.getBooleanCellValue());
                break;
            default:
                break;
        }
        return value.trim();
    }

    /**
     * 生成标签Excel文件
     *
     * @param records  标签记录列表
     * @param fileName 文件名
     * @return 文件路径
     */
    public static String generateTagExcel(List<HwTagRecord> records, String fileName) {
        try {
            // 使用ExcelUtil导出
            ExcelUtil<HwTagRecord> util = new ExcelUtil<>(HwTagRecord.class);
            // 导出Excel并获取结果
            AjaxResult result = util.exportExcel(records, "标签数据");
            if (result != null && HttpStatus.SUCCESS == Integer.parseInt(String.valueOf(result.get(AjaxResult.CODE_TAG)))) {
                String exportFileName = (String) result.get(AjaxResult.MSG_TAG);
                if (exportFileName == null || exportFileName.isEmpty()) {
                    throw new RuntimeException("导出文件名不能为空");
                }
                String fileUrl = ApiConstants.BASE_URL + UUID.randomUUID();
                String absoluteFile = ExcelUtil.getAbsoluteFile(exportFileName);
                // 存储文件信息
                saveFileInfo(fileUrl, fileName, absoluteFile);
                log.info("Excel文件生成成功: {}", absoluteFile);
                return fileUrl;
            } else {
                String errorMsg = result != null ? (String) result.get(AjaxResult.MSG_TAG) : "导出失败";
                throw new RuntimeException("导出Excel失败: " + errorMsg);
            }
        } catch (Exception e) {
            log.error("生成Excel文件失败", e);
            throw new RuntimeException("生成Excel文件失败: " + e.getMessage());
        }
    }

    /**
     * 保存文件信息到数据库
     *
     * @param filePath      文件路径
     * @param fileName      文件名
     * @param attachAddress 附件地址
     */
    private static void saveFileInfo(String filePath, String fileName, String attachAddress) {
        try {
            SysAttachInfo sysAttachInfo = new SysAttachInfo();
            sysAttachInfo.setAttachUrl(filePath);
            sysAttachInfo.setAttachAddress(attachAddress);
            sysAttachInfo.setAttachName(fileName);
            sysAttachInfo.setAttachType("1");
            Date currentDate = new Date();
            sysAttachInfo.setExpirationTime(new Date(currentDate.getTime() + ApiConstants.PASS_TIME));
            SpringUtils.getBean(ISysAttachInfoService.class).insertSysAttachInfo(sysAttachInfo);
            log.info("文件信息保存成功: {}", filePath);
        } catch (Exception e) {
            log.error("保存文件信息失败", e);
            throw new RuntimeException("保存文件信息失败: " + e.getMessage());
        }
    }

    /**
     * 检查原始字符串是否以目标字符串匹配（支持通配符'*'匹配）
     *
     * @param originalField 原始字符串（待检查的字符串）
     * @param checkField    目标字符串（可包含通配符'*'，表示该位置任意字符均匹配）
     * @return 返回匹配结果
     */
    public static boolean startsWithCheck(String originalField, String checkField) {
        if (originalField == null || checkField == null || originalField.length() < checkField.length()) {
            return false;
        }
        char wildcard = '*';
        char[] originalChars = originalField.toCharArray();
        char[] checkChars = checkField.toCharArray();
        // 逐字符比对（跳过checkField中的通配符）
        for (int i = 0; i < checkChars.length; i++) {
            if (checkChars[i] == wildcard) {
                continue;// 通配符位置跳过校验
            }
            if (originalChars[i] != checkChars[i]) {
                return false;// 非通配符位置字符不匹配
            }
        }
        return true;
    }

    /**
     * 当检测到"-"时，会将其拆分为连续的数字序列
     *
     * @param input 字符串
     * @return
     */
    public static List<String> splitHorizontalBarString(String input, Boolean zeroFlag) {
        List<String> result = new ArrayList<>();

        if (input == null || input.isEmpty()) {
            return result;
        }

        if (input.contains("-")) {
            String[] parts = input.split("-");
            if (parts.length == 2) {
                try {
                    int start = Integer.parseInt(parts[0]);
                    int end = Integer.parseInt(parts[1]);

                    // 确保start <= end
                    if (start > end) {
                        int temp = start;
                        start = end;
                        end = temp;
                    }

                    // 生成连续数字序列
                    for (int i = start; i <= end; i++) {
                        // 保持原始位数，前面补零
                        if (zeroFlag) {
                            result.add(String.valueOf(i));
                        } else {
                            String formatted = String.format("%0" + parts[0].length() + "d", i);
                            result.add(formatted);
                        }
                    }
                } catch (NumberFormatException e) {
                    // 如果无法解析为数字，则直接添加原始字符串
                    result.add(input);
                }
            } else {
                // 如果"-"分割后不是两部分，则直接添加原始字符串
                result.add(input);
            }
        } else {
            // 没有"-"，直接添加
            result.add(input);
        }

        return result;
    }

    /**
     * 提取导入参数
     */
    public static ImportParams extractImportParams(Map<String, Object> fields) {
        ImportParams params = new ImportParams();
        params.setImportMode(String.valueOf(fields.get("导入模式")));
        params.setFileUrl(String.valueOf(fields.get("文件链接")));
        params.setTIDCheck(String.valueOf(fields.getOrDefault("TID校验", "")));
        params.setEPCCheck(String.valueOf(fields.getOrDefault("EPC校验", "")));
        params.setEPCNumberCheckLength(Integer.parseInt(String.valueOf(fields.getOrDefault("EPC位数校验", "0"))));
        params.setFileName(String.valueOf(fields.getOrDefault("文件名", "")));
        params.setModel(String.valueOf(fields.getOrDefault("型号", "")));
        params.setDestinationInfo(String.valueOf(fields.getOrDefault("去向信息", "")));
        params.setLibraryFlag(String.valueOf(fields.getOrDefault("是否在库", "")));
        params.setIntendedUse(String.valueOf(fields.getOrDefault("计划用途", "")));
        params.setRemark(String.valueOf(fields.getOrDefault("备注", "")));
        return params;
    }
} 