import { writable } from 'svelte/store';
import { browser } from '$app/environment';
import { goto } from '$app/navigation';
import { currentArxletTitle } from './stores/settings';

export interface NavigationState {
	canGoBack: boolean;
	canGoForward: boolean;
	currentIndex: number;
	history: string[];
}

function createNavigationStore() {
	const initialState: NavigationState = {
		canGoBack: false,
		canGoForward: false,
		currentIndex: 0,
		history: []
	};

	const { subscribe, set, update } = writable<NavigationState>(initialState);

	let isNavigating = false;

	function updateNavigationState() {
		if (!browser) return;

		currentArxletTitle.set('');

		update((state) => {
			return {
				...state,
				canGoBack: window.history.length > 1 && state.currentIndex > 0,
				canGoForward: state.currentIndex < state.history.length - 1
			};
		});
	}

	function pushState(url: string) {
		if (!browser || isNavigating) return;

		update((state) => {
			const newHistory = [...state.history.slice(0, state.currentIndex + 1), url];
			const newIndex = newHistory.length - 1;

			return {
				...state,
				history: newHistory,
				currentIndex: newIndex,
				canGoBack: newIndex > 0,
				canGoForward: false
			};
		});
	}

	function goBack() {
		if (!browser) return false;

		let canGo = false;
		update((state) => {
			if (state.canGoBack) {
				canGo = true;
				const newIndex = state.currentIndex - 1;
				return {
					...state,
					currentIndex: newIndex,
					canGoBack: newIndex > 0,
					canGoForward: true
				};
			}
			return state;
		});

		if (canGo) {
			isNavigating = true;
			window.history.go(-1);
			setTimeout(() => {
				isNavigating = false;
			}, 100);
		}

		return canGo;
	}

	function goForward() {
		if (!browser) return false;

		let canGo = false;
		update((state) => {
			if (state.canGoForward) {
				canGo = true;
				const newIndex = state.currentIndex + 1;
				return {
					...state,
					currentIndex: newIndex,
					canGoBack: true,
					canGoForward: newIndex < state.history.length - 1
				};
			}
			return state;
		});

		if (canGo) {
			isNavigating = true;
			window.history.go(1);
			setTimeout(() => {
				isNavigating = false;
			}, 100);
		}

		return canGo;
	}

	function navigateTo(url: string) {
		currentArxletTitle.set('');
		pushState(url);
		goto(url);
	}

	function initialize(currentUrl: string) {
		if (!browser) return;

		set({
			canGoBack: window.history.length > 1,
			canGoForward: false,
			currentIndex: 0,
			history: [currentUrl]
		});

		const handlePopState = () => {
			currentArxletTitle.set('');
			if (!isNavigating) updateNavigationState();
		};

		window.addEventListener('popstate', handlePopState);
		window.addEventListener('pushstate', () => {
			currentArxletTitle.set('');
		});

		return () => {
			window.removeEventListener('popstate', handlePopState);
		};
	}

	return {
		subscribe,
		pushState,
		goBack,
		goForward,
		navigateTo,
		initialize,
		updateNavigationState
	};
}

export const navigationStore = createNavigationStore();
