/**
 * Default settings overrides form: default weight, tariff code, country of manufacture.
 * Owns state, validation (Zod), and errors. Notifies page via onChange 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 { DefaultSettingsOverrides } from '../../types/settings';
import type { SettingsFieldSelectOption } from './settings-field';
import { defaultSettingsOverridesSchema } from './utils/schemas';
import { getSectionFieldErrors } from './utils/getSettingsFieldErrors';
import { formatDisplayNumber, getWeightBounds } from '../../shared/utils';

export const SETTINGS_OVERRIDES_FORM_ID = 'settings-overrides' as const;

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

function DefaultSettingsOverridesFormInner({
	defaultValue,
	weightUnit = 'kg',
	onChange,
	onInteraction,
	resetTrigger = 0,
	submitErrors,
	countryOptions,
}: DefaultSettingsOverridesFormProps) {
	const [value, setValue] = useState<DefaultSettingsOverrides>(() => ({
		...defaultValue,
	}));
	const [errors, setErrors] = useState<Record<string, string>>({});
	const hasInteracted = useRef(false);
	const weightBounds = getWeightBounds(weightUnit);

	useEffect(() => {
		setValue({ ...defaultValue });
		setErrors({});
		hasInteracted.current = false;
	}, [defaultValue, resetTrigger]);

	useEffect(() => {
		const result = defaultSettingsOverridesSchema.safeParse(value);
		const nextErrors: Record<string, string> = result.success
			? {}
			: getSectionFieldErrors(result.error);

		if (value.defaultWeightKg > 0 && value.defaultWeightKg < weightBounds.min) {
			nextErrors.defaultWeightKg = __(
				`Default weight must be at least ${formatDisplayNumber(weightBounds.min)} ${weightUnit} (0.01kg equivalent).`,
				'parcel2go-shipping'
			);
		}

		if (result.success) {
			setErrors(nextErrors);
		} else {
			setErrors(nextErrors);
		}
	}, [value, weightBounds.min, weightUnit]);

	const displayErrors = submitErrors ?? errors;

	const handleChange = useCallback(
		(field: keyof DefaultSettingsOverrides, v: string | number) => {
			if (!hasInteracted.current) {
				hasInteracted.current = true;
				onInteraction?.();
			}
			const next: DefaultSettingsOverrides = { ...value };
			if (field === 'defaultWeightKg') {
				next.defaultWeightKg = typeof v === 'number' ? v : parseFloat(String(v)) || 0;
			} else if (field === 'defaultTariffCode') {
				next.defaultTariffCode = String(v);
			} else {
				next.defaultCountryOfManufacture = String(v);
			}
			setValue(next);
			onChange(SETTINGS_OVERRIDES_FORM_ID, next);
		},
		[value, onChange, onInteraction]
	);

	return (
		<Flex direction="column" gap={3}>
			<SettingsField
				kind="text"
				label={`${__('Default Weight', 'parcel2go-shipping')} (${weightUnit})`}
				value={String(value.defaultWeightKg)}
				onChange={(v) =>
					handleChange('defaultWeightKg', parseFloat(v || '0') || 0)
				}
				type="number"
				min={weightBounds.min}
				step={weightBounds.step}
				error={displayErrors.defaultWeightKg}
				description={__(
					'The default weight to apply when a product has no weight set.',
					'parcel2go-shipping'
				)}
			/>
			<SettingsField
				kind="text"
				label={__('Default Tariff Code', 'parcel2go-shipping')}
				value={value.defaultTariffCode}
				onChange={(v) => handleChange('defaultTariffCode', v)}
				error={displayErrors.defaultTariffCode}
				description={__(
					'The default tariff code to apply to your products that do not have a tariff code set. 10 characters max.',
					'parcel2go-shipping'
				)}
			/>
			<SettingsField
				kind="select"
				label={__('Default Country of Manufacture', 'parcel2go-shipping')}
				value={value.defaultCountryOfManufacture}
				onChange={(v) => handleChange('defaultCountryOfManufacture', v)}
				options={countryOptions}
				error={displayErrors.defaultCountryOfManufacture}
				description={__(
					'The default country of manufacture to apply to your products that do not have a country of manufacture set.',
					'parcel2go-shipping'
				)}
			/>
		</Flex>
	);
}

export const DefaultSettingsOverridesForm = memo(
	DefaultSettingsOverridesFormInner
);
