/**
 * The mapping editor.
 *
 * The type hint beside every mapping row is the point of this screen: when
 * a value does not match the Brevo attribute's declared type, Brevo accepts
 * the request and silently drops the value. Surfacing the mismatch here is
 * what stops "success, but the field is empty".
 */
import { useCallback, useEffect, useMemo, useState } from '@wordpress/element';
import Dialog from '../../components/Dialog';
import { __, sprintf } from '@wordpress/i18n';
import { useNavigate, useParams } from 'react-router-dom';

import {
	BlockStack,
	InlineStack,
	Note,
	SelectBox,
	SkeletonLoader,
} from '../../ui/molecules';
import { Button, Checkbox, Icon, Input, Switcher, Text } from '../../ui/atoms';
import Section from '../../components/Section';
import { createAttribute } from '../../api/brevo';
import { createFeed, fetchFeed, updateFeed } from '../../api/feeds';
import { fetchFields, fetchForms } from '../../api/forms';
import { useApp } from '../../store/AppStore';
import { compatibility } from './typeHints';

const EMPTY_CONFIG = {
	lists: [],
	mappings: [],
	email_field: '',
	update_existing: true,
	consent_field: '',
	no_consent_ack: false,
};

const HINT_COLOR = {
	ok: 'success',
	warn: 'warning',
	risky: 'error',
	muted: 'gray-500',
};

