import { RefAttributes, useState } from 'react';
import { PiGpsBold, PiGpsFixBold, PiMinusBold, PiPlusBold } from 'react-icons/pi';
import { Marker, MarkerProps, useMapEvent } from 'react-leaflet';
import {
	ButtonBase,
	ButtonBaseProps,
	Divider,
	Paper,
	PaperProps,
	Stack,
	StackProps,
	styled,
	Tooltip
} from '@mui/material';
import { useNotification } from '@remate/core';
import { icon, LatLngLiteral, Marker as LeafletMarker } from 'leaflet';
import { isFunction } from 'lodash';

import { useLocalization } from '../../../localization';

export interface IControlsProps {
	onChange?: (value: LatLngLiteral) => void;
	/**
	 * @default true
	 */
	enableShowUserLocation?: boolean;

	slotProps?: {
		root?: StackProps;
		paper?: PaperProps;
		button?: Omit<ButtonBaseProps, 'onClick' | 'disabled'>;
		userLocationMarker?: Omit<MarkerProps, 'position'> & RefAttributes<LeafletMarker<any>>;
	};
}

const Controls = ({ onChange, enableShowUserLocation = true, slotProps }: IControlsProps) => {
	const map = useMapEvent('zoom', (evt) => {
		setCurrentZoom(evt.target.getZoom() as number);
	});

	const [currentZoom, setCurrentZoom] = useState(map.getZoom());
	const { open } = useNotification();
	const { translate } = useLocalization();
	const [gettingUserPosition, setGettingUserPosition] = useState(false);
	const [userPosiotion, setUserPosition] = useState<LatLngLiteral | null>(null);

	return (
		<>
			<Stack
				spacing={1}
				style={{ position: 'absolute', bottom: 8, left: 8 }}
				{...slotProps?.root}
			>
				{enableShowUserLocation && (
					<Paper
						elevation={2}
						{...slotProps?.paper}
						sx={(theme) => ({
							zIndex: 500,
							borderRadius: 0.5,
							overflow: 'hidden',
							...(isFunction(slotProps?.paper?.sx) ? (slotProps.paper.sx as Function)(theme) : slotProps?.paper?.sx)
						})}
					>
						<Tooltip
							title={translate('locationPicker.userLocationTooltipText')}
							placement="right"
							arrow
						>
							<ControlButton
								{...slotProps?.button}
								disabled={gettingUserPosition}
								onClick={() => {
									setGettingUserPosition(true);
									navigator.geolocation.getCurrentPosition(
										({ coords: { latitude, longitude } }) => {
											const value = { lat: latitude, lng: longitude };
											onChange?.(value);
											setUserPosition(value);
											map.flyTo(value, 17);
											setGettingUserPosition(false);
										},
										(error) => {
											setGettingUserPosition(false);
											open?.({
												type: 'error',
												message: translate('locationPicker.geolocationPositionError', error)
											});
										},
										{ enableHighAccuracy: true }
									);
								}}
							>
								{gettingUserPosition ? <PiGpsBold /> : <PiGpsFixBold />}
							</ControlButton>
						</Tooltip>
					</Paper>
				)}

				<Paper
					elevation={2}
					{...slotProps?.paper}
					sx={(theme) => ({
						zIndex: 500,
						borderRadius: 0.5,
						overflow: 'hidden',
						...(isFunction(slotProps?.paper?.sx) ? (slotProps.paper.sx as Function)(theme) : slotProps?.paper?.sx)
					})}
				>
					<Stack>
						<ControlButton
							{...slotProps?.button}
							disabled={map.getMaxZoom() <= currentZoom}
							onClick={() => {
								map.zoomIn();
							}}
						>
							<PiPlusBold />
						</ControlButton>

						<Divider sx={{ marginX: 0.75 }} />

						<ControlButton
							{...slotProps?.button}
							disabled={map.getMinZoom() >= currentZoom}
							onClick={() => {
								map.zoomOut();
							}}
						>
							<PiMinusBold />
						</ControlButton>
					</Stack>
				</Paper>
			</Stack>

			{userPosiotion && (
				<Marker
					position={userPosiotion}
					{...slotProps?.userLocationMarker}
					icon={icon({
						iconUrl: currentLocationicon,
						iconSize: [32, 32]
					})}
				/>
			)}
		</>
	);
};

const currentLocationicon =
	'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGNsYXNzPSJzdmctaWNvbiIgc3R5bGU9IndpZHRoOiAxZW07IGhlaWdodDogMWVtO3ZlcnRpY2FsLWFsaWduOiBtaWRkbGU7ZmlsbDogY3VycmVudENvbG9yO292ZXJmbG93OiBoaWRkZW47IiB2aWV3Qm94PSIwIDAgMTAyNCAxMDI0IiB2ZXJzaW9uPSIxLjEiPjxwYXRoIGQ9Ik01MTEuOTI3NDc5IDU3NC4zNjgyNzJtLTQ0OS42MzE3MjggMGE0NDkuNjMxNzI4IDQ0OS42MzE3MjggMCAxIDAgODk5LjI2MzQ1NiAwIDQ0OS42MzE3MjggNDQ5LjYzMTcyOCAwIDEgMC04OTkuMjYzNDU2IDBaIiBmaWxsPSIjMkI2N0VEIiBvcGFjaXR5PSIuMzQiLz48cGF0aCBkPSJNNTExLjkyNzQ3OSA1NzQuMzY4MjcybS0yNjEuMjIxNTMgMGEyNjEuMjIxNTMgMjYxLjIyMTUzIDAgMSAwIDUyMi40NDMwNTkgMCAyNjEuMjIxNTMgMjYxLjIyMTUzIDAgMSAwLTUyMi40NDMwNTkgMFoiIGZpbGw9IiM0MzgxRUYiLz48cGF0aCBkPSJNNTExLjkyNzQ3OSA4MzUuNzM0ODQ0YTI2MS4wNzY0ODcgMjYxLjA3NjQ4NyAwIDEgMSAyNjEuMDc2NDg3LTI2MS4wNzY0ODcgMjYxLjA3NjQ4NyAyNjEuMDc2NDg3IDAgMCAxLTI2MS4wNzY0ODcgMjYxLjA3NjQ4N3ogbTAtNDkzLjE0NDQ3NmEyMzIuMDY3OTg5IDIzMi4wNjc5ODkgMCAxIDAgMjMyLjA2Nzk4OCAyMzIuMDY3OTg5IDIzMi4wNjc5ODkgMjMyLjA2Nzk4OSAwIDAgMC0yMzIuMDY3OTg4LTIzMi42NDgxNTl6IiBmaWxsPSIjRkZGRkZGIi8+PC9zdmc+';

const ControlButton = styled(ButtonBase)({
	width: 36,
	height: 36,
	'&:disabled': { opacity: 0.5 },
	'& svg': {
		fontSize: 17
	}
});

export default Controls;
