// src/resources/js/scrollfx/ScrollTrigger.js

export default class ScrollTrigger {
    constructor(config) {
        this.element = this.resolveElement(config.element);
        this.target = config.target
            ? this.element.querySelector(config.target)
            : this.element;

        if (config.target && !this.target) {
            throw new Error(`Target selector '${config.target}' not found inside element '${config.element}'.`);
        }

        this.start = config.start || 'top 80%';
        this.end = config.end || 'bottom 20%';
        this.scrub = config.scrub || false;
        this.onEnter = config.onEnter || null;
        this.onLeave = config.onLeave || null;
        this.onUpdate = config.onUpdate || null;

        this._wasVisible = false;
        this._progress = 0;
    }

    resolveElement(input) {
        if (typeof input === 'string') {
            const els = document.querySelectorAll(input);
            if (els.length === 1) return els[0];
            throw new Error(`Selector '${input}' matched ${els.length} elements, expected exactly 1.`);
        }
        return input;
    }

    getScrollProgress(viewportHeight) {
        const rect = this.element.getBoundingClientRect();
        const startPx = this.parsePosition(this.start, viewportHeight);
        const endPx = this.parsePosition(this.end, viewportHeight);
        const scrollRange = endPx - startPx;
        const current = rect.top - startPx;
        return 1 - Math.min(Math.max(current / scrollRange, 0), 1);
    }

    parsePosition(pos, viewportHeight) {
        const [edge, value] = pos.split(' ');
        const edgeOffset = edge === 'top' ? 0 : viewportHeight;
        const percentage = parseFloat(value) / 100;
        return edgeOffset - viewportHeight * percentage;
    }

    update(viewportHeight) {
        const rect = this.element.getBoundingClientRect();
        const inViewport = rect.bottom > 0 && rect.top < viewportHeight;

        if (inViewport && !this._wasVisible) {
            this._wasVisible = true;
            if (this.onEnter) this.onEnter(this.target);
        }

        if (!inViewport && this._wasVisible) {
            this._wasVisible = false;
            if (this.onLeave) this.onLeave(this.target);
        }

        if (this.scrub && inViewport) {
            const progress = this.getScrollProgress(viewportHeight);
            if (this.onUpdate) this.onUpdate(this.target, progress);
        }
    }
}
