/**
 * External dependencies
 */
import { __ } from '@wordpress/i18n';
import { Button, TextControl, Notice, Spinner } from '@wordpress/components';
import { SelectControl } from '@woocommerce/components';
import { Icon, chevronDown } from '@wordpress/icons';
import {
	createInterpolateElement,
	useEffect,
	useState,
} from '@wordpress/element';
import { findCountryOption, getCountry } from '@woocommerce/onboarding';
import { decodeEntities } from '@wordpress/html-entities';

/**
 * Internal dependencies
 */
import { CoreProfilerStateMachineContext, BusinessInfoEvent } from '../index';
import { CountryStateOption } from '../services/country';
import { Heading } from '../components/heading/heading';
import { Navigation } from '../components/navigation/navigation';

/** These are some store names that are known to be set by default and not likely to be used as actual names */
export const POSSIBLY_DEFAULT_STORE_NAMES = [
	undefined,
	'woocommerce',
	'Site Title',
	'',
];
export type IndustryChoice = ( typeof industryChoices )[ number ][ 'key' ];
export const industryChoices = [
	{
		label: __( 'Clothing and accessories', 'woocommerce' ),
		key: 'clothing_and_accessories' as const,
	},
	{
		label: __( 'Health and beauty', 'woocommerce' ),
		key: 'health_and_beauty' as const,
	},
	{
		label: __( 'Food and drink', 'woocommerce' ),
		key: 'food_and_drink' as const,
	},
	{
		label: __( 'Home, furniture and garden', 'woocommerce' ),
		key: 'home_furniture_and_garden' as const,
	},
	{
		label: __( 'Education and learning', 'woocommerce' ),
		key: 'education_and_learning' as const,
	},
	{
		label: __( 'Electronics and computers', 'woocommerce' ),
		key: 'electronics_and_computers' as const,
	},
	{
		label: __( 'Other', 'woocommerce' ),
		key: 'other' as const,
	},
];

export type IndustryChoiceOption = ( typeof industryChoices )[ number ];

export const selectIndustryMapping = {
	im_just_starting_my_business: __(
		'What type of products or services do you plan to sell?',
		'woocommerce'
	),
	im_already_selling: __(
		'Which industry is your business in?',
		'woocommerce'
	),
	im_setting_up_a_store_for_a_client: __(
		"Which industry is your client's business in?",
		'woocommerce'
	),
};

export type BusinessInfoContextProps = Pick<
	CoreProfilerStateMachineContext,
	'geolocatedLocation' | 'userProfile' | 'businessInfo' | 'countries'
> & {
	onboardingProfile: Pick<
		CoreProfilerStateMachineContext[ 'onboardingProfile' ],
		'industry' | 'business_choice' | 'is_store_country_set'
	>;
};

