import { writable } from 'svelte/store';

const IOS_HINT_DISMISSED_KEY = 'phonecam-ios-install-hint-dismissed';

const createInitialState = () => ({
	installAvailable: false,
	updateAvailable: false,
	offlineReady: false,
	installing: false,
	isOffline: false,
	isStandalone: false,
	showIosInstallHint: false
});

export const pwaState = writable(createInitialState());

let deferredInstallPrompt: any = null;

const setPwaState = (partial: Record<string, unknown>) => {
	pwaState.update((state) => ({
		...state,
		...partial
	}));
};

export const setInstallPrompt = (event: any) => {
	deferredInstallPrompt = event;
	setPwaState({
		installAvailable: true
	});
};

export const clearInstallPrompt = () => {
	deferredInstallPrompt = null;
	setPwaState({
		installAvailable: false,
		installing: false
	});
};

export const setUpdateAvailable = (updateAvailable: boolean) => {
	setPwaState({ updateAvailable });
};

export const setOfflineReady = (offlineReady: boolean) => {
	setPwaState({ offlineReady });
};

export const dismissOfflineReady = () => {
	setPwaState({ offlineReady: false });
};

export const setOnlineStatus = (isOnline: boolean) => {
	setPwaState({ isOffline: !isOnline });
};

export const setStandaloneMode = (isStandalone: boolean) => {
	setPwaState({ isStandalone });
};

const isIosSafariInstallable = () => {
	if (typeof window === 'undefined' || typeof navigator === 'undefined') {
		return false;
	}

	const userAgent = navigator.userAgent || '';
	const isIos = /iPad|iPhone|iPod/.test(userAgent);
	const isWebkit = /WebKit/.test(userAgent);
	const isCriOS = /CriOS/.test(userAgent);
	const isFxiOS = /FxiOS/.test(userAgent);

	return isIos && isWebkit && !isCriOS && !isFxiOS;
};

export const syncInstallHelpState = () => {
	if (typeof window === 'undefined') {
		return;
	}

	const isStandalone =
		window.matchMedia?.('(display-mode: standalone)').matches || (window.navigator as any)?.standalone === true;
	const dismissed =
		typeof localStorage !== 'undefined' && localStorage.getItem(IOS_HINT_DISMISSED_KEY) === 'true';

	setPwaState({
		isStandalone,
		showIosInstallHint: isIosSafariInstallable() && !isStandalone && !dismissed && !deferredInstallPrompt
	});
};

export const dismissIosInstallHint = () => {
	if (typeof localStorage !== 'undefined') {
		localStorage.setItem(IOS_HINT_DISMISSED_KEY, 'true');
	}
	setPwaState({ showIosInstallHint: false });
};

export const promptInstall = async () => {
	if (!deferredInstallPrompt) {
		return false;
	}

	setPwaState({
		installing: true
	});

	try {
		await deferredInstallPrompt.prompt();
		const choice = await deferredInstallPrompt.userChoice;
		clearInstallPrompt();
		syncInstallHelpState();
		return choice?.outcome === 'accepted';
	} catch (error) {
		setPwaState({
			installing: false
		});
		throw error;
	}
};
