import { FieldPath, FieldValues, useController, UseControllerProps } from 'react-hook-form';
import { LatLngLiteral } from 'leaflet';
import { isBoolean, isString } from 'lodash';

import { useDefaultProps } from '../../hooks';
import { useLocalization } from '../../localization';
import { LocationPicker, LocationPickerProps } from '../map';

export type RHFLocationPickerProps<
	TFieldValues extends FieldValues = FieldValues,
	TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>
> = Omit<LocationPickerProps, 'error' | 'inputRef' | 'value' | 'onChange'> &
	UseControllerProps<TFieldValues, TName> & {
		onChange?: (lanlng: LatLngLiteral) => void;
	};

const RHFLocationPicker = <
	TName extends FieldPath<TFieldValues>,
	TFieldValues extends FieldValues = Record<TName, LatLngLiteral | null>
>(
	inProps: RHFLocationPickerProps<TFieldValues, TName>
) => {
	const {
		onChange,
		helperText,
		label,
		required,
		name,
		control,
		defaultValue,
		disabled,
		rules,
		shouldUnregister,
		...locationPickerProps
	} = useDefaultProps({ name: 'ReevolveRHFLocationPicker', props: inProps });

	const { translate } = useLocalization();

	const {
		field,
		fieldState: { error }
	} = useController<TFieldValues, TName>({
		name,
		control,
		defaultValue,
		shouldUnregister,
		disabled,
		rules: rules && {
			...rules,
			required: rules?.required === true ? translate('validation.required', { label }) : rules?.required
		}
	});

	function onChangeHandler(value: LatLngLiteral) {
		field.onChange(value);
		onChange?.(value);
	}

	return (
		<LocationPicker
			{...locationPickerProps}
			name={name}
			value={field.value}
			label={label}
			onChange={onChangeHandler}
			disabled={field.disabled}
			error={!!error}
			helperText={error?.message ?? helperText}
			required={
				isBoolean(rules?.required)
					? rules.required
					: ((isString(rules?.required) || rules?.required?.value) ?? required)
			}
			inputRef={field.ref}
		/>
	);
};

declare module '@mui/material' {
	interface Components {
		ReevolveRHFLocationPicker?: {
			defaultProps?: Partial<RHFLocationPickerProps>;
		};
	}
}

export default RHFLocationPicker;
