/**
 * Settings → Email: route WordPress's own mail through Brevo, so the site
 * needs no separate SMTP plugin.
 *
 * Two transports. The API one short-circuits wp_mail() into Brevo's
 * transactional endpoint over HTTPS 443 and is the default, because the
 * ports SMTP needs are blocked on a lot of hosts. The relay is there for
 * the accounts and policies that still require a real SMTP conversation.
 */
import { useCallback, useEffect, useState } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';

import {
	BlockStack,
	InlineStack,
	Note,
	SelectBox,
	SkeletonLoader,
} from '../../ui/molecules';
import { Button, Input, Switcher, Text } from '../../ui/atoms';
import Section from '../../components/Section';
import StatusBadge from '../../components/StatusBadge';
import {
	fetchEmailStatus,
	refreshSenders,
	sendTestEmail,
} from '../../api/email';
import { useApp } from '../../store/AppStore';
import { formatDateTime } from '../../utils/format';

const TRANSPORTS = [
	{
		value: 'api',
		name: () =>
			__( 'Brevo API — recommended', 'rewind-form-bridge-for-brevo' ),
	},
	{
		value: 'smtp',
		name: () => __( 'Brevo SMTP relay', 'rewind-form-bridge-for-brevo' ),
	},
];

// The saved sender, checked against the account's verified senders.
function SenderState( { status } ) {
	if ( status.sender_verified === null ) {
		return (
			<Text size="xs" color="gray-500">
				{ __(
					'Load your senders to check this address is one Brevo will accept.',
					'rewind-form-bridge-for-brevo'
				) }
			</Text>
		);
	}

	return status.sender_verified ? (
		<StatusBadge
			status="success"
			label={ __( 'Verified sender', 'rewind-form-bridge-for-brevo' ) }
		/>
	) : (
		<StatusBadge
			status="failed"
			label={ __(
				'Not a verified sender',
				'rewind-form-bridge-for-brevo'
			) }
		/>
	);
}