export default function FeedEditor() {
	const { id } = useParams();
	const navigate = useNavigate();
	const { brevo, brevoState, loadBrevo, addToast, bootstrap } = useApp();

	const isNew = ! id;

	const [ loading, setLoading ] = useState( true );
	const [ error, setError ] = useState( '' );
	const [ dirty, setDirty ] = useState( false );
	const [ saving, setSaving ] = useState( false );
	const [ saveHint, setSaveHint ] = useState( '' );
	const [ confirmLeave, setConfirmLeave ] = useState( false );

	const [ feed, setFeed ] = useState( {
		title: '',
		adapter: bootstrap.adapters?.[ 0 ]?.slug || '',
		form_id: '',
		status: 'active',
		config: EMPTY_CONFIG,
	} );

	const [ forms, setForms ] = useState( [] );
	const [ fields, setFields ] = useState( [] );

	// A consent field has to be a checkbox. Plenty of contact forms have none,
	// in which case the picker is empty and the acknowledgement is the only
	// way forward — worth saying out loud rather than leaving a blank select.
	const hasConsentCandidates = fields.some(
		( field ) => field.type === 'checkbox'
	);
	const [ formsLoading, setFormsLoading ] = useState( false );

	const [ newAttrLabel, setNewAttrLabel ] = useState( '' );
	const [ newAttrType, setNewAttrType ] = useState( 'text' );
	const [ creatingAttr, setCreatingAttr ] = useState( false );

	const patch = useCallback( ( changes ) => {
		setFeed( ( current ) => ( { ...current, ...changes } ) );
		setDirty( true );
	}, [] );

	const patchConfig = useCallback( ( changes ) => {
		setFeed( ( current ) => ( {
			...current,
			config: { ...current.config, ...changes },
		} ) );
		setDirty( true );
	}, [] );

	useEffect( () => {
		let cancelled = false;

		const boot = async () => {
			setLoading( true );

			try {
				loadBrevo();

				if ( ! isNew ) {
					const existing = await fetchFeed( id );

					if ( cancelled ) {
						return;
					}

					setFeed( {
						title: existing.title,
						adapter: existing.adapter,
						form_id: existing.form_id,
						status: existing.status,
						config: { ...EMPTY_CONFIG, ...existing.config },
					} );
				}

				if ( ! cancelled ) {
					setDirty( false );
				}
			} catch ( requestError ) {
				if ( ! cancelled ) {
					setError( requestError.message );
				}
			} finally {
				if ( ! cancelled ) {
					setLoading( false );
				}
			}
		};

		boot();

		return () => {
			cancelled = true;
		};
	}, [ id, isNew, loadBrevo ] );

	useEffect( () => {
		if ( ! feed.adapter ) {
			return undefined;
		}

		let cancelled = false;
		setFormsLoading( true );

		fetchForms( feed.adapter )
			.then(
				( response ) => ! cancelled && setForms( response.forms || [] )
			)
			.catch( ( requestError ) => {
				if ( ! cancelled ) {
					addToast( requestError.message, 'error' );
					setForms( [] );
				}
			} )
			.finally( () => ! cancelled && setFormsLoading( false ) );

		return () => {
			cancelled = true;
		};
	}, [ feed.adapter, addToast ] );

	useEffect( () => {
		if ( ! feed.adapter || ! feed.form_id ) {
			setFields( [] );
			return undefined;
		}

		let cancelled = false;

		fetchFields( feed.adapter, feed.form_id )
			.then(
				( response ) =>
					! cancelled && setFields( response.fields || [] )
			)
			.catch( ( requestError ) => {
				if ( ! cancelled ) {
					addToast( requestError.message, 'error' );
					setFields( [] );
				}
			} );

		return () => {
			cancelled = true;
		};
	}, [ feed.adapter, feed.form_id, addToast ] );

	const attributeByName = useMemo( () => {
		const map = {};

		brevo.attributes.forEach( ( attribute ) => {
			map[ attribute.name ] = attribute;
		} );

		return map;
	}, [ brevo.attributes ] );

	const fieldByKey = useMemo( () => {
		const map = {};

		fields.forEach( ( field ) => {
			map[ field.key ] = field;
		} );

		return map;
	}, [ fields ] );

	const mappedKeys = useMemo(
		() =>
			new Set(
				[ feed.config.email_field, feed.config.consent_field ]
					.concat(
						feed.config.mappings.map( ( row ) => row.field_key )
					)
					.filter( Boolean )
			),
		[ feed.config ]
	);

	const unmapped = fields.filter(
		( field ) => ! mappedKeys.has( field.key )
	);

	const addMappingRow = () =>
		patchConfig( {
			mappings: [
				...feed.config.mappings,
				{
					field_key: '',
					attribute: '',
					brevo_type: 'text',
					required: false,
					date_format: '',
				},
			],
		} );

	const updateMappingRow = ( index, changes ) =>
		patchConfig( {
			mappings: feed.config.mappings.map( ( row, position ) =>
				position === index ? { ...row, ...changes } : row
			),
		} );

	const removeMappingRow = ( index ) =>
		patchConfig( {
			mappings: feed.config.mappings.filter(
				( _, position ) => position !== index
			),
		} );

	const onCreateAttribute = async () => {
		if ( ! newAttrLabel.trim() ) {
			return;
		}

		setCreatingAttr( true );

		try {
			const result = await createAttribute(
				newAttrLabel.trim(),
				newAttrType
			);

			addToast(
				sprintf(
					/* translators: %s: the new Brevo attribute name. */
					__(
						'Created attribute %s in Brevo.',
						'rewind-form-bridge-for-brevo'
					),
					result.name
				)
			);

			setNewAttrLabel( '' );
			await loadBrevo();
		} catch ( requestError ) {
			addToast( requestError.message, 'error' );
		} finally {
			setCreatingAttr( false );
		}
	};

	// The three rules the REST controller enforces, checked here first so the
	// answer names the field instead of arriving as a generic 400 toast.
	const blocker = () => {
		if ( ! feed.form_id ) {
			return __(
				'Pick the form this mapping listens to.',
				'rewind-form-bridge-for-brevo'
			);
		}

		if ( feed.config.lists.length === 0 ) {
			return __(
				'Step 2: pick at least one Brevo list to subscribe contacts to.',
				'rewind-form-bridge-for-brevo'
			);
		}

		if ( ! feed.config.email_field ) {
			return __(
				'Step 3: pick the form field that supplies the email address.',
				'rewind-form-bridge-for-brevo'
			);
		}

		if ( ! feed.config.consent_field && ! feed.config.no_consent_ack ) {
			return hasConsentCandidates
				? __(
						'Step 4: pick the consent checkbox, or tick "This form does not need a consent field".',
						'rewind-form-bridge-for-brevo'
				  )
				: __(
						'Step 4: this form has no checkbox field to use for consent, so tick "This form does not need a consent field" to confirm that is deliberate.',
						'rewind-form-bridge-for-brevo'
				  );
		}

		return '';
	};

	const onSave = async () => {
		const blocked = blocker();

		if ( blocked ) {
			addToast( blocked, 'error' );
			setSaveHint( blocked );
			return;
		}

		setSaveHint( '' );
		setSaving( true );

		try {
			const payload = {
				title: feed.title,
				adapter: feed.adapter,
				form_id: feed.form_id,
				status: feed.status,
				config: feed.config,
			};

			const saved = isNew
				? await createFeed( payload )
				: await updateFeed( id, payload );

			setDirty( false );
			addToast( __( 'Mapping saved.', 'rewind-form-bridge-for-brevo' ) );

			if ( isNew ) {
				navigate( `/mappings/${ saved.id }`, { replace: true } );
			}
		} catch ( requestError ) {
			addToast( requestError.message, 'error' );
		} finally {
			setSaving( false );
		}
	};

	const leave = () => navigate( '/mappings' );

	const onCancel = () => ( dirty ? setConfirmLeave( true ) : leave() );

	if ( loading ) {
		return (
			<div className="rbfb-page rbfb-page--wide">
				<BlockStack gap={ 16 } style={ { width: '100%' } }>
					{ [ 0, 1, 2 ].map( ( row ) => (
						<SkeletonLoader
							key={ row }
							width="100%"
							height="120px"
						/>
					) ) }
				</BlockStack>
			</div>
		);
	}

	if ( error ) {
		return (
			<div className="rbfb-page rbfb-page--wide">
				<Note type="error">
					<Note.Normal>{ error }</Note.Normal>
				</Note>
			</div>
		);
	}

	const ready = brevoState !== 'loading';
	const noBrevoData = ready && ! brevo.cached;
	// Cached successfully, but the Brevo account itself has no contact lists.
	// Without this the Target lists box just says "No results found", which
	// reads like a plugin fault rather than an empty Brevo account.
	const noBrevoLists = ready && brevo.cached && brevo.lists.length === 0;

	return (
		<div className="rbfb-page rbfb-page--wide rbfb-feed-editor">
			<BlockStack gap={ 20 }>
				{ noBrevoData && (
					<Note type="warning">
						<Note.Normal>
							{ __(
								'Your Brevo lists and attributes are not cached yet, so there is nothing to map to. Load them from the Connections screen first.',
								'rewind-form-bridge-for-brevo'
							) }
						</Note.Normal>
					</Note>
				) }

				{ noBrevoLists && (
					<Note type="warning">
						<Note.Normal>
							{ __(
								'Your Brevo account has no contact lists yet, so there is nothing to subscribe contacts to. Create a list in Brevo under Contacts → Lists, then use Refresh from Brevo on the Connections screen.',
								'rewind-form-bridge-for-brevo'
							) }
						</Note.Normal>
					</Note>
				) }

				<Section
					icon="dynamic_form"
					title={ __(
						'1. Source form',
						'rewind-form-bridge-for-brevo'
					) }
				>
					<BlockStack
						gap={ 16 }
						style={ { width: '100%', maxWidth: 520 } }
					>
						<Input
							label={ __(
								'Mapping title',
								'rewind-form-bridge-for-brevo'
							) }
							value={ feed.title }
							onChange={ ( value ) => patch( { title: value } ) }
							placeholder={ __(
								'Newsletter sign-ups',
								'rewind-form-bridge-for-brevo'
							) }
						/>

						<SelectBox
							label={ __(
								'Form plugin',
								'rewind-form-bridge-for-brevo'
							) }
							value={ feed.adapter ? [ feed.adapter ] : [] }
							options={ ( bootstrap.adapters || [] ).map(
								( adapter ) => ( {
									value: adapter.slug,
									name: adapter.label,
								} )
							) }
							onChange={ ( values ) =>
								patch( {
									adapter: values[ 0 ] || '',
									form_id: '',
								} )
							}
						/>

						<SelectBox
							label={ __(
								'Form',
								'rewind-form-bridge-for-brevo'
							) }
							searchable
							loading={ formsLoading }
							disabled={ formsLoading || forms.length === 0 }
							placeholder={ __(
								'Pick a form…',
								'rewind-form-bridge-for-brevo'
							) }
							value={ feed.form_id ? [ feed.form_id ] : [] }
							options={ forms.map( ( form ) => ( {
								value: form.id,
								name: form.title,
							} ) ) }
							onChange={ ( values ) =>
								patch( { form_id: values[ 0 ] || '' } )
							}
						/>
					</BlockStack>
				</Section>

				<Section
					icon="groups"
					title={ __(
						'2. Brevo lists',
						'rewind-form-bridge-for-brevo'
					) }
				>
					<BlockStack
						gap={ 10 }
						style={ { width: '100%', maxWidth: 520 } }
					>
						<Text size="xs" color="gray-500">
							{ __(
								'Every contact this mapping creates is subscribed to the lists you pick.',
								'rewind-form-bridge-for-brevo'
							) }
						</Text>

						<SelectBox
							multiple
							searchable
							label={ __(
								'Target lists',
								'rewind-form-bridge-for-brevo'
							) }
							placeholder={ __(
								'Pick one or more lists…',
								'rewind-form-bridge-for-brevo'
							) }
							value={ feed.config.lists.map( String ) }
							options={ brevo.lists.map( ( list ) => ( {
								value: String( list.id ),
								name: list.name,
							} ) ) }
							onChange={ ( values ) =>
								patchConfig( { lists: values.map( Number ) } )
							}
						/>

						{ noBrevoLists && (
							<Text size="xs" color="warning">
								{ __(
									'No lists were found on your Brevo account. Create one in Brevo, then refresh from the Connections screen.',
									'rewind-form-bridge-for-brevo'
								) }
							</Text>
						) }
					</BlockStack>
				</Section>

				<Section
					icon="swap_horiz"
					title={ __(
						'3. Field mapping',
						'rewind-form-bridge-for-brevo'
					) }
				>
					<BlockStack gap={ 16 } style={ { width: '100%' } }>
						<div style={ { maxWidth: 520 } }>
							<SelectBox
								label={ __(
									'Email field (required)',
									'rewind-form-bridge-for-brevo'
								) }
								placeholder={ __(
									'Pick a field…',
									'rewind-form-bridge-for-brevo'
								) }
								disabled={ fields.length === 0 }
								value={
									feed.config.email_field
										? [ feed.config.email_field ]
										: []
								}
								options={ fields.map( ( field ) => ( {
									value: field.key,
									name: `${ field.label } (${ field.type })`,
								} ) ) }
								onChange={ ( values ) =>
									patchConfig( {
										email_field: values[ 0 ] || '',
									} )
								}
							/>
						</div>

						{ feed.config.mappings.length === 0 && (
							<Text size="xs" color="gray-500">
								{ __(
									'No fields mapped yet. The email address alone will be sent.',
									'rewind-form-bridge-for-brevo'
								) }
							</Text>
						) }

						{ feed.config.mappings.length > 0 && (
							<table className="rbfb-table rbfb-mapping-table">
								<thead>
									<tr>
										<th>
											{ __(
												'Form field',
												'rewind-form-bridge-for-brevo'
											) }
										</th>
										<th>
											{ __(
												'Brevo attribute',
												'rewind-form-bridge-for-brevo'
											) }
										</th>
										<th>
											{ __(
												'Type check',
												'rewind-form-bridge-for-brevo'
											) }
										</th>
										<th>
											{ __(
												'Required',
												'rewind-form-bridge-for-brevo'
											) }
										</th>
										<th />
									</tr>
								</thead>
								<tbody>
									{ feed.config.mappings.map(
										( row, index ) => {
											const field =
												fieldByKey[ row.field_key ];
											const attribute =
												attributeByName[
													row.attribute
												];
											const hint = compatibility(
												field?.type,
												attribute?.type
											);

											return (
												<tr key={ index }>
													<td
														style={ {
															minWidth: 200,
														} }
													>
														<SelectBox
															placeholder={ __(
																'Pick a field…',
																'rewind-form-bridge-for-brevo'
															) }
															disabled={
																fields.length ===
																0
															}
															value={
																row.field_key
																	? [
																			row.field_key,
																	  ]
																	: []
															}
															options={ fields.map(
																( item ) => ( {
																	value: item.key,
																	name: item.label,
																} )
															) }
															onChange={ (
																values
															) =>
																updateMappingRow(
																	index,
																	{
																		field_key:
																			values[ 0 ] ||
																			'',
																	}
																)
															}
														/>
													</td>

													<td
														style={ {
															minWidth: 200,
														} }
													>
														<SelectBox
															searchable
															placeholder={ __(
																'Pick an attribute…',
																'rewind-form-bridge-for-brevo'
															) }
															value={
																row.attribute
																	? [
																			row.attribute,
																	  ]
																	: []
															}
															options={ brevo.attributes.map(
																( item ) => ( {
																	value: item.name,
																	name: `${ item.name } (${ item.type })`,
																} )
															) }
															onChange={ (
																values
															) =>
																updateMappingRow(
																	index,
																	{
																		attribute:
																			values[ 0 ] ||
																			'',
																		brevo_type:
																			attributeByName[
																				values[ 0 ]
																			]
																				?.type ||
																			'text',
																	}
																)
															}
														/>
													</td>

													<td>
														<Text
															size="xs"
															color={
																HINT_COLOR[
																	hint.level
																]
															}
														>
															{ hint.message }
														</Text>
													</td>

													<td>
														<Checkbox
															checked={ Boolean(
																row.required
															) }
															ariaLabel={ __(
																'Required',
																'rewind-form-bridge-for-brevo'
															) }
															onChange={ (
																checked
															) =>
																updateMappingRow(
																	index,
																	{
																		required:
																			checked,
																	}
																)
															}
														/>
													</td>

													<td>
														<Button
															variant="error"
															size="small"
															startIcon="delete"
															ariaLabel={ sprintf(
																/* translators: %d: row number. */
																__(
																	'Remove mapping row %d',
																	'rewind-form-bridge-for-brevo'
																),
																index + 1
															) }
															onClick={ () =>
																removeMappingRow(
																	index
																)
															}
														/>
													</td>
												</tr>
											);
										}
									) }
								</tbody>
							</table>
						) }

						<InlineStack gap={ 8 }>
							<Button
								variant="outlined"
								size="small"
								startIcon="add"
								disabled={ fields.length === 0 }
								onClick={ addMappingRow }
							>
								{ __(
									'Add field',
									'rewind-form-bridge-for-brevo'
								) }
							</Button>
						</InlineStack>

						{ unmapped.length > 0 && feed.form_id && (
							<Note type="info">
								<Note.Normal>
									<Note.Title
										title={ sprintf(
											/* translators: %d: number of unmapped fields. */
											__(
												'%d form field(s) are not mapped',
												'rewind-form-bridge-for-brevo'
											),
											unmapped.length
										) }
									/>
									{ unmapped
										.slice( 0, 6 )
										.map( ( field ) => field.label )
										.join( ', ' ) }
									{ unmapped.length > 6 ? '…' : '' }
								</Note.Normal>
							</Note>
						) }

						<InlineStack gap={ 10 } blockAlign="end" wrap>
							<div style={ { minWidth: 220 } }>
								<Input
									label={ __(
										'New Brevo attribute',
										'rewind-form-bridge-for-brevo'
									) }
									value={ newAttrLabel }
									onChange={ setNewAttrLabel }
									placeholder={ __(
										'Company size',
										'rewind-form-bridge-for-brevo'
									) }
								/>
							</div>

							<div style={ { minWidth: 160 } }>
								<SelectBox
									label={ __(
										'Type',
										'rewind-form-bridge-for-brevo'
									) }
									value={ [ newAttrType ] }
									options={ [
										{
											value: 'text',
											name: __(
												'Text',
												'rewind-form-bridge-for-brevo'
											),
										},
										{
											value: 'float',
											name: __(
												'Number',
												'rewind-form-bridge-for-brevo'
											),
										},
										{
											value: 'date',
											name: __(
												'Date',
												'rewind-form-bridge-for-brevo'
											),
										},
										{
											value: 'boolean',
											name: __(
												'Yes / no',
												'rewind-form-bridge-for-brevo'
											),
										},
									] }
									onChange={ ( values ) =>
										setNewAttrType( values[ 0 ] || 'text' )
									}
								/>
							</div>

							<Button
								startIcon="add_circle"
								variant="outlined"
								size="small"
								loading={ creatingAttr }
								disabled={
									creatingAttr || ! newAttrLabel.trim()
								}
								onClick={ onCreateAttribute }
							>
								{ __(
									'Create in Brevo',
									'rewind-form-bridge-for-brevo'
								) }
							</Button>
						</InlineStack>
					</BlockStack>
				</Section>

				<Section
					icon="tune"
					title={ __(
						'4. Behaviour',
						'rewind-form-bridge-for-brevo'
					) }
				>
					<BlockStack
						gap={ 16 }
						style={ { width: '100%', maxWidth: 520 } }
					>
						<BlockStack gap={ 6 }>
							<Switcher
								checked={ Boolean(
									feed.config.update_existing
								) }
								title={ __(
									'Update existing contacts',
									'rewind-form-bridge-for-brevo'
								) }
								onChange={ ( checked ) =>
									patchConfig( { update_existing: checked } )
								}
							/>
							<Text size="xs" color="gray-500">
								{ __(
									'When off, a repeat submitter keeps their existing Brevo data and the submission is logged as skipped.',
									'rewind-form-bridge-for-brevo'
								) }
							</Text>
						</BlockStack>

						<SelectBox
							label={ __(
								'Consent checkbox',
								'rewind-form-bridge-for-brevo'
							) }
							placeholder={ __(
								'— no consent field —',
								'rewind-form-bridge-for-brevo'
							) }
							disabled={ fields.length === 0 }
							value={
								feed.config.consent_field
									? [ feed.config.consent_field ]
									: []
							}
							options={ fields
								.filter(
									( field ) => field.type === 'checkbox'
								)
								.map( ( field ) => ( {
									value: field.key,
									name: field.label,
								} ) ) }
							onChange={ ( values ) =>
								patchConfig( {
									consent_field: values[ 0 ] || '',
									no_consent_ack: values[ 0 ]
										? false
										: feed.config.no_consent_ack,
								} )
							}
						/>

						{ ! hasConsentCandidates && fields.length > 0 && (
							<Text size="xs" color="warning">
								{ __(
									'This form has no checkbox field, so there is nothing to map as consent. Tick the box below to save anyway.',
									'rewind-form-bridge-for-brevo'
								) }
							</Text>
						) }

						{ ! feed.config.consent_field && (
							<BlockStack gap={ 10 }>
								<Checkbox
									checked={ Boolean(
										feed.config.no_consent_ack
									) }
									title={ __(
										'This form does not need a consent field',
										'rewind-form-bridge-for-brevo'
									) }
									onChange={ ( checked ) =>
										patchConfig( {
											no_consent_ack: checked,
										} )
									}
								/>

								{ feed.config.no_consent_ack && (
									<Note type="error">
										<Note.Normal>
											{ __(
												'Without a consent checkbox you are subscribing people who may not have agreed to marketing. That can violate the GDPR and similar laws, and the resulting spam complaints will damage your Brevo sender reputation. Only continue if consent is collected some other way.',
												'rewind-form-bridge-for-brevo'
											) }
										</Note.Normal>
									</Note>
								) }
							</BlockStack>
						) }

						<Switcher
							checked={ feed.status === 'active' }
							title={ __(
								'Mapping is active',
								'rewind-form-bridge-for-brevo'
							) }
							onChange={ ( checked ) =>
								patch( {
									status: checked ? 'active' : 'paused',
								} )
							}
						/>
					</BlockStack>
				</Section>

				<InlineStack
					gap={ 10 }
					align="between"
					blockAlign="center"
					className="rbfb-editor-actions"
				>
					<InlineStack gap={ 6 } blockAlign="center">
						<Icon
							name={
								dirty ? 'running_with_errors' : 'check_circle'
							}
							color={ dirty ? 'warning' : 'success' }
							fontSize="lg"
						/>
						<Text size="xs" color="gray-500">
							{ dirty
								? __(
										'Unsaved changes',
										'rewind-form-bridge-for-brevo'
								  )
								: __(
										'All changes saved',
										'rewind-form-bridge-for-brevo'
								  ) }
						</Text>
					</InlineStack>

					<InlineStack gap={ 8 }>
						<Button
							startIcon="close"
							variant="outlined"
							size="small"
							disabled={ saving }
							onClick={ onCancel }
						>
							{ __( 'Cancel', 'rewind-form-bridge-for-brevo' ) }
						</Button>
						<Button
							startIcon="save"
							variant="primary"
							size="small"
							loading={ saving }
							disabled={ saving }
							onClick={ onSave }
						>
							{ __(
								'Save mapping',
								'rewind-form-bridge-for-brevo'
							) }
						</Button>
					</InlineStack>
				</InlineStack>

				{ saveHint && (
					<Note type="error">
						<Note.Normal>{ saveHint }</Note.Normal>
					</Note>
				) }
			</BlockStack>

			{ confirmLeave && (
				<Dialog
					title={ __(
						'Discard your changes?',
						'rewind-form-bridge-for-brevo'
					) }
					onRequestClose={ () => setConfirmLeave( false ) }
				>
					<Text size="sm">
						{ __(
							'This mapping has edits that have not been saved.',
							'rewind-form-bridge-for-brevo'
						) }
					</Text>

					<InlineStack
						gap={ 8 }
						align="end"
						style={ { marginTop: 24 } }
					>
						<Button
							startIcon="edit"
							variant="outlined"
							size="small"
							onClick={ () => setConfirmLeave( false ) }
						>
							{ __(
								'Keep editing',
								'rewind-form-bridge-for-brevo'
							) }
						</Button>
						<Button
							variant="error"
							size="small"
							startIcon="delete_forever"
							onClick={ leave }
						>
							{ __(
								'Discard changes',
								'rewind-form-bridge-for-brevo'
							) }
						</Button>
					</InlineStack>
				</Dialog>
			) }
		</div>
	);
}
