"use strict";

var __awaiter = this && this.__awaiter || function(thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))((function(resolve, reject) {
        function fulfilled(value) {
            try {
                step(generator.next(value));
            } catch (e) {
                reject(e);
            }
        }
        function rejected(value) {
            try {
                step(generator.throw(value));
            } catch (e) {
                reject(e);
            }
        }
        function step(result) {
            var value;
            result.done ? resolve(result.value) : (value = result.value, value instanceof P ? value : new P((function(resolve) {
                resolve(value);
            }))).then(fulfilled, rejected);
        }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    }));
}, __importDefault = this && this.__importDefault || function(mod) {
    return mod && mod.__esModule ? mod : {
        default: mod
    };
};

Object.defineProperty(exports, "__esModule", {
    value: !0
}), exports.parseCellAddress = exports.parseMergedCells = exports.parseWorksheetToSheetData = exports.importExcelMultipleSheets = exports.importCsvFile = void 0;

const exceljs_1 = __importDefault(require("exceljs"));

function importCsvFile(file, options) {
    return __awaiter(this, void 0, void 0, (function*() {
        const text = yield file.text(), delimiter = (null == options ? void 0 : options.delimiter) || ",", lines = text.split(/\r?\n/).filter((line => line.trim().length > 0));
        if (0 === lines.length) throw new Error("CSV 文件为空");
        const data = [];
        for (const line of lines) {
            const row = parseCsvLine(line, delimiter);
            data.push(row);
        }
        const rowCount = data.length, columnCount = Math.max(...data.map((row => row.length)), 0);
        return {
            sheets: [ {
                sheetTitle: file.name.replace(/\.(csv|txt)$/i, "") || "Sheet1",
                sheetKey: `sheet_${Date.now()}_0`,
                data: data,
                columnCount: columnCount,
                rowCount: rowCount
            } ]
        };
    }));
}

function parseCsvLine(line, delimiter) {
    const result = [];
    let current = "", inQuotes = !1;
    for (let i = 0; i < line.length; i++) {
        const char = line[i], nextChar = line[i + 1];
        '"' === char ? inQuotes && '"' === nextChar ? (current += '"', i++) : inQuotes = !inQuotes : char !== delimiter || inQuotes ? current += char : (result.push(current.trim()), 
        current = "");
    }
    return result.push(current.trim()), result;
}

function importExcelMultipleSheets(file, options) {
    return __awaiter(this, void 0, void 0, (function*() {
        const workbook = new exceljs_1.default.Workbook;
        if (yield workbook.xlsx.load(yield file.arrayBuffer()), !workbook.worksheets || 0 === workbook.worksheets.length) throw new Error("Excel 文件无有效工作表");
        let sheetIndices;
        sheetIndices = (null == options ? void 0 : options.sheetIndices) && options.sheetIndices.length > 0 ? options.sheetIndices.filter((index => index >= 0 && index < workbook.worksheets.length)) : Array.from({
            length: workbook.worksheets.length
        }, ((_, i) => i));
        const sheets = [];
        for (const sheetIndex of sheetIndices) {
            const worksheet = workbook.worksheets[sheetIndex];
            if (worksheet) try {
                const sheetData = yield parseWorksheetToSheetData(worksheet, sheetIndex, options);
                sheets.push(sheetData);
            } catch (error) {}
        }
        if (0 === sheets.length) throw new Error("没有成功解析任何工作表");
        return {
            sheets: sheets
        };
    }));
}

