import { computed, makeObservable, observable } from 'mobx';
const SECTION_PREFIX = '$$$wix-patterns-sections$$$-';
const INVISIBLE_ROW_ID = `${SECTION_PREFIX}invisible`;
export class TableSectionsState {
    constructor(table, groupBy, renderSection, collapsible) {
        this.toggleSection = (sectionId) => {
            const currentCollapsed = this.isSectionCollapsed(sectionId);
            this.onToggleCallback?.(sectionId, !currentCollapsed);
        };
        this.table = table;
        this.groupBy = groupBy;
        this.renderSection = renderSection;
        this.collapsible = collapsible ?? false;
        makeObservable(this, {
            renderSection: observable.ref,
            sectionsKeyedItems: computed,
            sectionCounts: computed,
        });
    }
    isSectionCollapsed(sectionId) {
        const sectionItems = this.getSectionItems(sectionId);
        const section = this.renderSection(sectionId, sectionItems);
        return section.collapsed ?? false;
    }
    getSectionItems(sectionId) {
        const items = [];
        for (const keyedItem of this.table.keyedItems) {
            if (this.groupBy(keyedItem.item) === sectionId) {
                items.push(keyedItem.item);
            }
        }
        return items;
    }
    generateSectionId(firstItemId) {
        return `${SECTION_PREFIX}${firstItemId}`;
    }
    get computeSectionData() {
        const counts = new Map();
        const items = new Map();
        const indices = new Map();
        const keyedItems = [];
        if (this.table.keyedItems.length === 0) {
            return { counts, items, indices, keyedItems };
        }
        // Add invisible row for design purposes
        keyedItems.push({
            id: INVISIBLE_ROW_ID,
            key: INVISIBLE_ROW_ID,
            item: this.table.keyedItems[0].item,
            index: 0,
            pageIndex: 0,
            indexWithinPage: 0,
        });
        let currentSectionId = null;
        let currentSectionIndex = 0;
        let currentHeaderId = null;
        let count = 0;
        let isCurrentSectionCollapsed = false;
        let currentSectionItems = [];
        for (const keyedItem of this.table.keyedItems) {
            const sectionId = this.groupBy(keyedItem.item);
            if (sectionId !== currentSectionId) {
                // Store count and items for previous section
                if (currentHeaderId) {
                    counts.set(currentHeaderId, { count, isComplete: true });
                    items.set(currentHeaderId, currentSectionItems);
                }
                // Start new section
                currentSectionId = sectionId;
                currentHeaderId = this.generateSectionId(`${sectionId}@${currentSectionIndex}`);
                indices.set(currentHeaderId, currentSectionIndex);
                currentSectionIndex++;
                count = 1;
                currentSectionItems = [keyedItem.item];
                // Determine if section is collapsed from renderSection
                const section = this.renderSection(sectionId, this.getSectionItems(sectionId));
                isCurrentSectionCollapsed =
                    this.collapsible && (section.collapsed ?? false);
                // Add section header to keyed items
                const sectionKeyedItem = {
                    id: currentHeaderId,
                    key: currentHeaderId,
                    item: keyedItem.item,
                    index: keyedItems.length,
                    pageIndex: 0,
                    indexWithinPage: keyedItems.length,
                };
                keyedItems.push(sectionKeyedItem);
            }
            else {
                count++;
                currentSectionItems.push(keyedItem.item);
            }
            // Add the actual data item only if section is not collapsed
            if (!isCurrentSectionCollapsed) {
                keyedItems.push(keyedItem);
            }
        }
        // Handle last section
        if (currentHeaderId) {
            const isLastSectionComplete = this.table.collection.fetchedLastPage;
            counts.set(currentHeaderId, { count, isComplete: isLastSectionComplete });
            items.set(currentHeaderId, currentSectionItems);
        }
        return { counts, items, indices, keyedItems };
    }
    get sectionCounts() {
        return this.computeSectionData.counts;
    }
    get sectionItems() {
        return this.computeSectionData.items;
    }
    get sectionIndices() {
        return this.computeSectionData.indices;
    }
    get sectionsKeyedItems() {
        return this.computeSectionData.keyedItems;
    }
    getSectionWithCount(sectionKeyedItem) {
        const headerId = sectionKeyedItem.id;
        const sectionData = headerId
            ? this.sectionCounts.get(headerId) || { count: 0, isComplete: true }
            : { count: 0, isComplete: true };
        const sectionItemsList = headerId
            ? this.sectionItems.get(headerId) || []
            : [];
        const sectionIndex = headerId ? this.sectionIndices.get(headerId) ?? 0 : 0;
        const sectionId = this.groupBy(sectionKeyedItem.item);
        const section = this.renderSection(sectionId, sectionItemsList);
        return {
            sectionId,
            sectionIndex,
            section: {
                ...section,
                count: sectionData.count,
                hasMore: !sectionData.isComplete,
                items: sectionItemsList,
                collapsed: this.collapsible && (section.collapsed ?? false),
            },
            collapsible: this.collapsible,
        };
    }
    isSectionRow(keyedItem) {
        return keyedItem.id.startsWith(SECTION_PREFIX);
    }
    isInvisibleRow(keyedItem) {
        return keyedItem.id === INVISIBLE_ROW_ID;
    }
}
//# sourceMappingURL=TableSectionsState.js.map