export default function EmailTab( { values, patch, save, saving, loading } ) {
	const { addToast, connection } = useApp();

	const [ status, setStatus ] = useState( null );
	const [ statusState, setStatusState ] = useState( 'idle' );
	const [ smtpKeyInput, setSmtpKeyInput ] = useState( '' );
	const [ testTo, setTestTo ] = useState( '' );
	const [ testing, setTesting ] = useState( false );
	const [ loadingSenders, setLoadingSenders ] = useState( false );

	const loadStatus = useCallback( async () => {
		setStatusState( 'loading' );

		try {
			setStatus( await fetchEmailStatus() );
			setStatusState( 'ready' );
		} catch ( error ) {
			addToast( error.message, 'error' );
			setStatusState( 'error' );
		}
	}, [ addToast ] );

	useEffect( () => {
		loadStatus();
	}, [ loadStatus ] );

	if ( loading || ! values || statusState === 'loading' || ! status ) {
		return <SkeletonLoader width="100%" height="420px" />;
	}

	const isSmtp = values.email_transport === 'smtp';
	const smtpFromConstant = status.smtp_key_source === 'constant';

	const onSave = async () => {
		const payload = {
			email_enabled: Boolean( values.email_enabled ),
			email_transport: values.email_transport || 'api',
			email_from_email: values.email_from_email || '',
			email_from_name: values.email_from_name || '',
			email_reply_to: values.email_reply_to || '',
			email_force_from: Boolean( values.email_force_from ),
			email_fallback: Boolean( values.email_fallback ),
			smtp_login: values.smtp_login || '',
			smtp_port: Number( values.smtp_port ) || 587,
		};

		if ( smtpKeyInput.trim() ) {
			payload.smtp_key = smtpKeyInput.trim();
		}

		try {
			await save( payload );
			setSmtpKeyInput( '' );
			await loadStatus();
		} catch ( error ) {
			// save() already surfaced the message as a toast.
		}
	};

	const onLoadSenders = async () => {
		setLoadingSenders( true );

		try {
			const result = await refreshSenders();

			setStatus( ( current ) => ( {
				...current,
				senders: result.senders || [],
				senders_cached: true,
				sender_verified: result.sender_verified,
			} ) );
			addToast(
				sprintf(
					/* translators: %d: number of senders found. */
					__(
						'%d senders loaded from Brevo.',
						'rewind-form-bridge-for-brevo'
					),
					( result.senders || [] ).length
				)
			);
		} catch ( error ) {
			addToast( error.message, 'error' );
		} finally {
			setLoadingSenders( false );
		}
	};

	const onSendTest = async () => {
		setTesting( true );

		try {
			const result = await sendTestEmail( testTo.trim() );

			addToast(
				sprintf(
					/* translators: %s: recipient address. */
					__(
						'Brevo accepted a test email to %s.',
						'rewind-form-bridge-for-brevo'
					),
					testTo.trim()
				)
			);
			setStatus( ( current ) => ( {
				...current,
				last_sent: result.sent_at || current.last_sent,
				last_error: null,
			} ) );
		} catch ( error ) {
			addToast( error.message, 'error' );
			await loadStatus();
		} finally {
			setTesting( false );
		}
	};

	const senderOptions = ( status.senders || [] ).map( ( sender ) => ( {
		value: sender.email,
		name: sender.name
			? `${ sender.name } <${ sender.email }>`
			: sender.email,
	} ) );

	return (
		<>
			<Section
				title={ __(
					'WordPress email through Brevo',
					'rewind-form-bridge-for-brevo'
				) }
				actions={
					<Button
						variant="primary"
						size="small"
						loading={ saving }
						disabled={ saving }
						onClick={ onSave }
					>
						{ __(
							'Save email settings',
							'rewind-form-bridge-for-brevo'
						) }
					</Button>
				}
			>
				<BlockStack
					gap={ 18 }
					style={ { width: '100%', maxWidth: 560 } }
				>
					{ status.conflicts.length > 0 && (
						<Note type="warning">
							<Note.Normal>
								<Note.Title
									title={ __(
										'Another mail plugin is active.',
										'rewind-form-bridge-for-brevo'
									) }
								/>
								{ sprintf(
									/* translators: %s: comma-separated plugin names. */
									__(
										'%s also rewrites wp_mail(). Two of them fighting over the same call is how mail starts vanishing at random — deactivate the other one before switching this on.',
										'rewind-form-bridge-for-brevo'
									),
									status.conflicts.join( ', ' )
								) }
							</Note.Normal>
						</Note>
					) }

					{ ! connection.hasKey && (
						<Note type="error">
							<Note.Normal>
								{ __(
									'No Brevo API key is saved yet. Add one on the Connections screen first — both transports need the account it identifies.',
									'rewind-form-bridge-for-brevo'
								) }
							</Note.Normal>
						</Note>
					) }

					<BlockStack gap={ 6 }>
						<Switcher
							checked={ Boolean( values.email_enabled ) }
							title={ __(
								'Send WordPress email through Brevo',
								'rewind-form-bridge-for-brevo'
							) }
							onChange={ ( checked ) =>
								patch( { email_enabled: checked } )
							}
						/>
						<Text size="xs" color="gray-500">
							{ __(
								'Covers every wp_mail() call on the site: password resets, order receipts, form notifications. Off by default — nothing is rerouted until you say so.',
								'rewind-form-bridge-for-brevo'
							) }
						</Text>
					</BlockStack>

					<SelectBox
						label={ __(
							'Transport',
							'rewind-form-bridge-for-brevo'
						) }
						value={ [ values.email_transport || 'api' ] }
						options={ TRANSPORTS.map( ( item ) => ( {
							value: item.value,
							name: item.name(),
						} ) ) }
						helperText={
							isSmtp
								? sprintf(
										/* translators: %s: SMTP host name. */
										__(
											'Authenticates against %s with an SMTP key. Many hosts block outbound SMTP ports; if the test times out, that is usually why.',
											'rewind-form-bridge-for-brevo'
										),
										status.smtp_host
								  )
								: __(
										'Uses the API key you already saved, over HTTPS on port 443. Nothing extra to configure and nothing for a host firewall to block.',
										'rewind-form-bridge-for-brevo'
								  )
						}
						onChange={ ( selected ) =>
							patch( {
								email_transport: selected[ 0 ] || 'api',
							} )
						}
					/>

					{ isSmtp && (
						<>
							<Input
								label={ __(
									'SMTP login',
									'rewind-form-bridge-for-brevo'
								) }
								value={ values.smtp_login || '' }
								placeholder="you@example.com"
								helperText={ __(
									'The login shown in Brevo under SMTP & API → SMTP. Usually your account email, and not always the same as the sender address.',
									'rewind-form-bridge-for-brevo'
								) }
								onChange={ ( value ) =>
									patch( { smtp_login: value } )
								}
							/>

							<Input
								type="password"
								label={ __(
									'SMTP key',
									'rewind-form-bridge-for-brevo'
								) }
								value={ smtpKeyInput }
								disabled={ smtpFromConstant }
								placeholder={
									status.has_smtp_key
										? status.smtp_key_hint
										: 'xsmtpsib-…'
								}
								helperText={
									smtpFromConstant
										? __(
												'Set by the RBFB_SMTP_KEY constant in wp-config.php, so it cannot be edited here.',
												'rewind-form-bridge-for-brevo'
										  )
										: __(
												'The SMTP key from Brevo, which is a different credential from the v3 API key. Leave blank to keep the stored one.',
												'rewind-form-bridge-for-brevo'
										  )
								}
								onChange={ ( value ) =>
									setSmtpKeyInput( value )
								}
							/>

							<SelectBox
								label={ __(
									'Port',
									'rewind-form-bridge-for-brevo'
								) }
								value={ [ String( values.smtp_port || 587 ) ] }
								options={ ( status.smtp_ports || [] ).map(
									( port ) => ( {
										value: String( port ),
										name:
											port === 465
												? sprintf(
														/* translators: %d: port number. */
														__(
															'%d (implicit TLS)',
															'rewind-form-bridge-for-brevo'
														),
														port
												  )
												: sprintf(
														/* translators: %d: port number. */
														__(
															'%d (STARTTLS)',
															'rewind-form-bridge-for-brevo'
														),
														port
												  ),
									} )
								) }
								onChange={ ( selected ) =>
									patch( {
										smtp_port: Number(
											selected[ 0 ] || 587
										),
									} )
								}
							/>
						</>
					) }

					<InlineStack gap={ 12 } blockAlign="end" wrap>
						{ senderOptions.length > 0 ? (
							<div style={ { flex: '1 1 260px' } }>
								<SelectBox
									searchable
									label={ __(
										'Send from',
										'rewind-form-bridge-for-brevo'
									) }
									value={
										values.email_from_email
											? [ values.email_from_email ]
											: []
									}
									options={ senderOptions }
									placeholder={ __(
										'Pick a verified sender…',
										'rewind-form-bridge-for-brevo'
									) }
									onChange={ ( selected ) =>
										patch( {
											email_from_email:
												selected[ 0 ] || '',
										} )
									}
								/>
							</div>
						) : (
							<div style={ { flex: '1 1 260px' } }>
								<Input
									type="email"
									label={ __(
										'Send from',
										'rewind-form-bridge-for-brevo'
									) }
									value={ values.email_from_email || '' }
									placeholder="hello@example.com"
									onChange={ ( value ) =>
										patch( { email_from_email: value } )
									}
								/>
							</div>
						) }

						<Button
							variant="outlined"
							size="small"
							startIcon="refresh"
							loading={ loadingSenders }
							disabled={ loadingSenders || ! connection.hasKey }
							onClick={ onLoadSenders }
						>
							{ __(
								'Load senders',
								'rewind-form-bridge-for-brevo'
							) }
						</Button>
					</InlineStack>

					<BlockStack gap={ 6 }>
						<SenderState status={ status } />
						<Text size="xs" color="gray-500">
							{ __(
								'Brevo refuses a send whose from-address is not a registered, verified sender on the account. This is the single most common reason site email stops working after a switch.',
								'rewind-form-bridge-for-brevo'
							) }
						</Text>
					</BlockStack>

					<Input
						label={ __(
							'Sender name',
							'rewind-form-bridge-for-brevo'
						) }
						value={ values.email_from_name || '' }
						placeholder={ __(
							'Your site name',
							'rewind-form-bridge-for-brevo'
						) }
						onChange={ ( value ) =>
							patch( { email_from_name: value } )
						}
					/>

					<Input
						type="email"
						label={ __(
							'Reply-To (optional)',
							'rewind-form-bridge-for-brevo'
						) }
						value={ values.email_reply_to || '' }
						helperText={ __(
							'Where replies should land when the mail itself does not set a Reply-To.',
							'rewind-form-bridge-for-brevo'
						) }
						onChange={ ( value ) =>
							patch( { email_reply_to: value } )
						}
					/>

					<BlockStack gap={ 6 }>
						<Switcher
							checked={ Boolean( values.email_force_from ) }
							title={ __(
								'Always use this sender',
								'rewind-form-bridge-for-brevo'
							) }
							onChange={ ( checked ) =>
								patch( { email_force_from: checked } )
							}
						/>
						<Text size="xs" color="gray-500">
							{ __(
								'Overrides the From address other plugins set. Leave on unless one of them sends from an address you have also verified in Brevo.',
								'rewind-form-bridge-for-brevo'
							) }
						</Text>
					</BlockStack>

					<BlockStack gap={ 6 }>
						<Switcher
							checked={ Boolean( values.email_fallback ) }
							title={ __(
								'Fall back to the server mailer if Brevo fails',
								'rewind-form-bridge-for-brevo'
							) }
							onChange={ ( checked ) =>
								patch( { email_fallback: checked } )
							}
						/>
						<Text size="xs" color="gray-500">
							{ __(
								'On: a rejected send is retried by WordPress the old way, so a password reset still arrives. Off: the send fails loudly instead, which is what you want while you are diagnosing one.',
								'rewind-form-bridge-for-brevo'
							) }
						</Text>
					</BlockStack>
				</BlockStack>
			</Section>

			<Section
				title={ __(
					'Delivery status',
					'rewind-form-bridge-for-brevo'
				) }
				actions={
					<Button
						variant="outlined"
						size="small"
						startIcon="refresh"
						onClick={ loadStatus }
					>
						{ __( 'Refresh', 'rewind-form-bridge-for-brevo' ) }
					</Button>
				}
			>
				<BlockStack gap={ 16 } style={ { width: '100%' } }>
					<InlineStack gap={ 32 } blockAlign="center" wrap>
						<BlockStack gap={ 4 } style={ { flex: '0 0 auto' } }>
							<Text size="xs" color="gray-500">
								{ __(
									'Routing',
									'rewind-form-bridge-for-brevo'
								) }
							</Text>
							<StatusBadge
								status={ status.active ? 'active' : 'paused' }
								label={
									status.active
										? __(
												'Brevo is handling site email',
												'rewind-form-bridge-for-brevo'
										  )
										: __(
												'Using the server default',
												'rewind-form-bridge-for-brevo'
										  )
								}
							/>
						</BlockStack>

						<BlockStack gap={ 4 } style={ { flex: '0 0 auto' } }>
							<Text size="xs" color="gray-500">
								{ __(
									'Last accepted send',
									'rewind-form-bridge-for-brevo'
								) }
							</Text>
							<Text size="sm">
								{ formatDateTime( status.last_sent ) }
							</Text>
						</BlockStack>
					</InlineStack>

					{ status.last_error && (
						<Note type="error">
							<Note.Normal>
								<Note.Title
									title={ formatDateTime(
										status.last_error.created_at
									) }
								/>
								{ status.last_error.message }
							</Note.Normal>
						</Note>
					) }

					<InlineStack gap={ 12 } blockAlign="end" wrap>
						<div style={ { flex: '1 1 260px' } }>
							<Input
								type="email"
								label={ __(
									'Send a test email to',
									'rewind-form-bridge-for-brevo'
								) }
								value={ testTo }
								placeholder="you@example.com"
								onChange={ ( value ) => setTestTo( value ) }
							/>
						</div>

						<Button
							variant="primary"
							size="small"
							startIcon="send"
							loading={ testing }
							disabled={ testing || ! testTo.trim() }
							onClick={ onSendTest }
						>
							{ __(
								'Send test',
								'rewind-form-bridge-for-brevo'
							) }
						</Button>
					</InlineStack>

					<Text size="xs" color="gray-500">
						{ __(
							'The API test sends straight through Brevo, so it works before you switch routing on. The SMTP test goes through a real wp_mail() call, which means the settings have to be saved and switched on first.',
							'rewind-form-bridge-for-brevo'
						) }
					</Text>
				</BlockStack>
			</Section>
		</>
	);
}
