import React, { useEffect, useRef } from 'react';
import { __, sprintf } from '@wordpress/i18n';
import { Checkbox, Field, Icon, Input, Select, Textarea } from '../../../shared/ui';
import { currentUser, front, loginUrl } from '../config';
import { fieldOptions } from '../fields';

const AUTOCOMPLETE = {
	'customer.first_name': 'given-name',
	'customer.last_name': 'family-name',
	'customer.email': 'email',
	'customer.phone': 'tel',
};

function controlId(key) {
	return `bp-bw-f-${key.replace(/[^a-z0-9_-]/gi, '-')}`;
}

function FieldControl({ item, value, error, onChange }) {
	const { key, def, required } = item;
	const id = controlId(key);
	const label = def.label || def.field_key;

	if (def.type === 'checkbox') {
		return (
			<div className={['bp-field', error ? 'is-invalid' : ''].filter(Boolean).join(' ')}>
				<Checkbox
					id={id}
					label={
						<>
							{label}
							{required ? (
								<span className="bp-label__req" aria-hidden="true">
									*
								</span>
							) : null}
						</>
					}
					checked={!!value}
					aria-invalid={error ? 'true' : undefined}
					aria-required={required ? 'true' : undefined}
					aria-describedby={error ? `${id}-error` : undefined}
					onChange={(e) => onChange(e.target.checked)}
				/>
				{error ? (
					<div id={`${id}-error`} className="bp-error-text" role="alert">
						<Icon name="alert-circle" size={14} />
						<span>{error}</span>
					</div>
				) : null}
			</div>
		);
	}

	let control;
	if (def.type === 'textarea') {
		control = <Textarea rows={3} placeholder={def.placeholder || ''} value={value ?? ''} onChange={(e) => onChange(e.target.value)} />;
	} else if (def.type === 'select') {
		control = (
			<Select
				value={value ?? ''}
				placeholder={__('Select…', 'pointly-booking')}
				options={fieldOptions(def)}
				onChange={(e) => onChange(e.target.value)}
			/>
		);
	} else {
		const type = ['email', 'tel', 'number', 'date'].includes(def.type) ? def.type : 'text';
		control = (
			<Input
				type={type}
				inputMode={type === 'number' ? 'decimal' : undefined}
				autoComplete={AUTOCOMPLETE[key] || undefined}
				placeholder={def.placeholder || ''}
				value={value ?? ''}
				onChange={(e) => onChange(e.target.value)}
			/>
		);
	}

	return (
		<Field id={id} label={label} required={required} error={error}>
			{control}
		</Field>
	);
}

export default function DetailsStep({ flow }) {
	const user = currentUser();
	const login = loginUrl();
	const terms = front().design?.terms || null;
	const wrapRef = useRef(null);

	// After a failed "Continue", move focus to the first field with an error.
	const errorKeys = Object.keys(flow.fieldErrors);
	useEffect(() => {
		if (!errorKeys.length || !wrapRef.current) return;
		const first = wrapRef.current.querySelector('[aria-invalid="true"]');
		if (first) first.focus();
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [errorKeys.join('|')]);

	const groupTitle = {
		customer: __('Contact details', 'pointly-booking'),
		booking: __('About your booking', 'pointly-booking'),
		form: __('Additional information', 'pointly-booking'),
	};

	return (
		<div className="bp-bw-details" ref={wrapRef}>
			{user ? (
				<div className="bp-bw-account">
					<Icon name="user-check" />
					<span>
						{
							/* translators: %s: the visitor's display name. */
							sprintf(__('Signed in as %s', 'pointly-booking'), user.displayName || user.email)
						}
					</span>
				</div>
			) : login ? (
				<div className="bp-bw-account">
					<Icon name="user" />
					<span>
						{__('Booking as a guest.', 'pointly-booking')}{' '}
						<a className="bp-link-tap" href={login}>{__('Have an account? Log in', 'pointly-booking')}</a>
					</span>
				</div>
			) : null}

			{flow.fieldGroups.map((g) => (
				<fieldset className="bp-bw-fieldset" key={g.scope}>
					<legend className="bp-bw-subhead">{groupTitle[g.scope]}</legend>
					<div className="bp-bw-fields">
						{g.items.map((item) => (
							<div key={item.key} className={item.width === 'half' ? 'bp-bw-field--half' : 'bp-bw-field--full'}>
								<FieldControl
									item={item}
									value={flow.answers[item.key]}
									error={flow.fieldErrors[item.key]}
									onChange={(v) => flow.actions.setAnswer(item.key, v)}
								/>
							</div>
						))}
					</div>
				</fieldset>
			))}

			{terms && terms.enabled ? (
				<div className="bp-bw-terms">
					<FieldControl
						item={{
							key: 'form.__terms',
							def: {
								type: 'checkbox',
								label: (
									<>
										{String(terms.text || '').trim() || __('I agree to the terms and conditions', 'pointly-booking')}
										{terms.url ? (
											<>
												{' '}
												<a href={terms.url} target="_blank" rel="noopener noreferrer">
													{__('(read)', 'pointly-booking')}
												</a>
											</>
										) : null}
									</>
								),
							},
							required: true,
						}}
						value={flow.answers['form.__terms']}
						error={flow.fieldErrors['form.__terms']}
						onChange={(v) => flow.actions.setAnswer('form.__terms', v)}
					/>
				</div>
			) : null}
		</div>
	);
}
