/**
 * Detects and manages CSS scroll snap points
 * Reads snap-align values from DOM and calculates scroll positions
 */
class SnapPointDetector {
    constructor(element, orientation = 'vertical') {
        this.snapPoints = [];
        this.element = element;
        this.orientation = orientation;
        this.detectSnapPoints();
    }
    /**
     * Detect snap points from DOM
     * Reads CSS scroll-snap-type and scroll-snap-align
     */
    detectSnapPoints() {
        this.snapPoints = [];
        const style = window.getComputedStyle(this.element);
        const snapType = style.scrollSnapType;
        // Check if snap is enabled
        if (!snapType || snapType === 'none') {
            return;
        }
        // Get all direct children (potential snap points)
        const children = Array.from(this.element.children);
        children.forEach((child) => {
            const childStyle = window.getComputedStyle(child);
            const snapAlign = childStyle.scrollSnapAlign;
            if (snapAlign && snapAlign !== 'none') {
                const position = this.calculateSnapPosition(child, snapAlign);
                if (position !== null) {
                    this.snapPoints.push({
                        position,
                        element: child,
                        align: this.parseSnapAlign(snapAlign),
                    });
                }
            }
        });
        // Sort snap points by position
        this.snapPoints.sort((a, b) => a.position - b.position);
    }
    /**
     * Calculate scroll position for a snap point
     */
    calculateSnapPosition(element, snapAlign) {
        if (this.orientation === 'horizontal') {
            const elementOffset = element.offsetLeft;
            const containerWidth = this.element.clientWidth;
            const elementWidth = element.offsetWidth;
            if (snapAlign.includes('start')) {
                return elementOffset;
            }
            else if (snapAlign.includes('center')) {
                return elementOffset - (containerWidth - elementWidth) / 2;
            }
            else if (snapAlign.includes('end')) {
                return elementOffset - (containerWidth - elementWidth);
            }
        }
        else {
            const elementOffset = element.offsetTop;
            const containerHeight = this.element.clientHeight;
            const elementHeight = element.offsetHeight;
            if (snapAlign.includes('start')) {
                return elementOffset;
            }
            else if (snapAlign.includes('center')) {
                return elementOffset - (containerHeight - elementHeight) / 2;
            }
            else if (snapAlign.includes('end')) {
                return elementOffset - (containerHeight - elementHeight);
            }
        }
        return null;
    }
    /**
     * Parse snap align value
     */
    parseSnapAlign(snapAlign) {
        if (snapAlign.includes('center'))
            return 'center';
        if (snapAlign.includes('end'))
            return 'end';
        return 'start';
    }
    /**
     * Find nearest snap point to current position
     */
    findNearestSnapPoint(position) {
        if (this.snapPoints.length === 0)
            return null;
        let nearest = this.snapPoints[0];
        let minDistance = Math.abs(position - nearest.position);
        for (const snapPoint of this.snapPoints) {
            const distance = Math.abs(position - snapPoint.position);
            if (distance < minDistance) {
                minDistance = distance;
                nearest = snapPoint;
            }
        }
        return nearest;
    }
    /**
     * Find snap point in direction of scroll
     */
    findSnapPointInDirection(position, direction) {
        if (this.snapPoints.length === 0)
            return null;
        if (direction > 0) {
            // Scrolling down/right - find next snap point
            return (this.snapPoints.find((snap) => snap.position > position + 1) || null);
        }
        else {
            // Scrolling up/left - find previous snap point
            const reversed = [...this.snapPoints].reverse();
            return reversed.find((snap) => snap.position < position - 1) || null;
        }
    }
    /**
     * Check if position is close to a snap point
     */
    isNearSnapPoint(position, threshold = 10) {
        return this.snapPoints.some((snap) => Math.abs(snap.position - position) < threshold);
    }
    /**
     * Get all snap points
     */
    getSnapPoints() {
        return [...this.snapPoints];
    }
    /**
     * Refresh snap points (call when DOM changes)
     */
    refresh() {
        this.detectSnapPoints();
    }
    /**
     * Update orientation
     */
    setOrientation(orientation) {
        this.orientation = orientation;
        this.detectSnapPoints();
    }
}

export { SnapPointDetector };
