import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import { addQueryArgs } from '@wordpress/url';
import ReactPaginate from 'react-paginate';
import { debounce } from 'lodash';
import { useState, useEffect, useCallback } from '@wordpress/element';
import { SelectControl, Button, TextControl, Dropdown, Spinner, Notice, Popover, Snackbar } from '@wordpress/components';
import useSWR from 'swr';
import { useMatchMutate } from './utils';

export default function Table( { setId, setOpen } ) {
	const [ loading, setLoading ] = useState( '' );
	const [ page, setPage ] = useState( 1 );
	const [ perPage, setPerPage ] = useState( 10 );
	const [ search, setSearch ] = useState( '' );
	const [ user, setUser ] = useState( '' );
	const [ type, setType ] = useState( '' );
	const [ status, setStatus ] = useState( '' );

	const [ openUser, setOpenUser ] = useState( false );
	const [ searchUser, setSearchUser ] = useState( '' );
	const [ searchUserQuery, setSearchUserQuery ] = useState( '' );
	const [ listUsers, setListUsers ] = useState( [] );

	const [ notice, setNotice ] = useState( {
		type: '',
		message: '',
	} );

	const { data, error, isLoading } = useSWR(
		addQueryArgs(
			'/lp/notifications/v1/notifications',
			{
				per_page: perPage,
				page,
				search,
				user,
				type,
				status,
			}
		),
		( url: string ) => apiFetch( { path: url } )
	);

	const debounceFn = useCallback( debounce( ( searchInput ) => setSearchUserQuery( searchInput ), 600 ), [] );
	const matchMutate = useMatchMutate();

	useEffect( () => {
		( async () => {
			if ( ! searchUserQuery ) {
				return;
			}
			setLoading( 'fetchUsers' );

			const response = await apiFetch( { path: addQueryArgs( '/wp/v2/users', { search: searchUserQuery } ) } );

			// get all users id and name
			const users = response.map( ( user ) => ( {
				id: user.id,
				value: user.name,
				name: `#${ user.id } - ${ user.name }`,
			} ) );

			// add default user None to users
			users.unshift( {
				id: 0,
				value: '',
				name: __( '-- Defaut --' ),
			} );

			setListUsers( users );

			setLoading( '' );
		} )();
	}, [ searchUserQuery ] );

	useEffect( () => {
		// Hide snackbar after 3s.
		const timeout = setTimeout( () => {
			setNotice( { type: '', message: notice?.message || '' } );
		}, 3000 );

		return () => clearTimeout( timeout );
	}, [ notice ] );

	const deleteNotification = async ( id ) => {
		try {
			setLoading( 'delete' );

			const response = await apiFetch( {
				path: `/lp/notifications/v1/delete`,
				method: 'POST',
				data: {
					id,
				},
			} );

			if ( response?.success ) {
				setNotice( {
					type: 'delete',
					message: __( 'Notification deleted.' ),
				} );

				matchMutate( /^\/lp\/notifications\/v1\/notifications/ );
			} else {
				throw new Error( response?.message || __( 'Something went wrong.' ) );
			}
		} catch ( error ) {
			setNotice( {
				type: 'delete',
				message: error.message,
			} );
		} finally {
			setLoading( '' );
		}
	};

	const sendNotification = async ( id ) => {
		try {
			setLoading( 'send' );

			const response = await apiFetch( {
				path: `/lp/notifications/v1/send-notification`,
				method: 'POST',
				data: {
					id,
				},
			} );

			if ( response?.success ) {
				setNotice( {
					type: 'send',
					message: __( 'Notification sent.' ),
				} );

				matchMutate( /^\/lp\/notifications\/v1\/notifications/ );
			} else {
				throw new Error( response?.message || __( 'Something went wrong.' ) );
			}
		} catch ( error ) {
			setNotice( {
				type: 'send',
				message: error.message,
			} );
		} finally {
			setLoading( '' );
		}
	};

	return (
		<div>
			<div className="lp-push-notifications__filters">
				<div className="lp-push-notifications__filters__inner">
					<div>
						<Button
							className="lp-push-notifications__filters__inner__search"
							variant="secondary"
							onClick={ () => setOpenUser( ! openUser ) }
							style={ { height: 30, marginBottom: 8, minWidth: 200 } }
						>
							{ user || __( 'Search user…' ) }
						</Button>

						{ openUser && (
							<Popover
								position="bottom right"
								onClose={ () => setOpenUser( false ) }
							>
								<div style={ { padding: 10, minWidth: 200 } }>
									<TextControl
										value={ searchUser }
										placeholder={ __( 'Enter user name…' ) }
										onChange={ ( value ) => {
											setSearchUser( value );
											debounceFn( value );
										} }
									/>
								</div>

								<div style={ { padding: 10, minWidth: 240 } }>
									{ loading === 'fetchUsers' ? <Spinner /> : (
										<>
											{ listUsers.map( ( user ) => (
												<div
													key={ user.id }
													style={ {
														display: 'flex',
														gap: 5,
														alignItems: 'center',
														marginBottom: 5,
													} }
												>
													<Button
														variant="tertiary"
														style={ { height: 30, width: '100%' } }
														onClick={ () => {
															setUser( user.value || '' );
															setOpenUser( false );
														} }
													>
														{ user.name }
													</Button>
												</div>
											) ) }
										</>
									) }
								</div>
							</Popover>
						) }
					</div>

					<SelectControl
						value={ type }
						onChange={ ( value ) => setType( value ) }
						options={ [
							{ label: __( 'Type' ), value: '' },
							{ label: __( 'Marketing' ), value: 'marketing' },
							{ label: __( 'Information' ), value: 'info' },
							{ label: __( 'Update' ), value: 'update' },
							{ label: __( 'Warning' ), value: 'warning' },
						] }
					/>

					<SelectControl
						value={ status }
						onChange={ ( value ) => setStatus( value ) }
						options={ [
							{ label: __( 'Status' ), value: '' },
							{ label: __( 'Pending' ), value: 'pending' },
							{ label: __( 'Completed' ), value: 'completed' },
							{ label: __( 'Failed' ), value: 'failed' },
						] }
					/>
					{ ( user || status || type ) && (
						<Button
							variant="secondary"
							onClick={ () => {
								setUser( '' );
								setType( '' );
								setStatus( '' );
							} }
							style={ { height: 30, marginBottom: 8 } }
						>
							{ __( 'Clear all filters' ) }
						</Button>
					) }
				</div>
			</div>

			{ isLoading ? (
				<div className="lp-push-notifications__loading">
					<Spinner />
				</div>
			) : (
				<>
					{ error || ! data?.success ? (
						<Notice status="error">
							{ data?.message || __( 'Something went wrong.' ) }
						</Notice>
					) : (
						<>
							{ data?.data?.notifications?.length ? (
								<>
									<table className="wp-list-table widefat fixed striped">
										<thead>
											<tr>
												<th>{ __( 'Title' ) }</th>
												<th>{ __( 'Content' ) }</th>
												<th>{ __( 'Name' ) }</th>
												<th>{ __( 'Type' ) }</th>
												<th>{ __( 'Status' ) }</th>
												<th>{ __( 'Date reminder' ) }</th>
												<th>{ __( 'Actions' ) }</th>
											</tr>
										</thead>
										<tbody>
											{ data.data.notifications.map( ( notification ) => (
												<tr key={ notification.notification_id }>
													<td>{ notification.title }</td>
													<td>{ notification.content }</td>
													<td>{ notification.name }</td>
													<td>{ notification.type }</td>
													<td>{ notification.status }</td>
													<td>{ notification.date_reminder || '' }</td>
													<td>
														<div className="lp-push-notifications__actions">
															<Button
																variant="primary"
																style={ { height: 30 } }
																onClick={ () => {
																	setId( notification.notification_id );
																	setOpen( true );
																} }
															>
																{ __( 'Edit' ) }
															</Button>

															<Dropdown
																popoverProps={ { placement: 'bottom-end' } }
																renderToggle={ ( { isOpen, onToggle } ) => (
																	<Button
																		className="lp-push-notifications__actions__toggle"
																		variant="link"
																		onClick={ onToggle }
																	>
																		<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={ 1.5 } stroke="currentColor">
																			<path strokeLinecap="round" strokeLinejoin="round" d="M12 6v12m6-6H6" />
																		</svg>

																	</Button>
																) }
																renderContent={ () => (
																	<ul className="lp-push-notifications__actions__dropdown">
																		{ notification.status === 'pending' && (
																			<li>
																				<Button variant="tertiary" onClick={ () => sendNotification( notification.notification_id ) }>
																					{ loading === 'send' ? <Spinner style={ { height: 14, width: 14 } } /> : '' }
																					{ __( 'Send now' ) }
																				</Button>
																			</li>
																		) }
																		<li>
																			<Button
																				onClick={ () => deleteNotification( notification.notification_id ) }
																				variant="tertiary"
																				style={ { color: '#b91c1c' } }
																			>
																				{ loading === 'delete' ? <Spinner style={ { height: 14, width: 14 } } /> : '' }
																				{ __( 'Delete' ) }
																			</Button>
																		</li>
																	</ul>
																) }
															/>
														</div>
													</td>
												</tr>
											) ) }
										</tbody>
									</table>

									{ data?.data?.total && Math.ceil( data.data.total / perPage ) > 1 && (
										<div className="lp-push-notifications__pagination">
											<ReactPaginate
												pageCount={ Math.ceil( data.data.total / perPage ) }
												pageRangeDisplayed={ 3 }
												marginPagesDisplayed={ 2 }
												forcePage={ page - 1 }
												onPageChange={ ( { selected } ) => setPage( selected + 1 ) }
												previousLabel={ __( 'Prev' ) }
												nextLabel={ __( 'Next' ) }
												breakLabel={ '...' }
												containerClassName="pagination"
												pageClassName="page-numbers"
												previousClassName="prev page-numbers"
												nextClassName="next page-numbers"
												disabledClassName="disabled"
												activeClassName="current"
											/>
										</div>
									) }
								</>
							) : (
								<div className="lp-push-notifications__empty">
									<Notice status="error">
										{ __( 'No notifications found.' ) }
									</Notice>
								</div>
							) }

						</>
					) }
				</>
			) }
			<Snackbar
				className={ `lp-push-notifications__snackbar lp-push-notifications__snackbar--fixed ${ notice?.type && [ 'delete', 'send' ].includes( notice.type ) ? 'lp-push-notifications__snackbar--show' : '' }` }
				explicitDismiss
				onDismiss={ () => setNotice( { type: '', message: notice.message } ) }
				onRemove={ () => setNotice( { type: '', message: notice.message } ) }
				status={ notice?.type || 'success' }
			>
				{ notice?.message || '' }
			</Snackbar>
		</div>
	);
}
