import apiFetch from '@wordpress/api-fetch';
import { createContext, useContext, useEffect, useState } from '@wordpress/element';
import { select, subscribe } from '@wordpress/data';

const DeviceContext = createContext();

const DEFAULT_DEVICES = {
	desktop: {
		name: 'Desktop',
		width: '100%',
		media: '',
	},
	tablet: {
		name: 'Tablet',
		width: '1024px',
		media: '@media (max-width: 1024px)',
	},
	mobile: {
		name: 'Mobile',
		width: '768px',
		media: '@media (max-width: 768px)',
	},
};

function normalizeDeviceSettings( settings ) {
	const tabletWidth = settings?.devices?.tablet?.width || '1024px';
	const mobileWidth = settings?.devices?.mobile?.width || '768px';

	return {
		desktop: {
			name: 'Desktop',
			width: '100%',
			media: '',
		},
		tablet: {
			name: settings?.devices?.tablet?.name || 'Tablet',
			width: tabletWidth,
			media: `@media (max-width: ${ tabletWidth })`,
		},
		mobile: {
			name: settings?.devices?.mobile?.name || 'Mobile',
			width: mobileWidth,
			media: `@media (max-width: ${ mobileWidth })`,
		},
	};
}

// Read the current WP preview device type so the per-block control opens in
// sync with WP's top-right switcher (e.g. user already switched to Tablet).
const getInitialActiveDevice = () => {
	try {
		const wpType =
			select( 'core/editor' )?.getDeviceType?.() ||
			select( 'core/edit-post' )?.__experimentalGetPreviewDeviceType?.() ||
			'Desktop';
		return wpType.toLowerCase();
	} catch ( e ) {
		return 'desktop';
	}
};

const getWpActiveDevice = () => {
	try {
		const wpType =
			select( 'core/editor' )?.getDeviceType?.() ||
			select( 'core/edit-post' )?.__experimentalGetPreviewDeviceType?.() ||
			'Desktop';
		return wpType.toLowerCase();
	} catch ( e ) {
		return 'desktop';
	}
};

export const DeviceProvider = ( { children } ) => {
	const [ activeDevice, setActiveDevice ] = useState( getInitialActiveDevice );
	const [ devices, setDevices ] = useState( DEFAULT_DEVICES );

	useEffect( () => {
		const syncFromWp = () => {
			const nextDevice = getWpActiveDevice();
			setActiveDevice( ( current ) => ( current === nextDevice ? current : nextDevice ) );
		};

		syncFromWp();

		return subscribe( syncFromWp );
	}, [] );

	useEffect( () => {
		const loadDeviceSettings = async () => {
			try {
				const settings = await apiFetch( {
					path: '/axcelersblocks/v1/device-settings',
				} );
				setDevices( normalizeDeviceSettings( settings ) );
			} catch ( error ) {
				setDevices( DEFAULT_DEVICES );
			}
		};

		loadDeviceSettings();
	}, [] );

	return (
		<DeviceContext.Provider
			value={ { activeDevice, setActiveDevice, devices } }
		>
			{ children }
		</DeviceContext.Provider>
	);
};

export const useDevice = () => useContext( DeviceContext );
