import { __ } from '@wordpress/i18n';
import apiFetch from '@wordpress/api-fetch';
import { addQueryArgs, isURL } from '@wordpress/url';
import { debounce } from 'lodash';
import { useState, useEffect, useCallback } from '@wordpress/element';
import { SelectControl, Button, TextControl, Modal, TextareaControl, Dropdown, TimePicker, BaseControl, Popover, Spinner, SlotFillProvider, Snackbar, Notice, CheckboxControl } from '@wordpress/components';
import { MediaUpload } from '@wordpress/media-utils';
import { useMatchMutate } from './utils';

export default function Edit( { id, isOpen, setOpen } ) {
	const [ name, setName ] = useState( '' );
	const [ title, setTitle ] = useState( '' );
	const [ content, setContent ] = useState( '' );
	const [ media, setMedia ] = useState( '' );
	const [ type, setType ] = useState( 'marketing' );
	const [ source, setSource ] = useState( '' );
	const [ reminder, setRemainder ] = useState( '' );
	const [ openUser, setOpenUser ] = useState( false );
	const [ searchUser, setSearchUser ] = useState( '' );
	const [ searchUserQuery, setSearchUserQuery ] = useState( '' );
	const [ listUsers, setListUsers ] = useState( [] );
	const [ receivers, setReceivers ] = useState( [] );
	const [ status, setStatus ] = useState( '' );
	const [ isSend, setIsSend ] = useState( false );
	const [ platform, setPlatform ] = useState( '' );

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

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

	useEffect( () => {
		async function fetchNotification() {
			if ( ! id ) {
				return;
			}

			try {
				setLoading( 'fetchNotification' );

				const response = await apiFetch( { path: `/lp/notifications/v1/notifications/${ id }` } );

				if ( ! response.success ) {
					throw new Error( response?.message || __( 'Something went wrong!' ) );
				}

				setName( response?.data?.name || '' );
				setTitle( response?.data?.title || '' );
				setContent( response?.data?.content || '' );
				setMedia( response?.data?.image || '' );
				setType( response?.data?.type || 'marketing' );
				setSource( response?.data?.source || '' );
				setRemainder( response?.data?.date_reminder || '' );
				setReceivers( response?.data?.receivers || [] );
				setStatus( response?.data?.status || '' );
			} catch ( error ) {
				setNotice( {
					message: error?.message || __( 'Something went wrong!' ),
					type: 'fetch',
				} );
			} finally {
				setLoading( '' );
			}
		}

		fetchNotification();
	}, [ id ] );

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

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

			setListUsers( response );
			setLoading( '' );
		}

		fetchUsers();
	}, [ searchUserQuery ] );

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

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

	const saveNotification = async () => {
		try {
			setLoading( 'saveNotification' );

			const data = {
				id,
				name,
				title,
				content,
				media,
				type,
				source,
				reminder,
				receivers,
			};

			// Check valid URL media.
			if ( media && ! isURL( media ) ) {
				throw new Error( __( 'Invalid image URL!' ) );
			}

			if ( ! id || status === 'pending' ) {
				data.isSend = isSend;
			}

			const response = await apiFetch( {
				path: '/lp/notifications/v1/save-notifications',
				method: 'POST',
				headers: {
					'Content-Type': 'application/json',
					'x-platform': platform || '',
				},
				data,
			} );

			if ( response?.success ) {
				setNotice( {
					message: __( 'Notification saved!' ),
					type: 'toast',
				} );
				setTimeout( () => {
					setOpen( false );
				}, 1000 );

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

	return (
		<SlotFillProvider>
			<Modal
				title={ __( 'Add new Notification' ) }
				style={ { minWidth: 1000 } }
				onRequestClose={ ( event ) => {
					// if is has class name notification-upload-media
					// then do not close modal
					if ( event.target.tagName.toLowerCase() === 'button' && event.target.className.includes( 'notification-upload-media' ) ) {
						return;
					}

					if ( event.target.tagName.toLowerCase() === 'span' && event.target.className.includes( 'components-snackbar__dismiss-button' ) ) {
						return;
					}

					setOpen( ! isOpen );
				} }
			>
				{ loading === 'fetchNotification' ? <Spinner /> : (
					<>
						{ notice?.type === 'fetch' ? (
							<Notice status="error">
								{ notice?.message || '' }
							</Notice>
						) : (
							<>
								<div style={ { display: 'flex', gap: 20 } }>
									<div style={ { flex: 1, display: 'flex', flexDirection: 'column', gap: 5 } }>
										<TextControl
											value={ name }
											label={ __( 'Name' ) }
											placeholder={ 'lp_broadcast_1' }
											onChange={ ( value ) => setName( value ) }
										/>
										<TextControl
											value={ title }
											label={ __( 'Title' ) }
											placeholder={ __( 'Enter title…' ) }
											onChange={ ( value ) => setTitle( value ) }
										/>
										<TextareaControl
											rows={ 6 }
											value={ content }
											label={ __( 'Content *' ) }
											placeholder={ __( 'Enter content…' ) }
											onChange={ ( value ) => setContent( value ) }
										/>
									</div>
									<div style={ { flex: 1, display: 'flex', flexDirection: 'column', gap: 5 } }>
										<div style={ { display: 'flex', gap: 5, alignItems: 'flex-end' } }>
											<TextControl
												label={ __( 'Image' ) }
												placeholder={ __( 'Enter image URL…' ) }
												type="url"
												value={ media || '' }
												onChange={ ( value ) => setMedia( value ) }
											/>
											<MediaUpload
												onSelect={ ( mediaUpload ) => setMedia( mediaUpload.url ) }
												value={ '' }
												allowedTypes={ [ 'image' ] }
												render={ ( { open } ) => (
													<Button
														className="notification-upload-media"
														variant="primary"
														onClick={ open }
														style={ { height: 30, marginBottom: 8 } }
													>
														{ __( 'Upload' ) }
													</Button>
												) }
											/>
										</div>
										<SelectControl
											value={ type }
											label={ __( 'Type' ) }
											options={ [
												{ label: __( 'Marketing' ), value: 'marketing' },
												{ label: __( 'Information' ), value: 'info' },
												{ label: __( 'Update' ), value: 'update' },
												{ label: __( 'Warning' ), value: 'warning' },
											] }
											onChange={ ( value ) => setType( value ) }
										/>
										<TextControl
											value={ source }
											label={ __( 'Link' ) }
											placeholder={ __( 'Enter link URL…' ) }
											type="url"
											onChange={ ( value ) => setSource( value ) }
											help={ __( 'Use Deep Link: edumaapp://courses/[course_id] to open course detail in app.' ) }
										/>
										<div>
											<BaseControl id="" label={ __( 'Date Reminder' ) }>
												<div style={ { display: 'flex', gap: 5, alignItems: 'center' } }>
													<input
														className="components-text-control__input"
														readOnly
														value={
															reminder ? reminder.replace( /T/, ' ' ).replace( /\..+/, '' ) : ''
														}
													/>
													<Dropdown
														popoverProps={ { placement: 'bottom-end' } }
														renderToggle={ ( { isOpen, onToggle } ) => (
															<Button
																variant="primary"
																onClick={ onToggle }
																aria-expanded={ isOpen }
																style={ { height: 30 } }
															>
																{ __( 'Choose date' ) }
															</Button>
														) }
														renderContent={ () => (
															<div style={ { padding: 10, minWidth: 240 } }>
																<TimePicker
																	currentTime={ reminder }
																	onChange={ ( newDate ) => setRemainder( newDate ) }
																/>
																<Button
																	disabled={ ! reminder }
																	variant="secondary"
																	onClick={ () => {
																		setRemainder( '' );
																	} }
																	style={ { height: 30, marginTop: 20 } }
																>
																	{ __( 'Clear' ) }
																</Button>
															</div>
														) }
													/>
												</div>
											</BaseControl>
										</div>
									</div>
								</div>
								<div>
									<BaseControl label={ __( 'Receivers' ) }>
										<div>
											{ receivers.map( ( receiver, index ) => (
												<div key={ index } style={ { display: 'flex', gap: 5, alignItems: 'center' } }>
													<div style={ { flex: 1 } }>
														<SelectControl
															value={ receiver.comparison }
															options={ [
																{ label: __( 'Include' ), value: 'include' },
																{ label: __( 'Exclude' ), value: 'exclude' },
															] }
															onChange={ ( newComparison ) => {
																const newReceiver = [ ...receivers ];
																newReceiver[ index ].comparison = newComparison;

																setReceivers( newReceiver );
															} }
														/>
													</div>

													<div style={ { flex: 1 } }>
														<SelectControl
															value={ receiver.type }
															options={ [
																{ label: __( 'All users' ), value: 'all' },
																{ label: __( 'Role' ), value: 'role' },
																{ label: __( 'Select user' ), value: 'user' },
															] }
															onChange={ ( newType ) => {
																const newReceiver = [ ...receivers ];
																newReceiver[ index ].type = newType;

																if ( newType === 'all' ) {
																	newReceiver[ index ].value = '';
																}

																setReceivers( newReceiver );
															} }
														/>
													</div>

													{ receiver.type === 'role' && (
														<div style={ { flex: 1 } }>
															<SelectControl
																value={ receiver.value }
																options={ [
																	{ label: __( 'Administrator' ), value: 'administrator' },
																	{ label: __( 'Instructor' ), value: 'lp_teacher' },
																	{ label: __( 'Student' ), value: 'subscriber' },
																] }
																onChange={ ( newValue ) => {
																	const newReceiver = [ ...receivers ];
																	newReceiver[ index ].value = newValue;

																	setReceivers( newReceiver );
																} }
															/>
														</div>
													) }
													{ receiver.type === 'user' && (
														<div style={ { flex: 1 } }>
															<Dropdown
																popoverProps={ { placement: 'bottom-start' } }
																renderToggle={ ( { isOpen, onToggle } ) => (
																	<Button
																		variant="secondary"
																		onClick={ () => {
																			setSearchUser( '' );
																			setSearchUserQuery( '' );
																			setListUsers( [] );
																			onToggle();
																		} }
																		aria-expanded={ isOpen }
																		style={ { height: 30, marginBottom: 8, minWidth: 240 } }
																	>
																		{ receiver?.value || __( 'Select user' ) }
																	</Button>

																) }
																renderContent={ () => (
																	<>
																		<div style={ { padding: 10, minWidth: 240 } }>
																			<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={ () => {
																									const newReceiver = [ ...receivers ];
																									newReceiver[ index ].value = user.name;

																									setReceivers( newReceiver );
																									setOpenUser( false );
																								} }
																							>
																								{ user.name }
																							</Button>
																						</div>
																					) ) }
																				</>
																			) }
																		</div>
																	</>
																) }
															/>
														</div>
													) }
													<Button
														variant="secondary"
														style={ { height: 30, marginBottom: 8 } }
														label="Remove"
														showTooltip
														onClick={ () => (
															setReceivers( receivers.filter( ( _, i ) => i !== index ) )
														) }
													>
														<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={ 1.5 } stroke="currentColor" style={ { width: 18, height: 18 } }>
															<path strokeLinecap="round" strokeLinejoin="round" d="M6 18L18 6M6 6l12 12" />
														</svg>
													</Button>
												</div>
											) ) }
											<Button variant="primary" style={ { height: 30 } } onClick={ () => setReceivers(
												[
													...receivers,
													{
														comparison: 'include',
														type: 'all',
														value: '',
													},
												]
											) }>
												<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" strokeWidth={ 1.5 } stroke="currentColor" style={ { width: 16, height: 16 } }>
													<path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
												</svg>

												{ __( 'Add' ) }
											</Button>
										</div>
									</BaseControl>
								</div>
							</>
						) }
					</>
				) }

				{ ( ! id || status === 'pending' ) && ! reminder && (
					<>
						<div style={ { display: 'flex', alignItems: 'center', marginTop: 20 } }>
							<CheckboxControl
								label={ __( 'Send push notification to all receivers.' ) }
								checked={ isSend }
								onChange={ () => setIsSend( ! isSend ) }
							/>
						</div>
						{ learnpressPushNotificationsSettings?.isMutilPlatform && (
							<div style={ { width: 300, marginTop: 10 } }>
								<SelectControl
									value={ platform }
									label={ __( 'Platform' ) }
									options={ [
										{ label: __( 'React Native' ), value: '' },
										{ label: __( 'Flutter' ), value: 'flutter' },
									] }
									onChange={ ( value ) => setPlatform( value ) }
								/>
							</div>
						) }
					</>
				) }

				<div style={ { display: 'flex', gap: 10, marginTop: 20 } }>
					<Button variant="primary" onClick={ saveNotification } disabled={ loading === 'saveNotification' }>
						{ loading === 'saveNotification' && <Spinner /> }
						{ __( 'Save' ) }
					</Button>

					<Button variant="secondary" onClick={ () => setOpen( ! isOpen ) }>
						{ __( 'Close' ) }
					</Button>
				</div>

				<Snackbar
					className={ `lp-push-notifications__snackbar ${ notice?.type === 'toast' ? '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>
			</Modal >
			<Popover.Slot />
		</SlotFillProvider>
	);
}
