/**
 * Hash routing. Every submenu item points at the same PHP page with a
 * different `#/fragment`, so the fragment is the route; `hashchange` covers
 * both the submenu links and the back button.
 */

import { useCallback, useEffect, useState } from 'react';

export type RouteId =
	| 'home'
	| 'services'
	| 'team'
	| 'resources'
	| 'placements'
	| 'design'
	| 'seo'
	| 'support'
	| 'settings';

export interface Route {
	id: RouteId;
	/** Everything after the route segment, e.g. `gallery` in `#/placements/gallery`. */
	sub: string | null;
}

const ROUTES: Record< string, RouteId > = {
	'': 'home',
	home: 'home',
	services: 'services',
	team: 'team',
	resources: 'resources',
	placements: 'placements',
	design: 'design',
	seo: 'seo',
	support: 'support',
	settings: 'settings',
};

export function parse( hash: string ): Route {
	const raw = hash.replace( /^#\/?/, '' ).replace( /\/+$/, '' );
	const [ head, ...rest ] = raw.split( '/' );

	return {
		id: ROUTES[ head ] ?? 'home',
		sub: rest.length ? rest.join( '/' ) : null,
	};
}

export function useRoute(): [ Route, ( to: string ) => void ] {
	const [ route, setRoute ] = useState< Route >( () => parse( window.location.hash ) );

	useEffect( () => {
		const onChange = () => setRoute( parse( window.location.hash ) );

		window.addEventListener( 'hashchange', onChange );

		return () => window.removeEventListener( 'hashchange', onChange );
	}, [] );

	const go = useCallback( ( to: string ) => {
		const next = `#/${ to.replace( /^#?\/?/, '' ) }`;

		if ( window.location.hash === next ) {
			// Assigning the same hash fires no event.
			setRoute( parse( next ) );

			return;
		}

		window.location.hash = next;
	}, [] );

	return [ route, go ];
}
