import gsap from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';

// Register GSAP plugin with error boundary
try {
    gsap.registerPlugin(ScrollTrigger);
} catch (error) {
    console.error('Failed to register GSAP ScrollTrigger plugin:', error);
    throw new Error('GSAP ScrollTrigger plugin registration failed. Parallax effects will not work.', { cause: error });
}

export interface ParallaxConfig {
    trigger: string | HTMLElement;
    target: string | HTMLElement;
    yPercent?: number;
    start?: string;
    end?: string;
    scrub?: number | boolean;
    respectReducedMotion?: boolean;
}

export class ParallaxEffect {
    private tween: gsap.core.Tween | null = null;
    private scrollTrigger: ScrollTrigger | null = null;
    private config: ParallaxConfig;

    constructor(config: ParallaxConfig) {
        this.config = {
            yPercent: 30,
            start: 'top top',
            end: 'bottom top',
            scrub: 1,
            respectReducedMotion: true,
            ...config
        };
    }

    public play(): void {
        if (this.config.respectReducedMotion && this.shouldReduceMotion()) {
            console.log('[ParallaxEffect] Skipped - prefers-reduced-motion');
            return;
        }

        const target = typeof this.config.target === 'string'
            ? document.querySelector<HTMLElement>(this.config.target)
            : this.config.target;

        if (!target) {
            console.warn('[ParallaxEffect] Target not found');
            return;
        }

        this.tween = gsap.to(target, {
            yPercent: this.config.yPercent,
            ease: 'none',
            scrollTrigger: {
                trigger: this.config.trigger,
                start: this.config.start,
                end: this.config.end,
                scrub: this.config.scrub,
            }
        });

        this.scrollTrigger = this.tween?.scrollTrigger ?? null;
    }

    public pause(): void {
        this.tween?.pause();
    }

    public resume(): void {
        this.tween?.resume();
    }

    public destroy(): void {
        this.scrollTrigger?.kill();
        this.tween?.kill();
        this.tween = null;
        this.scrollTrigger = null;
    }

    private shouldReduceMotion(): boolean {
        return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    }
}