export const BusinessInfo = ( {
	context,
	navigationProgress,
	sendEvent,
}: {
	context: BusinessInfoContextProps;
	navigationProgress: number;
	sendEvent: ( event: BusinessInfoEvent ) => void;
} ) => {
	const {
		geolocatedLocation,
		userProfile: { businessChoice },
		businessInfo,
		countries,
		onboardingProfile: {
			is_store_country_set: isStoreCountrySet,
			industry: industryFromOnboardingProfile,
			business_choice: businessChoiceFromOnboardingProfile,
		},
	} = context;

	const [ storeName, setStoreName ] = useState(
		businessInfo.storeName || ''
	);

	const [ storeCountry, setStoreCountry ] = useState< CountryStateOption >( {
		key: '',
		label: '',
	} );

	useEffect( () => {
		if ( isStoreCountrySet ) {
			const previouslyStoredCountryOption = countries.find(
				( country ) => country.key === businessInfo.location
			);
			setStoreCountry(
				previouslyStoredCountryOption || { key: '', label: '' }
			);
		}
	}, [ businessInfo.location, countries, isStoreCountrySet ] );

	const [ geolocationMatch, setGeolocationMatch ] = useState( {
		key: '',
		label: '',
	} );

	useEffect( () => {
		if ( geolocatedLocation ) {
			const foundCountryOption = findCountryOption(
				countries,
				geolocatedLocation
			);
			if ( foundCountryOption ) {
				setGeolocationMatch( foundCountryOption );
				if ( ! isStoreCountrySet ) {
					setStoreCountry( foundCountryOption );
				}
			}
		}
	}, [ countries, isStoreCountrySet, geolocatedLocation ] );

	const geolocationOverruled =
		geolocatedLocation &&
		getCountry( storeCountry.key ) !== getCountry( geolocationMatch.key );

	const [ industry, setIndustry ] = useState<
		IndustryChoiceOption | undefined
	>(
		industryFromOnboardingProfile
			? industryChoices.find(
					( choice ) =>
						choice.key === industryFromOnboardingProfile[ 0 ]
			  )
			: undefined
	);

	const selectCountryLabel = __( 'Select country/region', 'woocommerce' );
	const selectIndustryQuestionLabel =
		selectIndustryMapping[
			businessChoice ||
				businessChoiceFromOnboardingProfile ||
				'im_just_starting_my_business'
		];

	const [ dismissedGeolocationNotice, setDismissedGeolocationNotice ] =
		useState( false );

	const [ hasSubmitted, setHasSubmitted ] = useState( false );

	return (
		<div
			className="woocommerce-profiler-business-information"
			data-testid="core-profiler-business-information"
		>
			<Navigation percentage={ navigationProgress } />
			<div className="woocommerce-profiler-page__content woocommerce-profiler-business-information__content">
				<Heading
					className="woocommerce-profiler__stepper-heading"
					title={ __(
						'Tell us a bit about your store',
						'woocommerce'
					) }
					subTitle={ __(
						"We'll use this information to help you set up payments, shipping, and taxes, as well as recommending the best theme for your store.",
						'woocommerce'
					) }
				/>

				<form
					className="woocommerce-profiler-business-information-form"
					autoComplete="off"
				>
					<TextControl
						className="woocommerce-profiler-business-info-store-name"
						onChange={ ( value ) => {
							setStoreName( value );
						} }
						value={ decodeEntities( storeName ) }
						label={
							<>
								{ __(
									'Give your store a name',
									'woocommerce'
								) }
							</>
						}
						placeholder={ __(
							'Ex. My awesome store',
							'woocommerce'
						) }
					/>
					<p className="woocommerce-profiler-question-subtext">
						{ __(
							"Don't worry — you can always change it later!",
							'woocommerce'
						) }
					</p>
					<p className="woocommerce-profiler-question-label">
						{ selectIndustryQuestionLabel }
					</p>
					<SelectControl
						className="woocommerce-profiler-select-control__industry"
						instanceId={ 1 }
						placeholder={ __(
							'Select an industry',
							'woocommerce'
						) }
						label={ __( 'Select an industry', 'woocommerce' ) }
						options={ industryChoices }
						excludeSelectedOptions={ false }
						help={ <Icon icon={ chevronDown } /> }
						onChange={ (
							results: Array<
								( typeof industryChoices )[ number ]
							>
						) => {
							if ( results.length ) {
								setIndustry( results[ 0 ] );
							}
						} }
						selected={ industry ? [ industry ] : [] }
						showAllOnFocus
						isSearchable
					/>
					<p className="woocommerce-profiler-question-label">
						{ __( 'Where is your store located?', 'woocommerce' ) }
						<span className="woocommerce-profiler-question-required">
							{ '*' }
						</span>
					</p>
					<SelectControl
						className="woocommerce-profiler-select-control__country"
						instanceId={ 2 }
						placeholder={ selectCountryLabel }
						label={
							storeCountry.key === '' ? selectCountryLabel : ''
						}
						getSearchExpression={ ( query: string ) => {
							return new RegExp(
								'(^' + query + '| — (' + query + '))',
								'i'
							);
						} }
						options={ countries }
						excludeSelectedOptions={ false }
						help={ <Icon icon={ chevronDown } /> }
						onChange={ ( results: Array< CountryStateOption > ) => {
							if ( results.length ) {
								setStoreCountry( results[ 0 ] );
							}
						} }
						selected={ storeCountry ? [ storeCountry ] : [] }
						showAllOnFocus
						isSearchable
					/>
					{ /* woocommerce-profiler-select-control__country-spacer exists purely because the select-control above has an unremovable and unstyleable div and that's preventing margin collapse */ }
					<div className="woocommerce-profiler-select-control__country-spacer" />
					{ geolocationOverruled && ! dismissedGeolocationNotice && (
						<Notice
							className="woocommerce-profiler-geolocation-notice"
							onRemove={ () =>
								setDismissedGeolocationNotice( true )
							}
							status="warning"
						>
							<p>
								{ createInterpolateElement(
									__(
										// translators: first tag is filled with the country name detected by geolocation, second tag is the country name selected by the user
										"It looks like you're located in <geolocatedCountry></geolocatedCountry>. Are you sure you want to create a store in <selectedCountry></selectedCountry>?",
										'woocommerce'
									),
									{
										geolocatedCountry: (
											<Button
												className="geolocation-notice-geolocated-country"
												variant="link"
												onClick={ () =>
													setStoreCountry(
														geolocationMatch
													)
												}
											>
												{
													geolocatedLocation?.country_long
												}
											</Button>
										),
										selectedCountry: (
											<span className="geolocation-notice-selected-country">
												{ storeCountry.label }
											</span>
										),
									}
								) }
							</p>
							<p>
								{ __(
									'Setting up your store in the wrong country may lead to the following issues: ',
									'woocommerce'
								) }
							</p>
							<ul className="woocommerce-profiler-geolocation-notice__list">
								<li>
									{ __(
										'Tax and duty obligations',
										'woocommerce'
									) }
								</li>
								<li>
									{ __( 'Payment issues', 'woocommerce' ) }
								</li>
								<li>
									{ __( 'Shipping issues', 'woocommerce' ) }
								</li>
							</ul>
						</Notice>
					) }
				</form>
				<div className="woocommerce-profiler-button-container">
					<Button
						className="woocommerce-profiler-button"
						variant="primary"
						disabled={ ! storeCountry.key }
						onClick={ () => {
							sendEvent( {
								type: 'BUSINESS_INFO_COMPLETED',
								payload: {
									storeName,
									industry: industry?.key,
									storeLocation: storeCountry.key,
									geolocationOverruled:
										geolocationOverruled || false,
								},
							} );
							setHasSubmitted( true );
						} }
					>
						{ hasSubmitted ? (
							<Spinner />
						) : (
							__( 'Continue', 'woocommerce' )
						) }
					</Button>
				</div>
			</div>
		</div>
	);
};
