// eslint-disable-next-line
import React, {
	useState,
	useRef,
	useEffect,
	Children,
	cloneElement,
	ReactElement,
} from 'react';

interface TabProps {
	children?: React.ReactNode;
	isPro?: boolean;
	label: string;
	slug: string;
	status?: 'ok' | 'empty' | 'error';
}

interface TabsProps {
	urlKey: string;
	children: React.ReactNode;
	renderTabHeaders?: ( headers: ReactElement ) => React.ReactNode;
	renderTabContent?: ( content: ReactElement ) => React.ReactNode;
}

export default function Tabs( {
	urlKey,
	children,
	renderTabHeaders,
	renderTabContent,
}: TabsProps ) {
	const params = new URLSearchParams( window.location.search );
	const activeSlug = params.get( urlKey );
	const childArray = Children.toArray(
		children
	) as ReactElement< TabProps >[];
	const indexFromSlug = childArray.findIndex(
		( child ) =>
			React.isValidElement( child ) && child.props.slug === activeSlug
	);
	const [ activeIndex, setActiveIndex ] = useState(
		indexFromSlug >= 0 ? indexFromSlug : 0
	);
	const tabRefs = useRef< ( HTMLButtonElement | null )[] >( [] );
	const underlineRef = useRef< HTMLDivElement >( null );
	const isFirstRender = useRef( true );

	useEffect( () => {
		const updateUnderline = () => {
			const activeTab = tabRefs.current[ activeIndex ];
			const underline = underlineRef.current;

			if ( activeTab && underline ) {
				const { offsetLeft, offsetWidth } = activeTab;

				// Disable transition on first render
				if ( isFirstRender.current ) {
					underline.style.transition = 'none';
					isFirstRender.current = false;
				} else {
					underline.style.transition = '';
				}

				underline.style.left = `${ offsetLeft }px`;
				underline.style.width = `${ offsetWidth }px`;
			}
		};

		// Small delay to ensure DOM is ready
		const timer = setTimeout( updateUnderline, 0 );

		// Update on window resize
		window.addEventListener( 'resize', updateUnderline );
		return () => {
			clearTimeout( timer );
			window.removeEventListener( 'resize', updateUnderline );
		};
	}, [ activeIndex ] );

	const handleClick = ( index: number, slug: string ) => {
		setActiveIndex( index );
		params.set( urlKey, slug );
		window.history.replaceState( null, '', `?${ params.toString() }` );
	};

	const tabHeaders = (
		<ul className="gs-tabs__list">
			{ childArray.map( ( child, idx ) => {
				if ( ! React.isValidElement( child ) ) {
					return null;
				}
				const { label, isPro, slug, status } = child.props;
				const btnClasses = [
					'gs-tab',
					idx === activeIndex ? 'is-active' : '',
					status ? `gs-tab--status-${ status }` : '',
				];

				return (
					<li key={ slug }>
						<button
							ref={ ( el ) => ( tabRefs.current[ idx ] = el ) }
							className={ btnClasses
								.filter( Boolean )
								.join( ' ' ) }
							onClick={ () => handleClick( idx, slug ) }
							data-slug={ slug }
						>
							<span>{ label }</span>
							{ isPro && (
								<span className="gs-tab__badge">Pro</span>
							) }
						</button>
					</li>
				);
			} ) }
			<div ref={ underlineRef } className="gs-tabs__underline" />
		</ul>
	);

	const tabContent = (
		<div className="gs-tabs__panel">
			{ childArray.map( ( child, idx ) =>
				idx === activeIndex ? cloneElement( child ) : null
			) }
		</div>
	);

	return (
		<div className="gs-tabs">
			{ renderTabHeaders ? renderTabHeaders( tabHeaders ) : tabHeaders }
			{ renderTabContent ? renderTabContent( tabContent ) : tabContent }
		</div>
	);
}
