import { addEngineCounter } from './perf/engine-counters.js';
import { axisGeometryKeys, getAxisMetadataRecord, listAxisEntries, materializeAxisEntries, materializeAxisEntryRecords, moveAxisEntries, snapshotAxisEntriesInRange, spliceAxisEntries, syncAxisMetadataBucket, } from './workbook-axis-records.js';
import { axisMetadataKey } from './workbook-store-records.js';
function applyAxisGeometryPatch(entry, patch) {
    if (patch) {
        Object.assign(entry, patch);
    }
    for (const key of axisGeometryKeys) {
        if (patch?.[key] === undefined) {
            delete entry[key];
        }
    }
}
export class WorkbookAxisEntryStore {
    options;
    constructor(options) {
        this.options = options;
    }
    setAxisMetadata(sheet, axis, bucket, sheetName, start, count, size, hidden, geometry, filterHidden) {
        const entries = this.materializeAxisEntryRecords(sheet, axis, start, count);
        entries.forEach((entry) => {
            entry.size = size;
            entry.hidden = hidden;
            if (filterHidden !== undefined) {
                entry.filterHidden = filterHidden;
            }
            applyAxisGeometryPatch(entry, geometry);
        });
        this.syncAxisMetadataBucket(sheetName, sheet, axis, bucket);
        const record = this.getAxisMetadataRecord(sheet, axis, sheetName, start, count);
        if (!record) {
            bucket.delete(axisMetadataKey(sheetName, start, count));
        }
        return record;
    }
    listAxisMetadata(sheet, bucket, sheetName, axis) {
        if (!sheet) {
            return [];
        }
        this.syncAxisMetadataBucket(sheetName, sheet, axis, bucket);
        return [...bucket.values()]
            .filter((record) => record.sheetName === sheetName)
            .toSorted((left, right) => left.start - right.start || left.count - right.count);
    }
    listAxisEntries(sheet, axis) {
        if (!sheet) {
            return [];
        }
        return listAxisEntries(axis === 'row' ? sheet.rowAxis : sheet.columnAxis);
    }
    materializeAxisEntries(sheet, axis, start, count) {
        if (count === 1) {
            const entries = axis === 'row' ? sheet.rowAxis : sheet.columnAxis;
            let entry = entries[start];
            if (!entry) {
                const existingId = sheet.axisMap.getId(axis, start);
                entry = existingId ? { id: existingId, size: null, hidden: null, filterHidden: null } : this.options.createAxisEntry(axis);
                entries[start] = entry;
            }
            const snapshot = snapshotAxisEntriesInRange(entries, start, 1);
            sheet.axisMap.replaceRange(axis, start, snapshot);
            return snapshot;
        }
        this.hydrateAxisEntriesFromMap(sheet, axis, start, count);
        const entries = materializeAxisEntries(axis === 'row' ? sheet.rowAxis : sheet.columnAxis, start, count, () => this.options.createAxisEntry(axis));
        sheet.axisMap.replaceRange(axis, start, entries);
        return entries;
    }
    snapshotAxisEntriesInRange(sheet, axis, start, count) {
        if (!sheet) {
            return [];
        }
        return snapshotAxisEntriesInRange(axis === 'row' ? sheet.rowAxis : sheet.columnAxis, start, count);
    }
    spliceAxisEntries(sheet, axis, start, deleteCount, insertCount, entries) {
        const removed = spliceAxisEntries(axis === 'row' ? sheet.rowAxis : sheet.columnAxis, start, deleteCount, insertCount, () => this.options.createAxisEntry(axis), entries);
        sheet.axisMap.splice(axis, start, deleteCount, insertCount, snapshotAxisEntriesInRange(axis === 'row' ? sheet.rowAxis : sheet.columnAxis, start, insertCount));
        sheet.logicalAxisMap.splice(axis, start, deleteCount, insertCount, []);
        if (this.options.counters) {
            addEngineCounter(this.options.counters, 'axisMapSplices');
        }
        return removed;
    }
    moveAxisEntries(sheet, axis, start, count, target) {
        sheet.axisMap.move(axis, start, count, target);
        sheet.logicalAxisMap.move(axis, start, count, target);
        if (this.options.counters) {
            addEngineCounter(this.options.counters, 'axisMapMoves');
        }
        moveAxisEntries(axis === 'row' ? sheet.rowAxis : sheet.columnAxis, start, count, target, () => this.options.createAxisEntry(axis));
    }
    getAxisMetadataRecord(sheet, axis, sheetName, start, count) {
        return getAxisMetadataRecord(axis === 'row' ? sheet.rowAxis : sheet.columnAxis, sheetName, start, count);
    }
    hydrateAxisEntriesFromMap(sheet, axis, start, count) {
        if (count <= 0) {
            return;
        }
        const entries = axis === 'row' ? sheet.rowAxis : sheet.columnAxis;
        const snapshots = sheet.axisMap.snapshot(axis, start, count);
        for (let index = 0; index < snapshots.length; index += 1) {
            const snapshot = snapshots[index];
            if (entries[snapshot.index]) {
                continue;
            }
            entries[snapshot.index] = {
                id: snapshot.id,
                size: null,
                hidden: null,
                filterHidden: null,
            };
        }
    }
    materializeAxisEntryRecords(sheet, axis, start, count) {
        this.hydrateAxisEntriesFromMap(sheet, axis, start, count);
        const entries = materializeAxisEntryRecords(axis === 'row' ? sheet.rowAxis : sheet.columnAxis, start, count, () => this.options.createAxisEntry(axis));
        sheet.axisMap.replaceRange(axis, start, snapshotAxisEntriesInRange(axis === 'row' ? sheet.rowAxis : sheet.columnAxis, start, count));
        return entries;
    }
    syncAxisMetadataBucket(sheetName, sheet, axis, bucket) {
        syncAxisMetadataBucket(bucket, sheetName, axis === 'row' ? sheet.rowAxis : sheet.columnAxis);
    }
}
//# sourceMappingURL=workbook-axis-entry-store.js.map