import { axisMetadataKey, deleteRecordsBySheet } from './workbook-store-records.js';
export const axisGeometryKeys = [
    'styleIndex',
    'xlsxWidth',
    'xlsxHeight',
    'customFormat',
    'customWidth',
    'bestFit',
    'outlineLevel',
    'collapsed',
    'customHeight',
    'thickTop',
    'thickBottom',
];
function axisGeometryValue(entry, key) {
    return entry[key] ?? null;
}
function hasAxisGeometry(entry) {
    return axisGeometryKeys.some((key) => axisGeometryValue(entry, key) !== null);
}
function axisEntriesHaveSameMetadata(left, right) {
    return (left.size === right.size &&
        left.hidden === right.hidden &&
        left.filterHidden === right.filterHidden &&
        axisGeometryKeys.every((key) => axisGeometryValue(left, key) === axisGeometryValue(right, key)));
}
function copyAxisGeometry(source) {
    const geometry = {};
    for (const key of axisGeometryKeys) {
        if (source[key] !== undefined) {
            Object.assign(geometry, { [key]: source[key] });
        }
    }
    return geometry;
}
function makeAxisEntrySnapshot(entry, index) {
    const snapshot = { id: entry.id, index, ...copyAxisGeometry(entry) };
    if (entry.size !== null) {
        snapshot.size = entry.size;
    }
    if (entry.hidden !== null) {
        snapshot.hidden = entry.hidden;
    }
    if (entry.filterHidden !== undefined && entry.filterHidden !== null) {
        snapshot.filterHidden = entry.filterHidden;
    }
    return snapshot;
}
function makeAxisEntryRecord(snapshot) {
    return {
        id: snapshot.id,
        size: snapshot.size ?? null,
        hidden: snapshot.hidden ?? null,
        filterHidden: snapshot.filterHidden ?? null,
        ...copyAxisGeometry(snapshot),
    };
}
function copyAxisGeometryToMetadata(source) {
    const metadata = {};
    for (const key of axisGeometryKeys) {
        if (typeof source[key] === 'number' || typeof source[key] === 'boolean') {
            Object.assign(metadata, { [key]: source[key] });
        }
    }
    return metadata;
}
function makeAxisMetadataRecord(sheetName, start, count, entry) {
    const record = {
        sheetName,
        start,
        count,
        size: entry.size,
        hidden: entry.hidden,
        ...copyAxisGeometryToMetadata(Object.fromEntries(axisGeometryKeys.map((key) => [key, axisGeometryValue(entry, key)]))),
    };
    if (entry.filterHidden !== undefined && entry.filterHidden !== null) {
        record.filterHidden = entry.filterHidden;
    }
    return record;
}
export function listAxisEntries(entries) {
    const result = [];
    entries.forEach((entry, index) => {
        if (!entry) {
            return;
        }
        result.push(makeAxisEntrySnapshot(entry, index));
    });
    return result;
}
export function materializeAxisEntryRecords(entries, start, count, createEntry) {
    const materialized = [];
    for (let index = 0; index < count; index += 1) {
        const position = start + index;
        let entry = entries[position];
        if (!entry) {
            entry = createEntry();
            entries[position] = entry;
        }
        materialized.push(entry);
    }
    return materialized;
}
export function materializeAxisEntries(entries, start, count, createEntry) {
    if (count <= 0) {
        return [];
    }
    if (count === 1) {
        let entry = entries[start];
        if (!entry) {
            entry = createEntry();
            entries[start] = entry;
        }
        return [makeAxisEntrySnapshot(entry, start)];
    }
    return materializeAxisEntryRecords(entries, start, count, createEntry).map((entry, offset) => makeAxisEntrySnapshot(entry, start + offset));
}
export function snapshotAxisEntriesInRange(entries, start, count) {
    if (count <= 0) {
        return [];
    }
    if (count === 1) {
        const entry = entries[start];
        return entry ? [makeAxisEntrySnapshot(entry, start)] : [];
    }
    const snapshots = [];
    for (let offset = 0; offset < count; offset += 1) {
        const index = start + offset;
        const entry = entries[index];
        if (!entry) {
            continue;
        }
        snapshots.push(makeAxisEntrySnapshot(entry, index));
    }
    return snapshots;
}
export function spliceAxisEntries(axisEntries, start, deleteCount, insertCount, _createEntry, providedSnapshots) {
    if (insertCount === 0 && axisEntries.length <= start) {
        return [];
    }
    if (deleteCount === 0 &&
        insertCount > 0 &&
        axisEntries.length <= start &&
        (providedSnapshots === undefined || providedSnapshots.length === 0)) {
        return [];
    }
    if (axisEntries.length < start) {
        axisEntries.length = start;
    }
    if (providedSnapshots === undefined) {
        if (deleteCount === 0 && insertCount > 0 && axisEntries.length <= start) {
            return [];
        }
        let removed;
        if (insertCount === 0) {
            removed = axisEntries.splice(start, deleteCount);
        }
        else if (insertCount === 1) {
            removed = axisEntries.splice(start, deleteCount, _createEntry());
        }
        else {
            const inserted = Array.from({ length: insertCount }, () => _createEntry());
            removed = axisEntries.splice(start, deleteCount, ...inserted);
        }
        return removed.flatMap((entry, index) => (entry ? [makeAxisEntrySnapshot(entry, start + index)] : []));
    }
    if (providedSnapshots.length === 0) {
        if (deleteCount === 0 && insertCount > 0 && axisEntries.length <= start) {
            return [];
        }
        let removed;
        if (insertCount === 0) {
            removed = axisEntries.splice(start, deleteCount);
        }
        else if (insertCount === 1) {
            removed = axisEntries.splice(start, deleteCount, undefined);
        }
        else {
            const inserted = [];
            inserted.length = insertCount;
            removed = axisEntries.splice(start, deleteCount, ...inserted);
        }
        return removed.flatMap((entry, index) => (entry ? [makeAxisEntrySnapshot(entry, start + index)] : []));
    }
    if (deleteCount === 0 && insertCount === 1 && providedSnapshots.length <= 1) {
        const provided = providedSnapshots[0];
        const insertedEntry = provided?.index === start ? makeAxisEntryRecord(provided) : undefined;
        axisEntries.splice(start, 0, insertedEntry);
        return [];
    }
    const providedEntries = new Map();
    providedSnapshots.forEach((entry) => {
        const offset = entry.index - start;
        if (offset < 0 || offset >= insertCount) {
            return;
        }
        providedEntries.set(offset, entry);
    });
    const removed = axisEntries.splice(start, deleteCount, ...Array.from({ length: insertCount }, (_, index) => {
        const provided = providedEntries.get(index);
        if (provided) {
            return makeAxisEntryRecord(provided);
        }
        return undefined;
    }));
    return removed.flatMap((entry, index) => (entry ? [makeAxisEntrySnapshot(entry, start + index)] : []));
}
export function moveAxisEntries(axisEntries, start, count, target, createEntry) {
    if (count <= 0 || start === target) {
        return;
    }
    materializeAxisEntryRecords(axisEntries, start, count, createEntry);
    const moved = axisEntries.splice(start, count);
    axisEntries.splice(target, 0, ...moved);
}
export function getAxisMetadataRecord(entries, sheetName, start, count) {
    let size;
    let hidden;
    let filterHidden;
    const geometry = {};
    let sawMaterialized = false;
    for (let index = start; index < start + count; index += 1) {
        const entry = entries[index];
        if (!entry) {
            if (size === undefined) {
                size = null;
            }
            if (hidden === undefined) {
                hidden = null;
            }
            if (filterHidden === undefined) {
                filterHidden = null;
            }
            for (const key of axisGeometryKeys) {
                geometry[key] ??= null;
            }
            continue;
        }
        sawMaterialized = true;
        size ??= entry.size;
        hidden ??= entry.hidden;
        filterHidden ??= entry.filterHidden;
        if (size !== entry.size || hidden !== entry.hidden || filterHidden !== entry.filterHidden) {
            return undefined;
        }
        for (const key of axisGeometryKeys) {
            const value = axisGeometryValue(entry, key);
            geometry[key] ??= value;
            if (geometry[key] !== value) {
                return undefined;
            }
        }
    }
    if (!sawMaterialized ||
        ((size ?? null) === null &&
            (hidden ?? null) === null &&
            (filterHidden ?? null) === null &&
            axisGeometryKeys.every((key) => (geometry[key] ?? null) === null))) {
        return undefined;
    }
    const record = {
        sheetName,
        start,
        count,
        size: size ?? null,
        hidden: hidden ?? null,
        ...copyAxisGeometryToMetadata(geometry),
    };
    if ((filterHidden ?? null) !== null) {
        record.filterHidden = filterHidden ?? null;
    }
    return record;
}
export function syncAxisMetadataBucket(bucket, sheetName, entries) {
    deleteRecordsBySheet(bucket, sheetName, (record) => record.sheetName);
    let cursor = 0;
    while (cursor < entries.length) {
        const entry = entries[cursor];
        if (!entry || (entry.size === null && entry.hidden === null && entry.filterHidden === null && !hasAxisGeometry(entry))) {
            cursor += 1;
            continue;
        }
        const start = cursor;
        cursor += 1;
        while (cursor < entries.length) {
            const next = entries[cursor];
            if (!next || !axisEntriesHaveSameMetadata(entry, next)) {
                break;
            }
            cursor += 1;
        }
        const record = makeAxisMetadataRecord(sheetName, start, cursor - start, entry);
        bucket.set(axisMetadataKey(sheetName, start, record.count), record);
    }
}
//# sourceMappingURL=workbook-axis-records.js.map