function parseWorksheetToSheetData(worksheet, sheetIndex, options) {
    return __awaiter(this, void 0, void 0, (function*() {
        const sheetTitle = worksheet.name || `Sheet${sheetIndex + 1}`, sheetKey = `sheet_${Date.now()}_${sheetIndex}`, rowCount = worksheet.actualRowCount || 0, columnCount = worksheet.actualColumnCount || 0;
        if (0 === rowCount || 0 === columnCount) {
            const cellMerge = parseMergedCells(worksheet, []);
            return Object.assign({
                sheetTitle: sheetTitle,
                sheetKey: sheetKey,
                data: [],
                columnCount: 0,
                rowCount: 0
            }, cellMerge.length > 0 ? {
                cellMerge: cellMerge
            } : {});
        }
        const data = [];
        for (let rowNumber = 1; rowNumber <= rowCount; rowNumber++) {
            const row = worksheet.getRow(rowNumber), rowData = [];
            for (let colNumber = 1; colNumber <= columnCount; colNumber++) {
                let cellValue = row.getCell(colNumber).value;
                cellValue && "object" == typeof cellValue && ("richText" in cellValue ? cellValue = cellValue.richText.map((rt => rt.text)).join("") : "result" in cellValue ? cellValue = cellValue.result : "text" in cellValue && "hyperlink" in cellValue ? cellValue = cellValue.text : cellValue instanceof Date && (cellValue = cellValue.toISOString())), 
                rowData.push(null != cellValue ? cellValue : null);
            }
            data.push(rowData);
        }
        const cellMerge = parseMergedCells(worksheet, data);
        return Object.assign({
            sheetTitle: sheetTitle,
            sheetKey: sheetKey,
            data: data,
            columnCount: columnCount,
            rowCount: rowCount
        }, cellMerge.length > 0 ? {
            cellMerge: cellMerge
        } : {});
    }));
}

function parseMergedCells(worksheet, data) {
    var _a;
    const cellMerge = [];
    try {
        const worksheetAny = worksheet, merges = (null === (_a = worksheetAny.model) || void 0 === _a ? void 0 : _a.merges) || worksheetAny._merges || {};
        for (const [masterCell, range] of Object.entries(merges)) try {
            let startCol, startRow, endCol, endRow, text;
            if ("string" == typeof range) {
                const rangeMatch = range.match(/^([A-Z]+\d+):([A-Z]+\d+)$/i);
                if (!rangeMatch) continue;
                const startAddr = parseCellAddress(rangeMatch[1]), endAddr = parseCellAddress(rangeMatch[2]);
                if (!startAddr || !endAddr) continue;
                startCol = startAddr.col, startRow = startAddr.row, endCol = endAddr.col, endRow = endAddr.row;
            } else {
                if ("object" != typeof range || null === range) continue;
                {
                    const rangeObj = range;
                    if (rangeObj.tl && rangeObj.br) {
                        const startAddr = parseCellAddress(rangeObj.tl), endAddr = parseCellAddress(rangeObj.br);
                        if (!startAddr || !endAddr) continue;
                        startCol = startAddr.col, startRow = startAddr.row, endCol = endAddr.col, endRow = endAddr.row;
                    } else {
                        if ("number" != typeof rangeObj.top || "number" != typeof rangeObj.left || "number" != typeof rangeObj.bottom || "number" != typeof rangeObj.right) continue;
                        startRow = rangeObj.top - 1, startCol = rangeObj.left - 1, endRow = rangeObj.bottom - 1, 
                        endCol = rangeObj.right - 1;
                    }
                }
            }
            if (startRow >= 0 && startRow < data.length && startCol >= 0 && startCol < data[startRow].length) {
                const cellValue = data[startRow][startCol];
                null != cellValue && (text = String(cellValue));
            }
            cellMerge.push({
                text: text,
                range: {
                    start: {
                        col: startCol,
                        row: startRow
                    },
                    end: {
                        col: endCol,
                        row: endRow
                    },
                    isCustom: !0
                }
            });
        } catch (error) {}
    } catch (error) {}
    return cellMerge;
}

function parseCellAddress(address) {
    try {
        const match = address.match(/^([A-Z]+)(\d+)$/i);
        if (!match) return null;
        const colLetters = match[1].toUpperCase(), rowNumber = parseInt(match[2], 10);
        let col = 0;
        for (let i = 0; i < colLetters.length; i++) col = 26 * col + (colLetters.charCodeAt(i) - 64);
        col -= 1;
        return {
            col: col,
            row: rowNumber - 1
        };
    } catch (error) {
        return null;
    }
}

exports.importCsvFile = importCsvFile, exports.importExcelMultipleSheets = importExcelMultipleSheets, 
exports.parseWorksheetToSheetData = parseWorksheetToSheetData, exports.parseMergedCells = parseMergedCells, 
exports.parseCellAddress = parseCellAddress;
//# sourceMappingURL=excel.js.map