import {
	type AdminData,
	type AdminRecord,
	field,
	safeArray,
	safeRecord,
} from './admin-data';

export const launchDetailUuidFromLocation = (
	search = 'undefined' === typeof window ? '' : window.location.search,
	hash = 'undefined' === typeof window ? '' : window.location.hash
): string => {
	const params = new URLSearchParams( search );

	if ( 'change' === params.get( 'detail' ) && params.get( 'launch' ) ) {
		return params.get( 'launch' ) || '';
	}

	const hashMatch = hash.match( /^#change-([a-zA-Z0-9_-]+)$/ );

	return hashMatch?.[ 1 ] || '';
};

export const launchDetailFromLocation = (
	launches: AdminRecord[],
	search?: string,
	hash?: string
): AdminRecord | null => {
	const uuid = launchDetailUuidFromLocation( search, hash );

	if ( ! uuid ) {
		return null;
	}

	return (
		launches.find( ( launch ) => field( launch, 'uuid' ) === uuid ) || {
			uuid,
		}
	);
};

export const launchDetailFromData = (
	data: AdminData,
	uuid: string
): AdminRecord => {
	const launch = findLaunchByUuid(
		safeArray< AdminRecord >( data.launches ),
		uuid
	);

	if ( launch ) {
		return launch;
	}

	const calendarLaunch = findLaunchByUuid(
		safeArray< AdminRecord >( data.calendar ),
		uuid
	);

	if ( calendarLaunch ) {
		return calendarLaunch;
	}

	for ( const target of safeArray< AdminRecord >( data.targets ) ) {
		const historyLaunch = findLaunchByUuid(
			safeArray< AdminRecord >( safeRecord( target ).history ),
			uuid
		);

		if ( historyLaunch ) {
			return historyLaunch;
		}
	}

	return { uuid };
};

const findLaunchByUuid = (
	launches: AdminRecord[],
	uuid: string
): AdminRecord | null =>
	launches.find(
		( launch ) =>
			field( launch, 'uuid' ) === uuid || field( launch, 'id' ) === uuid
	) || null;

export const launchDetailHref = ( baseHref: string, uuid: string ): string => {
	if ( ! uuid ) {
		return baseHref || '#';
	}

	try {
		const fallbackHref =
			'undefined' === typeof window
				? 'http://scheduled-changes.local/'
				: window.location.href;
		const url = new URL( baseHref || fallbackHref, fallbackHref );

		url.hash = '';
		url.searchParams.set( 'detail', 'change' );
		url.searchParams.set( 'launch', uuid );

		return url.toString();
	} catch {
		const href = ( baseHref || '' ).split( '#' )[ 0 ];
		const separator = href.includes( '?' ) ? '&' : '?';

		return `${
			href || ''
		}${ separator }detail=change&launch=${ encodeURIComponent( uuid ) }`;
	}
};

export const pushLaunchDetailRoute = ( uuid: string ): void => {
	if ( 'undefined' === typeof window || ! uuid || ! window.history ) {
		return;
	}

	window.history.pushState(
		{
			...( 'object' === typeof window.history.state &&
			null !== window.history.state
				? window.history.state
				: {} ),
			scheduledChangesDetail: 'change',
			scheduledChangesLaunch: uuid,
		},
		'',
		launchDetailHref( window.location.href, uuid )
	);
};

export const clearLaunchDetailRoute = (): void => {
	if ( 'undefined' === typeof window || ! window.history ) {
		return;
	}

	const url = new URL( window.location.href );
	url.hash = '';
	url.searchParams.delete( 'detail' );
	url.searchParams.delete( 'launch' );
	window.history.replaceState(
		{
			...( 'object' === typeof window.history.state &&
			null !== window.history.state
				? window.history.state
				: {} ),
			scheduledChangesDetail: '',
			scheduledChangesLaunch: '',
		},
		'',
		url.toString()
	);
};
