import gsap from 'gsap';

interface MountainDrawOptions {
    container: HTMLElement;
    src: string;
    reducedMotion?: boolean;
}

/**
 * MountainDraw — fetches an external SVG, inlines it, and preps its outline
 * stroke path(s) for a scroll-driven "draw" animation (stroke-dashoffset).
 * The actual scroll-tied tween lives in the caller's ScrollTrigger timeline
 * (see assets/home.ts) so it can be sequenced with pinning/fade/etc.
 */
export class MountainDraw {
    private container: HTMLElement;
    private src: string;
    private reducedMotion: boolean;
    private paths: SVGPathElement[] = [];

    constructor(options: MountainDrawOptions) {
        this.container = options.container;
        this.src = options.src;
        this.reducedMotion = options.reducedMotion ?? false;
    }

    public async init(): Promise<SVGPathElement[]> {
        let svgMarkup: string;
        try {
            const response = await fetch(this.src);
            if (!response.ok) {
                throw new Error(`HTTP ${response.status}`);
            }
            svgMarkup = await response.text();
        } catch (error) {
            console.warn('[MountainDraw] Failed to load SVG:', error);
            return [];
        }

        this.container.innerHTML = svgMarkup;

        const svg = this.container.querySelector('svg');
        const paths = Array.from(
            this.container.querySelectorAll<SVGPathElement>('path[stroke]')
        );
        if (paths.length === 0) {
            return [];
        }

        // Some exported SVGs ship a viewBox whose X origin doesn't match the
        // path's actual horizontal extent (e.g. exported relative to a much
        // wider Figma canvas) — the declared Y/height already correctly
        // frame the visible ridge (crops out an invisible mask-helper shape
        // below it), so only the X origin/width need realigning to the
        // path's real bounding box.
        if (svg) {
            const [, origY, , origHeight] = (svg.getAttribute('viewBox') ?? '0 0 0 0')
                .split(' ')
                .map(Number);

            const bbox = paths.reduce((acc, path) => {
                const b = path.getBBox();
                if (!acc) return { x: b.x, x2: b.x + b.width };
                return {
                    x: Math.min(acc.x, b.x),
                    x2: Math.max(acc.x2, b.x + b.width),
                };
            }, null as { x: number; x2: number } | null);

            if (bbox) {
                const width = bbox.x2 - bbox.x;
                svg.setAttribute('viewBox', `${bbox.x} ${origY} ${width} ${origHeight}`);
                // The intrinsic width/height attributes (not the viewBox) drive the
                // aspect ratio used by the container's `height: auto` CSS — realign
                // them too, or the content stays squashed into the old aspect ratio.
                svg.setAttribute('width', String(width));
                svg.setAttribute('height', String(origHeight));
            }
        }

        this.paths = paths;

        if (this.reducedMotion) {
            return paths;
        }

        paths.forEach(path => {
            const length = path.getTotalLength();
            gsap.set(path, {
                strokeDasharray: length,
                strokeDashoffset: length,
            });
        });

        return paths;
    }

    public getPaths(): SVGPathElement[] {
        return this.paths;
    }
}
