/**
 * Settings, with a General tab and a Tools tab.
 *
 * Only settings the plugin actually acts on are offered here. Sync mode,
 * retry backoff and a queue runner belong to the queue phase and are not
 * stubbed in — an inert control is worse than an absent one.
 */
import { useCallback, useEffect, useRef, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { useNavigate, useParams } from 'react-router-dom';

import {
	BlockStack,
	InlineStack,
	Note,
	SkeletonLoader,
} from '../../ui/molecules';
import { Button, Checkbox, Input, Tabs, Text } from '../../ui/atoms';
import Section from '../../components/Section';
import StatusBadge from '../../components/StatusBadge';
import EmailTab from './EmailTab';
import { fetchSettings, resetSettings, saveSettings } from '../../api/settings';
import { exportSettings, fetchStatus, importSettings } from '../../api/system';
import { useApp } from '../../store/AppStore';
import { downloadFile, formatDateTime } from '../../utils/format';

const TABS = [
	{
		key: 'general',
		title: () => __( 'General', 'rewind-form-bridge-for-brevo' ),
		icon: 'tune',
	},
	{
		key: 'email',
		title: () => __( 'Email', 'rewind-form-bridge-for-brevo' ),
		icon: 'mail',
	},
	{
		key: 'tools',
		title: () => __( 'Tools', 'rewind-form-bridge-for-brevo' ),
		icon: 'handyman',
	},
];

/* flex:0 0 auto keeps a fact sized to its content, so a row of them lays
   out side by side instead of each stretching to the container width. */
function Fact( { label, children } ) {
	return (
		<BlockStack gap={ 4 } style={ { flex: '0 0 auto', minWidth: 110 } }>
			<Text size="xs" color="gray-500">
				{ label }
			</Text>
			<div>{ children }</div>
		</BlockStack>
	);
}

function StatusReport( { status } ) {
	const environment = [
		[ __( 'PHP', 'rewind-form-bridge-for-brevo' ), status.environment.php ],
		[
			__( 'WordPress', 'rewind-form-bridge-for-brevo' ),
			status.environment.wordpress,
		],
		[
			__( 'Plugin', 'rewind-form-bridge-for-brevo' ),
			status.environment.plugin,
		],
		[
			__( 'Schema', 'rewind-form-bridge-for-brevo' ),
			status.environment.db_version,
		],
		[
			__( 'MySQL', 'rewind-form-bridge-for-brevo' ),
			status.environment.mysql,
		],
		[
			__( 'Memory limit', 'rewind-form-bridge-for-brevo' ),
			status.environment.memory_limit,
		],
		[
			__( 'Timezone', 'rewind-form-bridge-for-brevo' ),
			status.environment.timezone,
		],
	];

	return (
		<BlockStack gap={ 20 } style={ { width: '100%' } }>
			<InlineStack gap={ 32 } blockAlign="start" wrap>
				{ environment.map( ( [ label, value ] ) => (
					<Fact key={ label } label={ label }>
						<Text size="sm">{ value || '—' }</Text>
					</Fact>
				) ) }

				<Fact label={ __( 'SSL', 'rewind-form-bridge-for-brevo' ) }>
					<StatusBadge
						status={ status.environment.ssl ? 'active' : 'failed' }
						label={
							status.environment.ssl
								? __( 'On', 'rewind-form-bridge-for-brevo' )
								: __( 'Off', 'rewind-form-bridge-for-brevo' )
						}
					/>
				</Fact>

				<Fact label={ __( 'WP-Cron', 'rewind-form-bridge-for-brevo' ) }>
					<StatusBadge
						status={
							status.environment.wp_cron ? 'active' : 'failed'
						}
						label={
							status.environment.wp_cron
								? __(
										'Enabled',
										'rewind-form-bridge-for-brevo'
								  )
								: __(
										'Disabled',
										'rewind-form-bridge-for-brevo'
								  )
						}
					/>
				</Fact>

				<Fact
					label={ __( 'Mappings', 'rewind-form-bridge-for-brevo' ) }
				>
					<Text size="sm">{ status.data.feeds }</Text>
				</Fact>

				<Fact
					label={ __(
						'Log entries',
						'rewind-form-bridge-for-brevo'
					) }
				>
					<Text size="sm">{ status.data.logs }</Text>
				</Fact>

				<Fact
					label={ __(
						'Form plugins detected',
						'rewind-form-bridge-for-brevo'
					) }
				>
					<Text size="sm">
						{ status.adapters.length > 0
							? status.adapters.join( ', ' )
							: __(
									'None active',
									'rewind-form-bridge-for-brevo'
							  ) }
					</Text>
				</Fact>

				<Fact
					label={ __(
						'Last verified',
						'rewind-form-bridge-for-brevo'
					) }
				>
					<Text size="sm">
						{ formatDateTime( status.connection.last_verified ) }
					</Text>
				</Fact>
			</InlineStack>

			<BlockStack gap={ 8 }>
				<Text size="xs" weight="semibold">
					{ __( 'Database tables', 'rewind-form-bridge-for-brevo' ) }
				</Text>
				<InlineStack gap={ 8 } wrap>
					{ Object.entries( status.tables ).map(
						( [ table, present ] ) => (
							<InlineStack
								key={ table }
								gap={ 6 }
								blockAlign="center"
							>
								<StatusBadge
									status={ present ? 'success' : 'failed' }
									label={
										present
											? __(
													'Present',
													'rewind-form-bridge-for-brevo'
											  )
											: __(
													'Missing',
													'rewind-form-bridge-for-brevo'
											  )
									}
								/>
								<Text size="xs">{ table }</Text>
							</InlineStack>
						)
					) }
				</InlineStack>
			</BlockStack>

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

export default function Settings() {
	const { tab } = useParams();
	const navigate = useNavigate();
	const { addToast, reloadSettings } = useApp();

	const activeTab = TABS.some( ( item ) => item.key === tab )
		? tab
		: 'general';

	const [ loading, setLoading ] = useState( true );
	const [ error, setError ] = useState( '' );
	const [ values, setValues ] = useState( null );
	const [ saving, setSaving ] = useState( false );
	const [ status, setStatus ] = useState( null );
	const [ statusState, setStatusState ] = useState( 'idle' );

	const fileInput = useRef( null );

	const load = useCallback( async () => {
		setLoading( true );
		setError( '' );

		try {
			setValues( await fetchSettings() );
		} catch ( requestError ) {
			setError( requestError.message );
		} finally {
			setLoading( false );
		}
	}, [] );

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

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

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

	useEffect( () => {
		if ( activeTab === 'tools' && statusState === 'idle' ) {
			loadStatus();
		}
	}, [ activeTab, statusState, loadStatus ] );

	const patch = ( changes ) =>
		setValues( ( current ) => ( { ...current, ...changes } ) );

	/* One writer for every tab: each passes just the fields it owns, so a
	   save on one tab can never overwrite another tab's unsaved edits. */
	const save = useCallback(
		async ( payload ) => {
			setSaving( true );

			try {
				const saved = await saveSettings( payload );

				setValues( saved );
				await reloadSettings();
				addToast(
					__( 'Settings saved.', 'rewind-form-bridge-for-brevo' )
				);

				return saved;
			} catch ( requestError ) {
				addToast( requestError.message, 'error' );
				throw requestError;
			} finally {
				setSaving( false );
			}
		},
		[ addToast, reloadSettings ]
	);

	const onSave = () =>
		save( {
			default_country: values.default_country,
			log_retention_days: Number( values.log_retention_days ),
			alert_email: values.alert_email,
			alert_failure_threshold: Number( values.alert_failure_threshold ),
			delete_data_on_uninstall: Boolean(
				values.delete_data_on_uninstall
			),
		} ).catch( () => {
			// save() already reported it.
		} );

	const onReset = async () => {
		setSaving( true );

		try {
			setValues( await resetSettings() );
			await reloadSettings();
			addToast(
				__(
					'Settings restored to defaults.',
					'rewind-form-bridge-for-brevo'
				)
			);
		} catch ( requestError ) {
			addToast( requestError.message, 'error' );
		} finally {
			setSaving( false );
		}
	};

	const onExport = async () => {
		try {
			const result = await exportSettings();

			downloadFile(
				result.filename,
				JSON.stringify(
					{
						plugin: result.plugin,
						exported_at: result.exported_at,
						settings: result.settings,
					},
					null,
					2
				),
				'application/json'
			);
			addToast(
				__( 'Settings exported.', 'rewind-form-bridge-for-brevo' )
			);
		} catch ( requestError ) {
			addToast( requestError.message, 'error' );
		}
	};

	const onImportFile = async ( event ) => {
		const file = event.target.files?.[ 0 ];

		if ( ! file ) {
			return;
		}

		try {
			const parsed = JSON.parse( await file.text() );

			await importSettings( parsed.settings || parsed );
			await load();
			await reloadSettings();

			addToast(
				__( 'Settings imported.', 'rewind-form-bridge-for-brevo' )
			);
		} catch ( requestError ) {
			addToast(
				requestError instanceof SyntaxError
					? __(
							'That file is not valid JSON.',
							'rewind-form-bridge-for-brevo'
					  )
					: requestError.message,
				'error'
			);
		} finally {
			event.target.value = '';
		}
	};

	return (
		<div className="rbfb-page rbfb-page--wide">
			<BlockStack gap={ 20 }>
				{ error && (
					<Note type="error">
						<Note.Normal>{ error }</Note.Normal>
					</Note>
				) }

				<Tabs
					rounded="md"
					tabRounded="sm"
					tabs={ TABS.map( ( item ) => ( {
						key: item.key,
						title: item.title(),
						icon: item.icon,
					} ) ) }
					active={ activeTab }
					onTabClick={ ( key ) => navigate( `/settings/${ key }` ) }
				/>

				{ activeTab === 'general' && (
					<Section
						icon="tune"
						title={ __(
							'Delivery behaviour',
							'rewind-form-bridge-for-brevo'
						) }
						actions={
							<InlineStack gap={ 8 }>
								<Button
									startIcon="save"
									variant="primary"
									size="small"
									loading={ saving }
									disabled={ saving || loading }
									onClick={ onSave }
								>
									{ __(
										'Save settings',
										'rewind-form-bridge-for-brevo'
									) }
								</Button>
								<Button
									startIcon="restart_alt"
									variant="outlined"
									size="small"
									disabled={ saving || loading }
									onClick={ onReset }
								>
									{ __(
										'Restore defaults',
										'rewind-form-bridge-for-brevo'
									) }
								</Button>
							</InlineStack>
						}
					>
						{ loading && (
							<SkeletonLoader width="100%" height="220px" />
						) }

						{ ! loading && values && (
							<BlockStack
								gap={ 18 }
								style={ { width: '100%', maxWidth: 520 } }
							>
								<Input
									label={ __(
										'Default phone country',
										'rewind-form-bridge-for-brevo'
									) }
									value={ values.default_country || '' }
									maxLength={ 2 }
									placeholder="BD"
									helperText={ __(
										'Two-letter ISO code used to add a dialling code to phone numbers submitted without one. Brevo rejects bare local numbers; leave blank to reject them instead.',
										'rewind-form-bridge-for-brevo'
									) }
									onChange={ ( value ) =>
										patch( {
											default_country:
												String( value ).toUpperCase(),
										} )
									}
								/>

								<Input
									type="number"
									label={ __(
										'Keep log entries for (days)',
										'rewind-form-bridge-for-brevo'
									) }
									value={ values.log_retention_days }
									helperText={ __(
										'Used by the "Clear older than" action on the Logs screen.',
										'rewind-form-bridge-for-brevo'
									) }
									onChange={ ( value ) =>
										patch( { log_retention_days: value } )
									}
								/>

								<Input
									type="email"
									label={ __(
										'Failure alert email',
										'rewind-form-bridge-for-brevo'
									) }
									value={ values.alert_email || '' }
									helperText={ __(
										'Where delivery-failure alerts go. Leave blank to use the site admin address.',
										'rewind-form-bridge-for-brevo'
									) }
									onChange={ ( value ) =>
										patch( { alert_email: value } )
									}
								/>

								<Input
									type="number"
									label={ __(
										'Alert after consecutive failures',
										'rewind-form-bridge-for-brevo'
									) }
									value={ values.alert_failure_threshold }
									onChange={ ( value ) =>
										patch( {
											alert_failure_threshold: value,
										} )
									}
								/>

								<BlockStack gap={ 6 }>
									<Checkbox
										checked={ Boolean(
											values.delete_data_on_uninstall
										) }
										title={ __(
											'Delete all plugin data when the plugin is uninstalled',
											'rewind-form-bridge-for-brevo'
										) }
										onChange={ ( checked ) =>
											patch( {
												delete_data_on_uninstall:
													checked,
											} )
										}
									/>
									<Text size="xs" color="gray-500">
										{ __(
											'Off by default: the delivery log and consent records may be compliance data you need to keep.',
											'rewind-form-bridge-for-brevo'
										) }
									</Text>
								</BlockStack>
							</BlockStack>
						) }
					</Section>
				) }

				{ activeTab === 'email' && (
					<EmailTab
						values={ values }
						patch={ patch }
						save={ save }
						saving={ saving }
						loading={ loading }
					/>
				) }

				{ activeTab === 'tools' && (
					<>
						<Section
							icon="description"
							title={ __(
								'Settings file',
								'rewind-form-bridge-for-brevo'
							) }
						>
							<BlockStack gap={ 12 } style={ { width: '100%' } }>
								<Text size="xs" color="gray-500">
									{ __(
										'Move this configuration between sites. The API key is never included in an export.',
										'rewind-form-bridge-for-brevo'
									) }
								</Text>

								<InlineStack gap={ 8 }>
									<Button
										startIcon="download"
										variant="outlined"
										size="small"
										onClick={ onExport }
									>
										{ __(
											'Export settings',
											'rewind-form-bridge-for-brevo'
										) }
									</Button>
									<Button
										startIcon="upload"
										variant="outlined"
										size="small"
										onClick={ () =>
											fileInput.current?.click()
										}
									>
										{ __(
											'Import settings',
											'rewind-form-bridge-for-brevo'
										) }
									</Button>
									<input
										ref={ fileInput }
										type="file"
										accept="application/json,.json"
										onChange={ onImportFile }
										style={ { display: 'none' } }
										aria-label={ __(
											'Choose a settings JSON file',
											'rewind-form-bridge-for-brevo'
										) }
									/>
								</InlineStack>
							</BlockStack>
						</Section>

						<Section
							icon="monitor_heart"
							title={ __(
								'System status',
								'rewind-form-bridge-for-brevo'
							) }
							actions={
								<Button
									variant="outlined"
									size="small"
									startIcon="refresh"
									disabled={ statusState === 'loading' }
									onClick={ loadStatus }
								>
									{ __(
										'Refresh',
										'rewind-form-bridge-for-brevo'
									) }
								</Button>
							}
						>
							{ statusState === 'loading' && (
								<SkeletonLoader width="100%" height="200px" />
							) }

							{ statusState === 'error' && (
								<Note type="error">
									<Note.Normal>
										{ __(
											'The status report could not be loaded.',
											'rewind-form-bridge-for-brevo'
										) }
									</Note.Normal>
								</Note>
							) }

							{ statusState === 'ready' && status && (
								<StatusReport status={ status } />
							) }
						</Section>
					</>
				) }
			</BlockStack>
		</div>
	);
}
