package com.cf.imes.module.executor.util.fileConversion.admin.files.excel;

import com.cf.imes.module.executor.util.fileConversion.admin.ToolUtil;
import com.monitorjbl.xlsx.StreamingReader;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;


/**
 * 大文件 excel 导入
 */
@Slf4j
@Component
public class LargeFilesUtils {

    public List<OrderPlateImportExcelVO>[] importExcelLargeFile(MultipartFile file) {
        try (InputStream inputStream = file.getInputStream();
             Workbook workbook = StreamingReader.builder()
                     .rowCacheSize(1000)
                     .bufferSize(10240)
                     .open(inputStream)) {

            Sheet sheet = workbook.getSheetAt(0);
            return processRows(sheet);

        } catch (Exception e) {
            log.error("Error processing Excel file", e);
            throw new RuntimeException("Failed to process Excel file", e);
        }
    }

    private List<OrderPlateImportExcelVO>[] processRows(Sheet sheet) { // 一个是order，一个是plateLiat
        List<OrderPlateImportExcelVO> preDelimiterList = new ArrayList<>();
        List<OrderPlateImportExcelVO> postDelimiterList = new ArrayList<>();
        AtomicBoolean fastRowBoolean = new AtomicBoolean(false);
        AtomicBoolean delimiterFound = new AtomicBoolean(false);
        AtomicBoolean stopReading = new AtomicBoolean(false);

        for (Row row : sheet) {
            if (stopReading.get() || shouldSkipRow(row, delimiterFound,fastRowBoolean,  stopReading)) {
                continue;
            }

            OrderPlateImportExcelVO vo = createOrderPlateFromRow(row);
            if (delimiterFound.get()) {
                postDelimiterList.add(vo);
            } else {
                preDelimiterList.add(vo);
            }

            handleSpecialDelimiters(row, () -> delimiterFound.set(true), () -> stopReading.set(true));
        }

        logResults(preDelimiterList.size(), postDelimiterList.size());

        return new List[] { preDelimiterList, postDelimiterList.stream()
                .filter(item -> !ToolUtil.isAllFieldsEmptyOrNull(item))
                .collect(Collectors.toList()) };
    }

    private boolean shouldSkipRow(Row row, AtomicBoolean delimiterFound, AtomicBoolean fastRowBoolean, AtomicBoolean stopReading) {
        if (stopReading.get()) return true;

        String firstCellValue = getFirstCellValue(row);
        if ("###".equals(firstCellValue) && !delimiterFound.get()) {
            delimiterFound.set(true);
            fastRowBoolean.set(true);
            return true;
        }

        if (fastRowBoolean.get()) {
            fastRowBoolean.set(false);
            return true;
        }

        if ("***".equals(firstCellValue)) {
            stopReading.set(true);
            return true;
        }

        return false;
    }

    private String getFirstCellValue(Row row) {
        Cell cell = row.getCell(0);
        return cell != null ? cell.getStringCellValue() : "";
    }

    private OrderPlateImportExcelVO createOrderPlateFromRow(Row row) {
        OrderPlateImportExcelVO vo = new OrderPlateImportExcelVO();

        for (Cell cell : row) {
            setOrderPlateProperty(vo, cell);
        }

        return vo;
    }

