import React, { useEffect, useMemo, useState } from 'react';
import { __ } from '@wordpress/i18n';
import { Box, Span } from '@chakra-ui/react';
import ListTable from '@QPComponents/ListTable';
import Search from '@QPComponents/Search';
import {
	capitalizeFirstLetter,
	plugin_root_url,
	route_path,
	useQuery,
} from '@QPUtils/helper';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';
import StatusOptions from '@QPComponents/StatusOptions';
import OptionMenu from '@QPComponents/OptionMenu';
import SnackbarAction from '@QPComponents/BulkAction/SnackbarAction';
import {
	fetchAllCertificates,
	moveCertificateToTrash,
	restoreCertificate,
	deleteCertificate,
	updateCertificate,
	updateCertificateCurrentPage,
	updateCertificateItemPerPage,
	makePrimaryCertificate,
} from '@QPRedux/Slices/certificateSlice/certificateSlice';

import './styles.scss';
import { fetchSettings } from '@QPRedux/Slices/settingsSlice/settingsSlice';

const statusArray = [
	{
		label: __( 'All', 'quizpress' ),
		value: 'all',
	},
	{
		label: __( 'Publish', 'quizpress' ),
		value: 'publish',
	},
	{
		label: __( 'Draft', 'quizpress' ),
		value: 'draft',
	},
	{
		label: __( 'Pending', 'quizpress' ),
		value: 'pending',
	},
	{
		label: __( 'Trash', 'quizpress' ),
		value: 'trash',
	},
];

