/**
 * Default shipping form: owns state, validation (Zod), and errors.
 * Notifies page via onChange(formId, value) and onInteraction().
 */
import { __ } from '@wordpress/i18n';
import {
	memo,
	useState,
	useEffect,
	useCallback,
	useRef,
} from '@wordpress/element';
import { Flex } from '@wordpress/components';
import { SettingsField } from './settings-field';
import type { DefaultShippingSettings } from '../../types/settings';
import type { SettingsFieldSelectOption } from './settings-field';
import { defaultShippingSchema } from './utils/schemas';
import { getSectionFieldErrors } from './utils/getSettingsFieldErrors';

export const SHIPPING_FORM_ID = 'shipping' as const;

export interface DefaultShippingFormProps {
	defaultValue: DefaultShippingSettings;
	onChange: (formId: string, value: DefaultShippingSettings) => void;
	onInteraction?: () => void;
	resetTrigger?: number;
	submitErrors?: Record<string, string>;
	countryOptions: SettingsFieldSelectOption[];
	countriesLoading?: boolean;
}

function DefaultShippingFormInner({
	defaultValue,
	onChange,
	onInteraction,
	resetTrigger = 0,
	submitErrors,
	countryOptions,
	countriesLoading = false,
}: DefaultShippingFormProps) {
	const [value, setValue] = useState<DefaultShippingSettings>(() => ({
		...defaultValue,
	}));
	const [errors, setErrors] = useState<Record<string, string>>({});
	const hasInteracted = useRef(false);

	// Reset to default when page triggers discard or default changes.
	useEffect(() => {
		setValue({ ...defaultValue });
		setErrors({});
		hasInteracted.current = false;
	}, [resetTrigger, defaultValue]);

	const displayErrors = submitErrors ?? errors;

	const handleChange = useCallback(
		(field: keyof DefaultShippingSettings, v: string) => {
			if (!hasInteracted.current) {
				hasInteracted.current = true;
				onInteraction?.();
			}
			const next = { ...value, [field]: v };

			const result = defaultShippingSchema.safeParse(next);

			// All setState calls together, outside any updater
			setValue(next);
			setErrors(
				result.success ? {} : getSectionFieldErrors(result.error)
			);
			onChange(SHIPPING_FORM_ID, next);
		},
		[value, onChange, onInteraction]
	);

	return (
		<Flex direction="column" gap={3}>
			<SettingsField
				kind="text"
				label={__('Name', 'parcel2go-shipping')}
				value={value.contactName}
				onChange={(v) => handleChange('contactName', v)}
				error={displayErrors.contactName}
				required
			/>
			<SettingsField
				kind="text"
				label={__('Company name', 'parcel2go-shipping')}
				value={value.organisation}
				onChange={(v) => handleChange('organisation', v)}
				error={displayErrors.organisation}
			/>
			<SettingsField
				kind="text"
				label={__('Property (House number)', 'parcel2go-shipping')}
				value={value.property}
				onChange={(v) => handleChange('property', v)}
				error={displayErrors.property}
				required
			/>
			<SettingsField
				kind="text"
				label={__('Street', 'parcel2go-shipping')}
				value={value.street}
				onChange={(v) => handleChange('street', v)}
				error={displayErrors.street}
				required
			/>
			<SettingsField
				kind="text"
				label={__('Town / City', 'parcel2go-shipping')}
				value={value.town}
				onChange={(v) => handleChange('town', v)}
				error={displayErrors.town}
				required
			/>
			<SettingsField
				kind="text"
				label={__('Postcode', 'parcel2go-shipping')}
				value={value.postcode}
				onChange={(v) => handleChange('postcode', v)}
				error={displayErrors.postcode}
				required
			/>
			<SettingsField
				kind="text"
				label={__('County', 'parcel2go-shipping')}
				value={value.county}
				onChange={(v) => handleChange('county', v)}
				error={displayErrors.county}
			/>
			<SettingsField
				kind="select"
				label={__('Country', 'parcel2go-shipping')}
				value={value.country}
				onChange={(v) => handleChange('country', v)}
				options={countryOptions}
				error={displayErrors.country}
				disabled={countriesLoading}
				required
			/>
			<SettingsField
				kind="text"
				label={__('Email', 'parcel2go-shipping')}
				value={value.email}
				onChange={(v) => handleChange('email', v)}
				type="email"
				error={displayErrors.email}
				required
			/>
			<SettingsField
				kind="text"
				label={__('Phone', 'parcel2go-shipping')}
				value={value.phone}
				onChange={(v) => handleChange('phone', v)}
				error={displayErrors.phone}
				required
			/>
		</Flex>
	);
}

export const DefaultShippingForm = memo(DefaultShippingFormInner);