    private void setOrderPlateProperty(OrderPlateImportExcelVO vo, Cell cell) {
        String value = cell.getStringCellValue();
        int index = cell.getColumnIndex();

            switch (index) {
                case 0:
                    vo.setOrdinal(value);
                    break;
                case 1:// 类型
                    vo.setGoodType(value);
                    break;
                case 2:// 物料编码
                    vo.setGoodsId(value);
                    break;
                case 3:// 商品名称
                    vo.setGoodsName(value);
                    break;
                case 4:// 材质
                    vo.setMaterial(value);
                    break;
                case 5:// 纹理
                    vo.setWave(value);
                    break;
                case 6:// 颜色
                    vo.setColor(value);
                    break;
                case 7:// 复合部件
                    vo.setIsComposite(value);
                    break;
                case 8:// 配件类型
                    vo.setCategory(value);
                    break;
                case 9:// 子类
                    vo.setType(value);
                    break;
                case 10:// 厂家
                    vo.setFactory(value);
                    break;
                case 11:// 品牌
                    vo.setBrand(value);
                    break;
                case 12:// 型号
                    vo.setModel(value);
                    break;
                case 13:// 板材/配件长
                    vo.setGoodsHeight(value);
                    break;
                case 14:// 板材/配件宽
                    vo.setGoodsWidth(value);
                    break;
                case 15:// 板材/配件厚
                    vo.setGoodsThickness(value);
                    break;
                case 16:// 规格
                    vo.setSpec(value);
                    break;
                case 17:// 单位
                    vo.setUnit(value);
                    break;
                case 18:// 数量
                    vo.setGoodsNumber(value);
                    break;
                case 19:// 房间
                    vo.setRoomsName(value);
                    break;
                case 20:// 柜体
                    vo.setCabinetsName(value);
                    break;
                case 21:// 加工组类型
                    vo.setSynthesisTypeName(value);
                    break;
                case 22:// 加工组名称
                    vo.setCombinationName(value);
                    break;
                case 23://板名称
                    vo.setName(value);
                    break;
                case 24:// 自定义板编号
                    vo.setPlateNo(value);
                    break;
                case 25:// 成品长
                    vo.setHeight(value);
                    break;
                case 26:// 成品宽
                    vo.setWidth(value);
                    break;
                case 27:// 拆单长
                    vo.setSplitHeight(value);
                    break;
                case 28:// 拆单宽
                    vo.setSplitWidth(value);
                    break;
                case 29:// 厚
                    vo.setThickness(value);
                    break;
                case 30:// 左封边
                    vo.setSealLeft(value);
                    break;
                case 31:// 右封边
                    vo.setSealRight(value);
                    break;
                case 32:// 上封边
                    vo.setSealUp(value);
                    break;
                case 33:// 下封边
                    vo.setSealDown(value);
                    break;
                case 34:// 排版面
                    vo.setTypographicFace(value);
                    break;
                case 35:// 纹路
                    vo.setTexture(value);
                    break;
                case 36:// 开门方向
                    vo.setOpenDoorType(value);
                    break;
                case 37://备注1
                    vo.setRemark1(value);
                    break;
                case 38://备注2
                    vo.setRemark2(value);
                    break;
                case 39://备注3
                    vo.setRemark3(value);
                    break;
                case 40://备注4
                    vo.setRemark4(value);
                    break;
                case 41://备注5
                    vo.setRemark5(value);
                    break;
                case 42://备注6
                    vo.setRemark6(value);
                    break;
                case 43://备注7
                    vo.setRemark7(value);
                    break;
                case 44://备注8
                    vo.setRemark8(value);
                    break;
                case 45://备注9
                    vo.setRemark9(value);
                    break;
                case 46://备注10
                    vo.setRemark10(value);
                    break;
                default:
                    // 处理默认情况，可以选择忽略或者做其他处理
                    break;

            }
    }

    private void handleSpecialDelimiters(Row row, Runnable onDelimiter, Runnable onStop) {
        String firstCellValue = getFirstCellValue(row);
        if ("###".equals(firstCellValue)) onDelimiter.run();
        if ("***".equals(firstCellValue)) onStop.run();
    }

    private void logResults(int preSize, int postSize) {
        log.info("preDelimiterList size: {}, postDelimiterList size: {}", preSize, postSize);
    }

    // vo转换
    public Map<String, String> changeToOrderMap(List<OrderPlateImportExcelVO> list) {
        Map<String, String> orderMap = new HashMap<>();

        // 初始化默认值
        orderMap.put(ProduceExcelConstants.ORDER_CUSTOM_ORDER_NO, "");
        orderMap.put(ProduceExcelConstants.ORDER_CUSTOMER, "");
        orderMap.put(ProduceExcelConstants.ORDER_ADDRESS, "");
        orderMap.put(ProduceExcelConstants.ORDER_PHONE_NUMBER, "");
        orderMap.put(ProduceExcelConstants.ORDER_REMARK, "");
        orderMap.put(ProduceExcelConstants.ORDER_SPLITTER, "");
        orderMap.put(ProduceExcelConstants.ORDER_SALESMAN, "");
        orderMap.put(ProduceExcelConstants.ORDER_DEALER_PHONE_NUMBER, "");
        orderMap.put(ProduceExcelConstants.ORDER_DEALER, "");
        orderMap.put(ProduceExcelConstants.ORDER_DELIVERY_DATE, "");

        // 定义一个映射规则数组，用于指示每个索引应更新哪些键
        String[][] keyMapping = {
                {ProduceExcelConstants.ORDER_CUSTOM_ORDER_NO, ProduceExcelConstants.ORDER_CUSTOMER},
                {ProduceExcelConstants.ORDER_DEALER, ProduceExcelConstants.ORDER_ADDRESS},
                {ProduceExcelConstants.ORDER_DEALER_PHONE_NUMBER, ProduceExcelConstants.ORDER_PHONE_NUMBER},
                {ProduceExcelConstants.ORDER_SALESMAN, ProduceExcelConstants.ORDER_DELIVERY_DATE},
                {ProduceExcelConstants.ORDER_SPLITTER, ProduceExcelConstants.ORDER_REMARK}
        };

        for (int i = 0; i < Math.min(keyMapping.length, list.size()); i++) {
            OrderPlateImportExcelVO vo = list.get(i);
            String[] keys = keyMapping[i];

            // 假设getGoodType()和getCabinetsName()只是示例方法，实际应用中应该根据实际情况选择合适的方法
            if (vo.getGoodType() != null && !vo.getGoodType().isEmpty()) {
                orderMap.put(keys[0], vo.getGoodType());
            }
            if (vo.getCabinetsName() != null && !vo.getCabinetsName().isEmpty()) {
                orderMap.put(keys[1], vo.getCabinetsName());
            }
        }

        return orderMap;
    }


}
