import { createEffect, createSignal, onCleanup } from 'solid-js';

export const LOADING_DELAY_MS = 100;

export const resolveDefaultBranchName = (
	branches: { is_default?: boolean; reference: { name: string } }[] | undefined,
): string | undefined =>
	branches?.find((branch) => branch.is_default)?.reference.name ?? branches?.[0]?.reference.name;

export const resolveRouteRefAndPath = (
	initialRef: string,
	initialPath: string,
	branchNames: string[] | undefined,
): { ref: string; path: string } => {
	if (!branchNames || !initialPath) {
		return { ref: initialRef, path: initialPath };
	}

	const names = new Set(branchNames);
	const pathSegments = initialPath.split('/').filter(Boolean);
	let resolved = { ref: initialRef, path: initialPath };

	for (let index = 0; index < pathSegments.length; index += 1) {
		const candidate = [initialRef, ...pathSegments.slice(0, index + 1)].join('/');
		if (names.has(candidate)) {
			resolved = {
				ref: candidate,
				path: pathSegments.slice(index + 1).join('/'),
			};
		}
	}

	return resolved;
};

export const hasNamedRef = (
	name: string,
	branches: { reference: { name: string } }[],
	tags: { name: string }[],
): boolean => branches.some((branch) => branch.reference.name === name) || tags.some((tag) => tag.name === name);

export const normalizeLanguages = (
	languages: Array<{ name: string; percentage: number; size: number; color?: string }>,
	totalSize?: number,
): Array<{ name: string; percentage: number; size: number; color?: string }> => {
	const computedTotalSize = totalSize ?? languages.reduce((sum, language) => sum + language.size, 0);
	return languages
		.map((language) => ({
			...language,
			percentage: computedTotalSize > 0 ? (language.size / computedTotalSize) * 100 : language.percentage,
		}))
		.sort((left, right) => right.size - left.size || left.name.localeCompare(right.name));
};

export const useDelayedLoading = (pending: () => boolean, delayMs = LOADING_DELAY_MS) => {
	const [visible, setVisible] = createSignal(false);
	let timer: ReturnType<typeof setTimeout> | undefined;

	createEffect(() => {
		if (pending()) {
			if (timer === undefined) {
				timer = setTimeout(() => {
					timer = undefined;
					setVisible(true);
				}, delayMs);
			}
			return;
		}

		if (timer !== undefined) {
			clearTimeout(timer);
			timer = undefined;
		}
		setVisible(false);
	});

	onCleanup(() => {
		if (timer !== undefined) clearTimeout(timer);
	});

	return visible;
};

export const shouldAnimateNavigation = (event: MouseEvent) =>
	event.button === 0 && !event.metaKey && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.defaultPrevented;