const CertificateTable = () => {
	const certificates = useSelector( ( state ) => state.certificates );
	const settings = useSelector( ( state ) => state.settings.data );
	const [ dataFetchingStatus, setDataFetchingStatus ] = useState(
		! settings || ! certificates?.data ? true : false
	);
	const [ onSearchLoader, setOnSearchLoader ] = useState( false );
	const [ selectedItems, setSelectedItems ] = useState( [] );
	const [ snackbarOption, setSnackbarOption ] = useState( {} );
	const [ confirm, setConfirm ] = useState( false );
	const [ resetSelectedItems, setResetSelectedItems ] = useState( false );

	const dispatch = useDispatch();
	const navigate = useNavigate();

	const location = useQuery();
	const questionStatus = location.get( 'status' );
	const certificatePerPage = location.get( 'PerPage' ) ?? 10;
	const searchText = location.get( 'search' );
	const [ status, setStatus ] = useState(
		questionStatus ? questionStatus : 'all'
	);

	const handleNavigate = ( tableStatus = '', text = '' ) => {
		let url = `${ route_path }admin.php?page=quizpress-certificates`;

		const queryParams = [];

		if ( tableStatus && tableStatus !== 'null' && tableStatus !== 'all' ) {
			queryParams.push( `status=${ encodeURIComponent( tableStatus ) }` );
		}

		if ( text && text !== 'null' ) {
			queryParams.push( `search=${ encodeURIComponent( text ) }` );
		}

		if ( queryParams.length > 0 ) {
			url +=
				( url.includes( '?' ) ? '&' : '?' ) + queryParams.join( '&' );
		}

		navigate( url );
	};

	const publishAction =
		status !== 'trash'
			? [
					{
						suffix: 'trash',
						label: __( 'Trash', 'quizpress' ),
						onClick: () =>
							setSnackbarOption( {
								value: 'trash',
								message: __(
									'Are you sure, you want to move these item to trash!',
									'quizpress'
								),
							} ),
					},
			  ]
			: [];
	const trashAction =
		status === 'trash'
			? [
					{
						suffix: 'restore',
						label: __( 'Restore', 'quizpress' ),
						onClick: () =>
							setSnackbarOption( {
								value: 'restore',
								message: __(
									'Are you sure, you want to restore these items?',
									'quizpress'
								),
							} ),
					},
					{
						suffix: 'delete',
						label: __( 'Delete Permanently', 'quizpress' ),
						onClick: () =>
							setSnackbarOption( {
								value: 'delete',
								message: __(
									'Are you sure, you want to delete these items?',
									'quizpress'
								),
							} ),
					},
			  ]
			: [];

	const snackbarOptions = [ ...publishAction, ...trashAction ];

	const handleTableDataFetch = ( page = 1, perPage = 10 ) => {
		setDataFetchingStatus( true );
		dispatch(
			fetchAllCertificates( { status, page, per_page: perPage } )
		).finally( () => setDataFetchingStatus( false ) );
	};

	const handlePageChange = ( page = 1, perPage = 10 ) => {
		dispatch( updateCertificateCurrentPage( page ) );
		handleTableDataFetch( page, perPage );
	};

	const handleItemsPage = ( itemsPerPage = 10, page = 1 ) => {
		dispatch( updateCertificateItemPerPage( itemsPerPage ) );
		handleTableDataFetch( page, itemsPerPage );
		handleNavigate( status );
	};

	useEffect( () => {
		if ( Object.keys( settings ).length === 0 ) {
			dispatch( fetchSettings() ).then( () => handleTableDataFetch() );
		} else {
			handleTableDataFetch();
		}
	}, [] );

	const handleReset = () => {
		setSelectedItems( [] );
		setSnackbarOption( {} );
		setResetSelectedItems( true );
		setConfirm( false );
	};

	const snackbarActionHandler = ( option ) => {
		if ( status !== 'trash' && option === 'trash' ) {
			selectedItems.forEach( ( item ) => {
				dispatch( moveCertificateToTrash( item?.id ) );
			} );
			handleReset();
		} else if ( option === 'restore' ) {
			selectedItems.forEach( ( item ) => {
				dispatch( restoreCertificate( { ...item, status: 'draft' } ) );
			} );
			handleReset();
		} else {
			selectedItems.forEach( ( item ) => {
				dispatch( deleteCertificate( item?.id ) );
				handleReset();
			} );
		}
	};

	React.useMemo( () => {
		if ( confirm ) {
			snackbarActionHandler( snackbarOption.value );
		} else {
			handleReset();
		}
	}, [ confirm ] );

	useEffect( () => {
		handleNavigate( questionStatus, searchText );
	}, [ questionStatus, searchText ] );

	useEffect( () => {
		( async () => {
			if (
				! certificates.data.length ||
				( certificates.data && certificates.data.length <= 1 )
			) {
				setDataFetchingStatus( true );
				dispatch( fetchAllCertificates( { status } ) ).finally( () => {
					setDataFetchingStatus( false );
				} );
			}
		} )();
	}, [] );

	const restoreHandler = ( item ) => {
		// eslint-disable-next-line
        dispatch(restoreCertificate({ ...item, status: 'draft' }));
	};

	const deleteHandler = ( item ) => {
		// eslint-disable-next-line
        dispatch(deleteCertificate(item?.id));
	};

	const columns = [
		{
			name: __( 'Title', 'quizpress' ),
			cell: ( row ) => (
				<Span
					cursor="pointer"
					onClick={ () =>
						window.open(
							`${ route_path }post.php?post=${ row.id }&action=edit&ref=quizpress`,
							'_blank'
						)
					}
				>
					{ row?.title?.rendered }
				</Span>
			),
		},
		{
			name: __( 'Date', 'quizpress' ),
			cell: ( row ) => {
				return (
					<div className="quizpress-table-title-wrap">
						<span>
							{ moment( row.date ).format( 'MMM DD, YYYY' ) }
						</span>
						<br />
						<span className="quizpress-table-time">
							{ moment( row.date ).format( 'hh:mm A' ) }
						</span>
					</div>
				);
			},
		},
		{
			name: __( 'Author', 'quizpress' ),
			cell: ( row ) => (
				<span>{ capitalizeFirstLetter( row?.author_name ) }</span>
			),
		},
		{
			name: __( 'Primary', 'quizpress' ),
			cell: ( row ) => {
				const isPrimary =
					Number( row?.id ) ===
					Number( settings?.quizpress_primary_certificate_id );
				return (
					<span
						className={ `quizpress-${
							isPrimary ? 'success' : 'draft'
						}` }
					>
						{ isPrimary ? __( 'Primary', 'quizpress' ) : '---' }
					</span>
				);
			},
		},
		{
			name: __( 'Status', 'quizpress' ),
			cell: ( row ) => {
				const statusHandler = ( itemStatus ) => {
					if ( itemStatus === 'trash' ) {
						dispatch( moveCertificateToTrash( row?.id ) );
					} else {
						const data = {
							status: itemStatus,
							content: row?.content?.raw ?? '',
						};
						dispatch(
							updateCertificate( { ID: row.id, formData: data } )
						);
					}
				};

				const scheduleStatus = [
					{
						label: __( 'Draft', 'quizpress' ),
						value: 'draft',
					},
					{
						label: __( 'Pending', 'quizpress' ),
						value: 'pending',
					},
					{
						label: __( 'Trash', 'quizpress' ),
						value: 'trash',
					},
				];

				const restStatus =
					row.status !== 'future'
						? [
								{
									label: __( 'Published', 'quizpress' ),
									value: 'publish',
								},
						  ]
						: [];
				return (
					<StatusOptions
						value={ row?.status }
						options={ {
							items: [ ...scheduleStatus, ...restStatus ],
						} }
						onChangeHandler={ statusHandler }
					/>
				);
			},
		},
		{
			name: __( 'Action', 'quizpress' ),
			cell: ( row ) => {
				const publishedActions =
					row.status !== 'trash'
						? [
								{
									type: 'button',
									suffix: 'trash',
									label: __( 'Trash', 'quizpress' ),
									icon: (
										<span className="quizpress-icon quizpress-icon--trash" />
									),
									onClick: () =>
										dispatch(
											moveCertificateToTrash( row?.id )
										),
								},
						  ]
						: [];
				const trashActions =
					row.status === 'trash'
						? [
								{
									type: 'button',
									label: __( 'Restore', 'quizpress' ),
									icon: (
										<span className="quizpress-icon quizpress-icon--reset"></span>
									),
									onClick: () => restoreHandler( row ),
								},
								{
									type: 'button',
									suffix: 'trash',
									label: __( 'Delete', 'quizpress' ),
									icon: (
										<span className="quizpress-icon quizpress-icon--trash" />
									),
									onClick: () => deleteHandler( row ),
								},
						  ]
						: [];
				return (
					<div className="quizpress-table-item-control">
						<OptionMenu
							options={ [
								{
									type: 'button',
									label: __( 'Edit', 'quizpress' ),
									icon: (
										<span className="quizpress-icon quizpress-icon--square-pen" />
									),
									onClick: () => {
										window.open(
											`${ route_path }post.php?post=${ row.id }&action=edit&ref=quizpress`,
											'_blank'
										);
									},
								},
								{
									type: 'button',
									label: __( 'Make Primary', 'quizpress' ),
									icon: (
										<img
											className="quizpress-icon-slash"
											src={
												plugin_root_url +
												'assets/images/set_primary.svg'
											}
											alt={ __( 'disable', 'quizpress' ) }
										/>
									),
									hasBorder: true,
									onClick: () => {
										dispatch(
											makePrimaryCertificate( row.id )
										);
									},
								},
								...publishedActions,
								...trashActions,
							] }
						/>
					</div>
				);
			},
		},
	];

	const subHeaderComponentMemo = useMemo( () => {
		const searchHandler = ( value ) => {
			setOnSearchLoader( true );
			dispatch(
				fetchAllCertificates( {
					status: value,
					page: 1,
					per_page: certificatePerPage,
					search: value,
				} )
			).then( () => {
				setOnSearchLoader( false );
				handleNavigate( status, value );
			} );
		};
		const dataFetchHandler = ( itemStatus ) => {
			setDataFetchingStatus( true );
			handleNavigate( itemStatus );
			dispatch(
				fetchAllCertificates( {
					status: itemStatus,
					page: 1,
					per_page: certificatePerPage,
				} )
			).finally( () => {
				setDataFetchingStatus( false );
			} );
		};

		return (
			<>
				<div className="quizpress-table__sub-header-left">
					{ statusArray.map( ( item, index ) => (
						<span
							role="presentation"
							className={ `tab ${
								item?.value === status ? 'is-active' : ''
							} ` }
							key={ index }
							onClick={ () => {
								setStatus( item.value );
								dataFetchHandler( item.value );
							} }
						>
							{ item.label }
							{ item.total !== 0 && (
								<span className="tab--total">
									{ item.total }
								</span>
							) }
						</span>
					) ) }
				</div>
				<div className="quizpress-table-sub-header-actions-right">
					<Search
						placeholder={ __( 'Search Items', 'quizpress' ) }
						onSearchHandler={ searchHandler }
						defaultValue={ searchText ? searchText : '' }
					/>
				</div>
			</>
		);
	}, [ status ] );

	return (
		<>
			<Box className="quizpress-page-content">
				<ListTable
					key={ JSON.stringify( {
						certificates: certificates?.data.length,
						settings,
					} ) }
					columns={ columns }
					data={ certificates?.data ?? [] }
					showSubHeader={ true }
					subHeaderComponent={ subHeaderComponentMemo }
					isRowSelectable={ true }
					showColumnFilter={ false }
					noDataText={ __(
						'Please, create Certificate to see the available list here.',
						'quizpress'
					) }
					getSelectRowValue={ ( selectedRow ) => {
						setSelectedItems( selectedRow );
						setResetSelectedItems( false );
					} }
					showPagination={ Number( certificates?.totalItems ) >= 10 }
					onChangePage={ handlePageChange }
					onChangeItemsPerPage={ handleItemsPage }
					totalItems={ Number( certificates?.totalItems ) ?? 10 }
					totalRows={ certificates?.data.length }
					dataFetchingStatus={ dataFetchingStatus || onSearchLoader }
					resetSelected={ resetSelectedItems }
					rowsPerPage={ Number( certificates?.itemPerPage ) }
					currentPageNumber={
						Number( certificates?.currentPage ) ?? 1
					}
					suffix="quiz-certificate-table"
				/>
				{ selectedItems.length > 0 && (
					<SnackbarAction
						actionButtons={ snackbarOptions }
						itemsLength={ selectedItems?.length }
						confirmHandler={ setConfirm }
						isActionSelected={ snackbarOption }
						resetHandler={ handleReset }
					/>
				) }
			</Box>
		</>
	);
};

export default CertificateTable;
