import { useEffect } from '@wordpress/element';
import {
	CheckboxControl,
	Flex,
	FlexBlock,
	FlexItem,
	SelectControl,
	TextControl,
	__experimentalSpacer as Spacer,
} from '@wordpress/components';
import { useFormContext } from '@woocommerce/components';
import { __ } from '@wordpress/i18n';
import { getCountryNames, getStateNames, isMailAndPhoneRequired } from 'utils';
import { useAddressContext } from './context';
import { withBoundary } from 'components/HOC';
import { ADDRESS_TYPES } from 'data/constants';

export const AddressFields = withBoundary(
	( { group, errorCallback, originCountry } ) => {
		const { isUpdating, validationErrors } = useAddressContext();

		const {
			values,
			getInputProps,
			getCheckboxControlProps,
			getSelectControlProps,
			errors,
		} = useFormContext();
		const allowChangeCountry = true;
		const countryNames = getCountryNames( group, values.country );

		const stateNames = values.country
			? getStateNames( values.country )
			: [];

		const getProps = ( key, props ) => {
			// "Props" is an optional argument which is why we have a fallback to get input props.
			if ( ! props ) {
				props = getInputProps( key );
			}

			// Mutate the props object to display input errors.
			if ( validationErrors[ key ] || errors[ key ] ) {
				return {
					...props,
					help: validationErrors[ key ] || errors[ key ],
					className: 'has-error',
				};
			}

			return props;
		};

		useEffect( () => {
			if ( 'general' in validationErrors ) {
				errorCallback( validationErrors.general );
			}
		}, [ errorCallback, validationErrors ] );

		const isPhoneAndEmailRequired = isMailAndPhoneRequired( {
			type: group,
			originCountry,
			destinationCountry: values.country,
		} );

		return (
			<div>
				<Flex direction="column">
					<TextControl
						{ ...getProps( 'name' ) }
						label={ __( 'Name', 'woocommerce-shipping' ) }
						required={ ! values.company || values.name }
						// Opting into the new styles for margin bottom
						__nextHasNoMarginBottom={ true }
						// Opting into the new styles for height
						__next40pxDefaultSize={ true }
					/>
					<Spacer marginTop={ 0 } marginBottom={ 1 } />
					<TextControl
						{ ...getProps( 'company' ) }
						label={ __( 'Company', 'woocommerce-shipping' ) }
						required={ ! values.name }
						disabled={ isUpdating }
						// Opting into the new styles for margin bottom
						__nextHasNoMarginBottom={ true }
						// Opting into the new styles for height
						__next40pxDefaultSize={ true }
					/>
					<Spacer marginTop={ 0 } marginBottom={ 1 } />
					<FlexItem>
						<Flex>
							<FlexBlock>
								<TextControl
									{ ...getProps( 'email' ) }
									label={
										group === ADDRESS_TYPES.ORIGIN
											? __(
													'Email address',
													'woocommerce-shipping'
											  )
											: __(
													'Email address',
													'woocommerce-shipping'
											  )
									}
									disabled={ isUpdating }
									required={ isPhoneAndEmailRequired }
									// Opting into the new styles for margin bottom
									__nextHasNoMarginBottom={ true }
									// Opting into the new styles for height
									__next40pxDefaultSize={ true }
								/>
							</FlexBlock>
							<FlexBlock>
								<TextControl
									{ ...getProps( 'phone' ) }
									label={
										group === ADDRESS_TYPES.ORIGIN
											? __(
													'Phone',
													'woocommerce-shipping'
											  )
											: __(
													'Phone',
													'woocommerce-shipping'
											  )
									}
									disabled={ isUpdating }
									required={ isPhoneAndEmailRequired }
									// Opting into the new styles for margin bottom
									__nextHasNoMarginBottom={ true }
									// Opting into the new styles for height
									__next40pxDefaultSize={ true }
								/>
							</FlexBlock>
						</Flex>
					</FlexItem>
					<Spacer marginTop={ 0 } marginBottom={ 1 } />
					<SelectControl
						label={ __( 'Country', 'woocommerce-shipping' ) }
						options={ countryNames }
						{ ...getProps(
							'country',
							getSelectControlProps( 'country' )
						) }
						disabled={ isUpdating || ! allowChangeCountry }
						required
						// Opting into the new styles for margin bottom
						__nextHasNoMarginBottom={ true }
						// Opting out of the new styles for height
						__next40pxDefaultSize={ true }
					/>
					<Spacer marginTop={ 0 } marginBottom={ 1 } />
					<TextControl
						label={ __( 'Address', 'woocommerce-shipping' ) }
						{ ...getProps( 'address' ) }
						disabled={ isUpdating }
						required
						// Opting into the new styles for margin bottom
						__nextHasNoMarginBottom={ true }
						// Opting into the new styles for height
						__next40pxDefaultSize={ true }
					/>
					<Spacer marginTop={ 0 } marginBottom={ 1 } />
					<TextControl
						label={ __( 'City', 'woocommerce-shipping' ) }
						{ ...getProps( 'city' ) }
						disabled={ isUpdating }
						required
						// Opting into the new styles for margin bottom
						__nextHasNoMarginBottom={ true }
						// Opting into the new styles for height
						__next40pxDefaultSize={ true }
					/>
					<Spacer marginTop={ 0 } marginBottom={ 1 } />
					<FlexItem direction="column">
						<Flex>
							<FlexBlock>
								<TextControl
									label={ __(
										'State',
										'woocommerce-shipping'
									) }
									{ ...getProps(
										'state',
										getSelectControlProps( 'state' )
									) }
									disabled={ isUpdating }
									required={ stateNames.length > 0 }
									// Opting into the new styles for margin bottom
									__nextHasNoMarginBottom={ true }
									// Opting into the new styles for height
									__next40pxDefaultSize={ true }
								/>
							</FlexBlock>
							<FlexBlock>
								<TextControl
									label={ __(
										'Postal code',
										'woocommerce-shipping'
									) }
									{ ...getProps( 'postcode' ) }
									disabled={ isUpdating }
									required
									// Opting into the new styles for margin bottom
									__nextHasNoMarginBottom={ true }
									// Opting into the new styles for height
									__next40pxDefaultSize={ true }
								/>
							</FlexBlock>
						</Flex>
						{ group === ADDRESS_TYPES.ORIGIN && (
							<>
								<Flex>
									<FlexBlock>
										<CheckboxControl
											label={ __(
												'Save as default origin address',
												'woocommerce-shipping'
											) }
											disabled={ isUpdating }
											{ ...getProps(
												'defaultAddress',
												getCheckboxControlProps(
													'defaultAddress'
												)
											) }
											__nextHasNoMarginBottom={ true }
										/>
									</FlexBlock>
								</Flex>
								<Flex>
									<FlexBlock>
										<CheckboxControl
											label={ __(
												'Save as default return address',
												'woocommerce-shipping'
											) }
											disabled={ isUpdating }
											{ ...getProps(
												'defaultReturnAddress',
												getCheckboxControlProps(
													'defaultReturnAddress'
												)
											) }
											__nextHasNoMarginBottom={ true }
										/>
									</FlexBlock>
								</Flex>
							</>
						) }
					</FlexItem>
				</Flex>
			</div>
		);
	}
)( 'AddressFields' );
