import {startTransition, useCallback, useEffect, useMemo, useRef, useState} from 'react';
import useFormSubmitSuccess from "../../hooks/useFormSubmitSuccess";
import IntlTelInput, {type IntlTelInputRef} from "intl-tel-input/react";
import isEditMode from "../../utils/isEditMode";
import type {Iso2} from "intl-tel-input/data";
import type {FieldProps} from './Field';
import use from "../../utils/use";
import fetchUtils from "./utils";
import geoIpLookup from "./geoIpLookup";
import {Iti} from 'intl-tel-input';

type TelInputProps = FieldProps & {
	attrs: Record<string, string>
}

const TelInput = (props: TelInputProps) => {
	const inputRef = useRef<HTMLInputElement>(null);
	const inputRef2 = useRef<IntlTelInputRef | null>(null);

	const [value, setValue] = useState(props.value);
	const [isValid, setIsValid] = useState(false);
	const [errorCode, setErrorCode] = useState<number | null>(null);
	const [fullPhone, setFullPhone] = useState('');

	// Reset after form submit
	useFormSubmitSuccess(inputRef, () => {
		setValue(props.value);
	}, [props.value]);

	const utilsLib: object = use(fetchUtils());

	const geoIpLookupCode: Iso2 = useMemo(() => {
		if (props.autoCountry) {
			return use(geoIpLookup());
		}
		return '' as Iso2;
	}, [props.autoCountry]);

	const geoIpLookupCallback = useCallback((callback: any) => {
		if (props.autoCountry && geoIpLookupCode) {
			return callback(geoIpLookupCode)
		}
		return null;
	}, [geoIpLookupCode, props.autoCountry]);

	const excludeCountries = useMemo(() => {
		if (props.autoCountry) {
			return props.excludeCountries.filter(value1 => {
				return value1.toLowerCase() !== geoIpLookupCode.toLowerCase();
			});
		}
		return props.excludeCountries;
	}, [geoIpLookupCode, props.autoCountry, props.excludeCountries]);

	const onlyCountries = useMemo(() => {
		if (props.autoCountry && props.onlyCountries.length > 0) {
			const found = props.onlyCountries.some(value1 => {
				return value1.toLowerCase() === geoIpLookupCode.toLowerCase();
			});
			if (!found) {
				props.onlyCountries.push(geoIpLookupCode);
			}
		}
		return props.onlyCountries;
	}, [geoIpLookupCode, props.autoCountry, props.onlyCountries]);

	const instance = useRef<Iti | null | undefined>(null);

	useEffect(() => {
		if (!props.fullPhone) {
			return;
		}
		startTransition(() => {
			if (!instance.current) {
				instance.current = inputRef2.current?.getInstance();
			}
			if (!instance.current) {
				return;
			}
			setFullPhone(instance.current.getNumber());
		});
	}, [props.fullPhone, value]);

	return (
		<>
			<IntlTelInput
				ref={inputRef2}
				initialValue={value}
				onChangeNumber={setValue}
				onChangeValidity={setIsValid}
				onChangeErrorCode={setErrorCode}
				inputProps={{
					...props.attrs,
					id: `${props.attrs.id}-telephone`
				}}
				initOptions={{
					initialCountry: props.autoCountry ? 'auto' : props.initialCountry,
					strictMode: props.strictMode,
					countryOrder: props.countryOrder,
					excludeCountries,
					onlyCountries,
					nationalMode: props.nationalMode,
					showFlags: props.showFlags,
					separateDialCode: props.separateDialCode,
					countrySearch: true,
					allowDropdown: true,
					fixDropdownWidth: true,
					allowedNumberTypes: ['MOBILE'],
					placeholderNumberType: 'MOBILE',
					dropdownContainer: document.querySelector('body'),
					...(props.placeholder && {
						customPlaceholder: (selectedCountryPlaceholder: string) => {
							return props.placeholder.replace('{{country}}', selectedCountryPlaceholder)
						}
					}),
					...(isEditMode && {useFullscreenPopup: false}),
					...((props.autoCountry && geoIpLookupCode) && {geoIpLookup: geoIpLookupCallback}),
					loadUtils: (): Promise<{ default: any }> => Promise.resolve({default: utilsLib}),
					containerClass: 'hulk-telephone',
				}}
			/>
			<input ref={inputRef} type="hidden" name={`form_fields[${props.custom_id}_fullPhone]`}
				   defaultValue={fullPhone}/>
			<input type="hidden" name={`form_fields[${props.custom_id}_isValid]`} defaultValue={String(isValid)}/>
			<input type="hidden" name={`form_fields[${props.custom_id}_errorCode]`} defaultValue={errorCode || 0}/>
			<div id={props.attrs.id}/>
		</>
	);
};

export default TelInput;
