/**
 * Tab System — Osmo adapted: pin + scrub, line-by-line text.
 * data-tabs* attributes must not be renamed.
 */
import { gsap } from 'gsap';
import { ScrollTrigger } from 'gsap/ScrollTrigger';
import { SplitText } from 'gsap/SplitText';
import { CustomEase } from 'gsap/CustomEase';
import { prefersReducedMotion, scopeRoot } from './runtime.js';

gsap.registerPlugin(ScrollTrigger, SplitText, CustomEase);
CustomEase.create('smooth', 'M0,0 C0.38,0.005 0.215,1 1,1');

function splitLines(el) {
	if (!el) return [];
	const split = SplitText.create(el, { type: 'lines', mask: 'lines' });
	return split.lines || [];
}

function setActive(contentItems, visualItems, rightItems, index) {
	contentItems.forEach((item, i) => {
		const on = i === index;
		item.classList.toggle('active', on);
		item.setAttribute('aria-selected', on ? 'true' : 'false');
		visualItems[i]?.classList.toggle('active', on);
		rightItems[i]?.classList.toggle('is-active', on);
	});
}

export default function initTabsScroll(root) {
	const scope = scopeRoot(root);
	const wrappers = scope.querySelectorAll('[data-tabs="wrapper"]');
	if (!wrappers.length) return;

	const reduced = prefersReducedMotion();

	const boot = () => {
		wrappers.forEach((wrapper) => {
			if (wrapper.hasAttribute('data-tabs-ready')) return;
			wrapper.setAttribute('data-tabs-ready', 'true');
			const contentItems = [...wrapper.querySelectorAll('[data-tabs="content-item"]')];
			const visualItems = [...wrapper.querySelectorAll('[data-tabs="visual-item"]')];
			const rightItems = [...wrapper.querySelectorAll('[data-tabs="right-item"]')];
			const count = contentItems.length;
			if (count < 2) return;

			const pinEl = wrapper.closest('[data-tabs-pin]') || wrapper;
			const bars = contentItems.map((item) => item.querySelector('[data-tabs="item-progress"]'));

			const titleEls = contentItems.map((item) => item.querySelector('.block-app-tabs__title'));
			const copyEls = rightItems.map((item) => [...item.querySelectorAll('.block-app-tabs__copy-p')]);

			const titleLines = titleEls.map((el) => splitLines(el));
			const copyLines = copyEls.map((paras) => paras.flatMap((p) => splitLines(p)));

			if (reduced) {
				setActive(contentItems, visualItems, rightItems, 0);
				bars.forEach((bar, i) => {
					if (bar) gsap.set(bar, { scaleY: i === 0 ? 1 : 0 });
				});
				return;
			}

			titleLines.forEach((lines, i) => {
				gsap.set(lines, { yPercent: i === 0 ? 0 : 110 });
			});
			copyLines.forEach((lines, i) => {
				gsap.set(lines, { yPercent: i === 0 ? 0 : 110 });
			});
			gsap.set(visualItems, { autoAlpha: 0 });
			gsap.set(visualItems[0], { autoAlpha: 1 });
			gsap.set(bars, { scaleY: 0, transformOrigin: 'top center' });
			setActive(contentItems, visualItems, rightItems, 0);

			let current = 0;

			const tl = gsap.timeline({
				defaults: { ease: 'none' },
				scrollTrigger: {
					trigger: pinEl,
					start: 'top top',
					end: () => `+=${Math.round(window.innerHeight * count * 0.85)}`,
					pin: true,
					// 'transform' survives [data-main] x/y transforms (underlay menu
					// + page leave). 'fixed' jumps/vanishes inside a transformed ancestor.
					pinType: 'transform',
					pinSpacing: true,
					scrub: 0.8,
					anticipatePin: 1,
					invalidateOnRefresh: true,
					refreshPriority: -1,
					onUpdate(self) {
						const next = Math.min(count - 1, Math.floor(self.progress * count));
						if (next !== current) {
							current = next;
							setActive(contentItems, visualItems, rightItems, current);
						}
					},
				},
			});

			contentItems.forEach((_, i) => {
				const visual = visualItems[i];
				const tLines = titleLines[i];
				const cLines = copyLines[i];
				const at = i;

				// Keep equal scroll segments for each slide
				tl.to({}, { duration: 1 }, at);

				if (i === 0) return;

				const prevT = titleLines[i - 1];
				const prevC = copyLines[i - 1];
				const prevVisual = visualItems[i - 1];
				const outDur = 0.28;
				const inDur = 0.42;

				if (prevT.length) {
					tl.to(prevT, { yPercent: -110, duration: outDur, stagger: 0.04, ease: 'smooth' }, at);
				}
				if (prevC.length) {
					tl.to(prevC, { yPercent: -110, duration: outDur, stagger: 0.03, ease: 'smooth' }, at);
				}
				tl.to(prevVisual, { autoAlpha: 0, duration: outDur, ease: 'smooth' }, at);

				if (tLines.length) {
					tl.fromTo(
						tLines,
						{ yPercent: 110 },
						{ yPercent: 0, duration: inDur, stagger: 0.06, ease: 'smooth' },
						at + 0.08,
					);
				}
				if (cLines.length) {
					tl.fromTo(
						cLines,
						{ yPercent: 110 },
						{ yPercent: 0, duration: inDur, stagger: 0.05, ease: 'smooth' },
						at + 0.12,
					);
				}
				tl.fromTo(
					visual,
					{ autoAlpha: 0 },
					{ autoAlpha: 1, duration: inDur, ease: 'smooth' },
					at + 0.08,
				);
			});

			// One continuous progress across all slides (shared by every rail)
			const activeBars = bars.filter(Boolean);
			if (activeBars.length) {
				tl.fromTo(
					activeBars,
					{ scaleY: 0 },
					{ scaleY: 1, duration: count, ease: 'none' },
					0,
				);
			}
		});
	};

	if (document.fonts?.ready) document.fonts.ready.then(boot);
	else boot();
}
