/**
 * Logs — the delivery log: status tabs, search, date range, a paginated
 * table, the payload detail modal and the bulk maintenance actions.
 */
import { useCallback, useEffect, useState } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { useSearchParams } from 'react-router-dom';

import {
	BlockStack,
	EmptyState,
	InlineStack,
	Note,
	Pagination,
	SkeletonLoader,
} from '../../ui/molecules';
import { Button, Icon, Input, Tabs, Text } from '../../ui/atoms';
import DateField from '../../components/DateField';
import Section from '../../components/Section';
import StatusBadge from '../../components/StatusBadge';
import LogDetail from './LogDetail';
import {
	exportLogs,
	fetchLog,
	fetchLogs,
	purgeLogs,
	retryFailed,
	retryLog,
} from '../../api/logs';
import { useApp } from '../../store/AppStore';
import {
	downloadFile,
	formatDateTime,
	formatRelative,
} from '../../utils/format';

const EMPTY_FILTERS = {
	status: '',
	feed_id: 0,
	search: '',
	date_from: '',
	date_to: '',
};
const PER_PAGE = 20;

const STATUS_TABS = [
	{
		key: '',
		title: () => __( 'All', 'rewind-form-bridge-for-brevo' ),
		icon: 'list',
	},
	{
		key: 'success',
		title: () => __( 'Success', 'rewind-form-bridge-for-brevo' ),
		icon: 'task_alt',
	},
	{
		key: 'failed',
		title: () => __( 'Failed', 'rewind-form-bridge-for-brevo' ),
		icon: 'error',
	},
	{
		key: 'skipped',
		title: () => __( 'Skipped', 'rewind-form-bridge-for-brevo' ),
		icon: 'block',
	},
	{
		key: 'retrying',
		title: () => __( 'Retrying', 'rewind-form-bridge-for-brevo' ),
		icon: 'cached',
	},
	{
		key: 'queued',
		title: () => __( 'Queued', 'rewind-form-bridge-for-brevo' ),
		icon: 'schedule',
	},
];

