"use strict";

var __importDefault = this && this.__importDefault || function(mod) {
    return mod && mod.__esModule ? mod : {
        default: mod
    };
};

Object.defineProperty(exports, "__esModule", {
    value: !0
}), exports.generateAutoFillData = void 0;

const big_js_1 = __importDefault(require("big.js")), isEqual_1 = __importDefault(require("lodash/isEqual")), isNumber_1 = __importDefault(require("lodash/isNumber")), isObject_1 = __importDefault(require("lodash/isObject")), translateRowObj_1 = require("./translateRowObj"), bigFunc = (a, b, func) => {
    if ("number" != typeof a && (a = Number(a)), "number" != typeof b && (b = Number(b)), 
    Number.isNaN(a) || Number.isNaN(b)) throw new Error(`${func}(a, b), a or b is NaN`);
    return new big_js_1.default(a)[func](b).toNumber();
}, add = (a = 0, b = 0) => bigFunc(a, b, "plus"), minus = (a = 0, b = 0) => bigFunc(a, b, "minus");

function splitOnLastNumber(str) {
    const match = str.match(/((\d+)(\.\d+)?)(?!.*(\d+)(\.\d+)?)/);
    if (!match || void 0 === match.index) return [ str ];
    const index = match.index, number = match[0];
    return [ str.slice(0, index), number, str.slice(index + number.length) ].filter((item => "" !== item));
}

const parseValue = value => {
    if ("number" == typeof value) return {
        prefix: "",
        number: value,
        full: value
    };
    const match = splitOnLastNumber(value), numberIndex = match.findIndex((str => !isNaN(Number(str)) && "" !== str && !isNaN(parseFloat(str)) && isFinite(Number(str))));
    return 1 === match.length ? 0 === numberIndex ? {
        prefix: "",
        number: Number(match[0]),
        suffix: "",
        full: value
    } : {
        prefix: value,
        number: null,
        suffix: "",
        full: value
    } : match.length > 1 ? 0 === numberIndex ? {
        prefix: "",
        number: Number(match[0]),
        suffix: match[1],
        full: value
    } : {
        prefix: match[0],
        number: Number(match[1]),
        suffix: null == match ? void 0 : match[2],
        full: value
    } : {
        prefix: null,
        number: null,
        suffix: null,
        full: value
    };
}, generateAutoFillData = (originalData, columns, startRange, currentEnd) => {
    if (!originalData || originalData.length < startRange.endRow - 1) return [];
    let newData = [];
    if (Array.isArray(null == originalData ? void 0 : originalData[0]) ? newData = originalData.map((row => [ ...row ])) : columns.length && (0, 
    isObject_1.default)(null == originalData ? void 0 : originalData[0]) && (newData = (0, 
    translateRowObj_1.translateRowObjToArray)(originalData, columns)), !(null == newData ? void 0 : newData.length)) return originalData;
    const verticalDelta = currentEnd.row - startRange.endRow, horizontalDelta = currentEnd.col - startRange.endCol, isVertical = Math.abs(verticalDelta) >= Math.abs(horizontalDelta), fillSteps = isVertical ? verticalDelta : horizontalDelta, [sampleStartRow, sampleEndRow] = [ startRange.startRow, startRange.endRow ].sort(((a, b) => a - b)), [sampleStartCol, sampleEndCol] = [ startRange.startCol, startRange.endCol ].sort(((a, b) => a - b)), sampleValues = [];
    for (let r = sampleStartRow; r <= sampleEndRow; r++) for (let c = sampleStartCol; c <= sampleEndCol; c++) sampleValues.push(newData[r][c]);
    const samples = sampleValues.map(parseValue), validSequence = samples.every((s => null !== s.number)) && samples.slice(1).every(((s, i) => s.prefix === samples[i].prefix)) && samples.length < 3 && !(2 === samples.length && (0, 
    isEqual_1.default)(samples[0], samples[1]));
    let step;
    if (1 === samples.length && null !== samples[0].number) step = 1; else if (validSequence && samples.length > 1) {
        const numbers = samples.map((s => s.number));
        step = minus(numbers[numbers.length - 1], numbers[numbers.length - 2]);
    }
    const positionInEdges = curPos => isVertical && verticalDelta > 0 ? curPos.row <= currentEnd.row : isVertical && verticalDelta < 0 ? curPos.row >= currentEnd.row : !isVertical && horizontalDelta > 0 ? curPos.col <= currentEnd.col : !isVertical && horizontalDelta < 0 && curPos.col >= currentEnd.col, totalSteps = Math.abs(fillSteps), direction = fillSteps > 0 ? 1 : -1, sampLength = samples.length;
    if (1 === samples.length) {
        const sample = samples[0];
        for (let i = 1; i <= totalSteps; i++) {
            const pos = {
                row: isVertical ? startRange.endRow + direction * i : startRange.startRow,
                col: isVertical ? startRange.startCol : startRange.endCol + direction * i
            };
            if (pos.row >= 0 && pos.col >= 0 && positionInEdges(pos)) {
                let tempRes = (0, isNumber_1.default)(sample.number) ? `${sample.prefix || ""}${((null == sample ? void 0 : sample.number) || 0) + (direction > 0 ? i : -i)}${sample.suffix || ""}` : sample.full;
                (0, isNumber_1.default)(sample.full) && (tempRes = ((null == sample ? void 0 : sample.number) || 0) + (direction > 0 ? i : -i)), 
                newData[pos.row][pos.col] = tempRes;
            }
        }
    } else if (samples.length >= 2) for (let i = 1; i <= totalSteps; i++) {
        let sample;
        const pos = {
            row: 0,
            col: 0
        };
        if (1 === direction ? (pos.row = isVertical ? startRange.endRow + direction * i : startRange.endRow, 
        pos.col = isVertical ? startRange.endCol : startRange.endCol + direction * i, sample = samples[(i - 1) % sampLength]) : (pos.row = isVertical ? startRange.startRow + direction * i : startRange.startRow, 
        pos.col = isVertical ? startRange.startCol : startRange.startCol + direction * i, 
        sample = samples[Math.abs(sampLength - i) % sampLength]), pos.row >= 0 && pos.col >= 0 && positionInEdges(pos)) {
            let tempRes;
            if ((0, isNumber_1.default)(sample.full) || Number(sample.full) === Number(sample.number) && 2 === sampLength) {
                const deltaLength = sampLength + Math.floor((i - 1) / sampLength) * sampLength;
                tempRes = add((null == sample ? void 0 : sample.number) || 0, direction > 0 ? (step || 1) * deltaLength : -(step || 1) * deltaLength);
            } else tempRes = validSequence ? `${sample.prefix || ""}${add((null == sample ? void 0 : sample.number) || 0, direction > 0 ? (step || 1) * sampLength : -(step || 1) * sampLength)}${sample.suffix || ""}` : (0, 
            isNumber_1.default)(null == sample ? void 0 : sample.number) ? `${sample.prefix || ""}${add((null == sample ? void 0 : sample.number) || 0, direction > 0 ? Math.floor((i - 1) / sampLength) + 1 : -(Math.floor((i - 1) / sampLength) + 1))}${sample.suffix || ""}` : sample.full;
            newData[pos.row][pos.col] = tempRes;
        }
    }
    return Array.isArray(null == originalData ? void 0 : originalData[0]) ? newData : (0, 
    translateRowObj_1.translateRowArrayToObj)(newData, columns);
};

exports.generateAutoFillData = generateAutoFillData;
//# sourceMappingURL=autoFillHandle.js.map