export default function Logs() {
	const { settings, addToast } = useApp();
	const [ searchParams, setSearchParams ] = useSearchParams();

	const [ loading, setLoading ] = useState( true );
	const [ error, setError ] = useState( '' );
	const [ rows, setRows ] = useState( [] );
	const [ page, setPage ] = useState( 1 );
	const [ pages, setPages ] = useState( 1 );
	const [ total, setTotal ] = useState( 0 );
	const [ filters, setFilters ] = useState( EMPTY_FILTERS );
	const [ detail, setDetail ] = useState( null );
	const [ retrying, setRetrying ] = useState( false );
	const [ busy, setBusy ] = useState( false );

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

		try {
			const response = await fetchLogs(
				activeFilters,
				nextPage,
				PER_PAGE
			);

			setRows( response.items || [] );
			setPages( response.pages || 1 );
			setTotal( response.total || 0 );
		} catch ( requestError ) {
			setError( requestError.message );
		} finally {
			setLoading( false );
		}
	}, [] );

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

	/* Deep link from the dashboard: ?entry=123 opens that row's panel. */
	useEffect( () => {
		const entryId = searchParams.get( 'entry' );

		if ( ! entryId ) {
			return;
		}

		fetchLog( entryId )
			.then( setDetail )
			.catch( ( requestError ) =>
				addToast( requestError.message, 'error' )
			)
			.finally( () => {
				searchParams.delete( 'entry' );
				setSearchParams( searchParams, { replace: true } );
			} );
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [] );

	const patchFilter = ( changes ) => {
		setPage( 1 );
		setFilters( ( current ) => ( { ...current, ...changes } ) );
	};

	const onRetry = async ( entry ) => {
		setRetrying( true );

		try {
			const updated = await retryLog( entry.id );

			setRows( ( current ) =>
				current.map( ( row ) =>
					row.id === updated.id ? updated : row
				)
			);
			setDetail( updated );

			addToast(
				updated.status === 'success'
					? __(
							'Delivery succeeded on retry.',
							'rewind-form-bridge-for-brevo'
					  )
					: __(
							'Retry failed again — see the entry for details.',
							'rewind-form-bridge-for-brevo'
					  ),
				updated.status === 'success' ? 'success' : 'error'
			);
		} catch ( requestError ) {
			addToast( requestError.message, 'error' );
		} finally {
			setRetrying( false );
		}
	};

	const onRetryFailed = async () => {
		setBusy( true );

		try {
			const result = await retryFailed( filters, 25 );

			addToast(
				sprintf(
					/* translators: 1: number retried, 2: number that succeeded. */
					__(
						'Retried %1$d entries; %2$d succeeded.',
						'rewind-form-bridge-for-brevo'
					),
					result.attempted,
					result.succeeded
				),
				result.succeeded > 0 ? 'success' : 'error'
			);

			load( page, filters );
		} catch ( requestError ) {
			addToast( requestError.message, 'error' );
		} finally {
			setBusy( false );
		}
	};

	const onExport = async () => {
		setBusy( true );

		try {
			const result = await exportLogs( filters );

			if ( result.rows === 0 ) {
				addToast(
					__(
						'Nothing to export with these filters.',
						'rewind-form-bridge-for-brevo'
					),
					'error'
				);
				return;
			}

			downloadFile(
				result.filename,
				result.csv,
				'text/csv;charset=utf-8'
			);
			addToast(
				sprintf(
					/* translators: %d: number of exported rows. */
					__(
						'Exported %d entries.',
						'rewind-form-bridge-for-brevo'
					),
					result.rows
				)
			);
		} catch ( requestError ) {
			addToast( requestError.message, 'error' );
		} finally {
			setBusy( false );
		}
	};

	const onPurge = async () => {
		setBusy( true );

		try {
			const days = Number( settings.log_retention_days ) || 30;
			const result = await purgeLogs( days );

			addToast(
				sprintf(
					/* translators: %d: number of deleted entries. */
					__(
						'Deleted %d old entries.',
						'rewind-form-bridge-for-brevo'
					),
					result.deleted
				)
			);

			setPage( 1 );
			load( 1, filters );
		} catch ( requestError ) {
			addToast( requestError.message, 'error' );
		} finally {
			setBusy( false );
		}
	};

	const hasFilters =
		JSON.stringify( filters ) !== JSON.stringify( EMPTY_FILTERS );
	const retentionDays = Number( settings.log_retention_days ) || 30;

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

				<Section
					icon="receipt_long"
					title={ __(
						'Delivery log',
						'rewind-form-bridge-for-brevo'
					) }
					actions={
						<InlineStack gap={ 8 }>
							<Button
								variant="outlined"
								size="small"
								startIcon="cached"
								disabled={ busy }
								onClick={ onRetryFailed }
							>
								{ __(
									'Retry failed',
									'rewind-form-bridge-for-brevo'
								) }
							</Button>
							<Button
								startIcon="download"
								variant="outlined"
								size="small"
								disabled={ busy }
								onClick={ onExport }
							>
								{ __(
									'Export CSV',
									'rewind-form-bridge-for-brevo'
								) }
							</Button>
							<Button
								startIcon="delete_sweep"
								variant="error"
								size="small"
								disabled={ busy }
								onClick={ onPurge }
							>
								{ sprintf(
									/* translators: %d: retention window in days. */
									__(
										'Clear older than %d days',
										'rewind-form-bridge-for-brevo'
									),
									retentionDays
								) }
							</Button>
						</InlineStack>
					}
				>
					<BlockStack gap={ 16 } style={ { width: '100%' } }>
						<InlineStack
							gap={ 12 }
							align="between"
							blockAlign="end"
							wrap
							className="rbfb-log-filters"
						>
							<Tabs
								size="small"
								rounded="md"
								tabRounded="sm"
								tabs={ STATUS_TABS.map( ( tab ) => ( {
									key: tab.key,
									title: tab.title(),
									icon: tab.icon,
								} ) ) }
								active={ filters.status }
								onTabClick={ ( key ) =>
									patchFilter( { status: key } )
								}
							/>

							<InlineStack gap={ 10 } blockAlign="end" wrap>
								<div style={ { minWidth: 200 } }>
									<Input
										rounded="xs"
										size="small"
										placeholder={ __(
											'Search by email…',
											'rewind-form-bridge-for-brevo'
										) }
										value={ filters.search }
										onChange={ ( value ) =>
											patchFilter( { search: value } )
										}
									/>
								</div>

								<div style={ { minWidth: 150 } }>
									<DateField
										label={ __(
											'From',
											'rewind-form-bridge-for-brevo'
										) }
										value={ filters.date_from }
										onChange={ ( value ) =>
											patchFilter( { date_from: value } )
										}
									/>
								</div>

								<div style={ { minWidth: 150 } }>
									<DateField
										label={ __(
											'To',
											'rewind-form-bridge-for-brevo'
										) }
										value={ filters.date_to }
										onChange={ ( value ) =>
											patchFilter( { date_to: value } )
										}
									/>
								</div>

								{ hasFilters && (
									<Button
										startIcon="filter_alt_off"
										variant="outlined"
										size="small"
										onClick={ () => {
											setPage( 1 );
											setFilters( EMPTY_FILTERS );
										} }
									>
										{ __(
											'Clear filters',
											'rewind-form-bridge-for-brevo'
										) }
									</Button>
								) }
							</InlineStack>
						</InlineStack>

						{ loading && (
							<BlockStack gap={ 10 } style={ { width: '100%' } }>
								{ [ 0, 1, 2, 3, 4 ].map( ( row ) => (
									<SkeletonLoader
										key={ row }
										width="100%"
										height="34px"
									/>
								) ) }
							</BlockStack>
						) }

						{ ! loading && rows.length === 0 && (
							<EmptyState
								icon={
									<Icon
										name="history"
										fontSize="4xl"
										color="gray-400"
									/>
								}
								title={
									hasFilters
										? __(
												'Nothing matches those filters',
												'rewind-form-bridge-for-brevo'
										  )
										: __(
												'No deliveries logged yet',
												'rewind-form-bridge-for-brevo'
										  )
								}
								description={
									hasFilters
										? __(
												'Try widening the date range or clearing the status filter.',
												'rewind-form-bridge-for-brevo'
										  )
										: __(
												'Every submission a mapping handles is recorded here, successful or not.',
												'rewind-form-bridge-for-brevo'
										  )
								}
							>
								{ hasFilters && (
									<Button
										startIcon="filter_alt_off"
										variant="outlined"
										size="small"
										onClick={ () => {
											setPage( 1 );
											setFilters( EMPTY_FILTERS );
										} }
									>
										{ __(
											'Clear filters',
											'rewind-form-bridge-for-brevo'
										) }
									</Button>
								) }
							</EmptyState>
						) }

						{ ! loading && rows.length > 0 && (
							<>
								<table className="rbfb-table">
									<thead>
										<tr>
											<th>
												{ __(
													'When',
													'rewind-form-bridge-for-brevo'
												) }
											</th>
											<th>
												{ __(
													'Contact',
													'rewind-form-bridge-for-brevo'
												) }
											</th>
											<th>
												{ __(
													'Form',
													'rewind-form-bridge-for-brevo'
												) }
											</th>
											<th>
												{ __(
													'Status',
													'rewind-form-bridge-for-brevo'
												) }
											</th>
											<th>
												{ __(
													'Tries',
													'rewind-form-bridge-for-brevo'
												) }
											</th>
											<th>
												{ __(
													'Message',
													'rewind-form-bridge-for-brevo'
												) }
											</th>
										</tr>
									</thead>
									<tbody>
										{ rows.map( ( row ) => (
											<tr
												key={ row.id }
												className="rbfb-table__row--clickable"
												onClick={ () =>
													setDetail( row )
												}
											>
												<td
													title={ formatDateTime(
														row.created_at
													) }
												>
													{ formatRelative(
														row.created_at
													) }
												</td>
												<td>
													{ row.email ||
														__(
															'(no email)',
															'rewind-form-bridge-for-brevo'
														) }
												</td>
												<td>{ row.feed_title }</td>
												<td>
													<StatusBadge
														status={ row.status }
													/>
												</td>
												<td>{ row.attempts }</td>
												<td
													className="rbfb-table__message"
													title={ row.message }
												>
													{ row.message }
												</td>
											</tr>
										) ) }
									</tbody>
								</table>

								<div className="rbfb-pagination">
									<Text size="xs" color="gray-500">
										{ sprintf(
											/* translators: %d: total number of entries. */
											__(
												'%d entries',
												'rewind-form-bridge-for-brevo'
											),
											total
										) }
									</Text>

									<Pagination
										current_page={ page }
										total_pages={ pages }
										onPageChange={ setPage }
									/>
								</div>
							</>
						) }
					</BlockStack>
				</Section>
			</BlockStack>

			{ detail && (
				<LogDetail
					entry={ detail }
					retrying={ retrying }
					onRetry={ onRetry }
					onClose={ () => setDetail( null ) }
				/>
			) }
		</div>
	);
}
