import React, { useEffect, useMemo, useState } from 'react';
import { __ } from '@wordpress/i18n';
import TopBar from '@QPComponents/TopBar';
import QPLabel from '@QPComponents/Labels/QPLabel';
import { Box, Button, Flex } from '@chakra-ui/react';
import { primaryBtn } from '../../../../../assets/scss/chakra/recipe';
import ListTable from '@QPComponents/ListTable';
import Search from '@QPComponents/Search';
import {
	capitalizeFirstLetter,
	formatDateTime,
	hideHtmlTags,
	makeRequest,
	quizpress_nonce,
	route_path,
	sliceString,
	useQuery,
} from '@QPUtils/helper';
import { useDispatch, useSelector } from 'react-redux';
import { Link, useNavigate } from 'react-router-dom';
import {
	deleteQuestion,
	fetchQuestions,
	importQuestions,
	moveQuestionTrash,
	restoreQuestion,
	updateQuestion,
	updateQuestionCurrentPage,
	updateQuestionItemPerPage,
} from '@QPRedux/Slices/quizQuestionSlice/quizQuestionSlice';
import StatusOptions from '@QPComponents/StatusOptions';
import OptionMenu from '@QPComponents/OptionMenu';
import SnackbarAction from '@QPComponents/BulkAction/SnackbarAction';
import { showNotification } from '@QPRedux/Slices/notificationSlice/notificationSlice';
import QuestionsImporter from '@QPComponents/QPImporters/QuestionsImporter';
import QPTooltip from '@QPComponents/QPTooltip';

import './styles/questionTable.scss';

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 Question = () => {
	const questions = useSelector( ( state ) => state.questions );
	const [ dataFetchingStatus, setDataFetchingStatus ] = useState( 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 [ openImportModal, setOpenImportModal ] = useState( false );

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

	const location = useQuery();
	const questionStatus = location.get( 'status' );
	const questionPerPage = 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-question`;

		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 handleReset = () => {
		setSelectedItems( [] );
		setSnackbarOption( {} );
		setResetSelectedItems( true );
		setConfirm( false );
	};

	const snackbarActionHandler = ( option ) => {
		if ( status !== 'trash' && option === 'trash' ) {
			selectedItems.forEach( ( item ) => {
				dispatch( moveQuestionTrash( item.question_id ) );
			} );
			handleReset();
		} else if ( option === 'restore' ) {
			selectedItems.forEach( ( item ) => {
				dispatch( restoreQuestion( item ) );
			} );
			handleReset();
		} else {
			selectedItems.forEach( ( item ) => {
				dispatch( deleteQuestion( item.question_id ) );
				handleReset();
			} );
		}
	};

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

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

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

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

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

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

	const restoreHandler = ( item ) => {
		// eslint-disable-next-line
		dispatch(restoreQuestion(item));
	};

	const deleteHandler = ( item ) => {
		// eslint-disable-next-line
		dispatch(deleteQuestion(item.question_id));
	};

	const columns = [
		{
			name: __( 'ID', 'quizpress' ),
			cell: ( row ) => {
				return (
					<div className="quizpress-table-id">
						<span>{ row.question_id }</span>
					</div>
				);
			},
		},
		{
			name: __( 'Title', 'quizpress' ),
			cell: ( row ) => {
				return (
					<div className="quizpress-table-title-wrap">
						<div className="quizpress-table-title">
							<Link
								to={ `${ route_path }admin.php?page=quizpress-question&path=question&action=edit&id=${ row.question_id }` }
							>
								<span
									className="quizpress-table-title quizpress-tooltip"
									data-tooltip={ sliceString(
										hideHtmlTags(
											row.question_title ??
												row.title?.rendered
										),
										80
									) }
									dangerouslySetInnerHTML={ {
										__html: sliceString(
											row.question_title ??
												row.title?.rendered
										),
									} }
								></span>
							</Link>
						</div>
					</div>
				);
			},
		},
		{
			name: __( 'Ans Count', 'quizpress' ),
			cell: ( row ) => <span>{ row?.total_answers }</span>,
		},
		{
			name: __( 'Type', 'quizpress' ),
			cell: ( row ) => (
				<span>{ capitalizeFirstLetter( row?.question_type ) }</span>
			),
		},
		{
			name: __( 'Last Modified', 'quizpress' ),
			cell: ( row ) => (
				<div>
					<span>
						{ formatDateTime( row.modified, 'MMM DD, YYYY' ) }
					</span>
					<br />
					<span className="quizpress-table-time">
						{ formatDateTime( row.modified, 'hh:mm A' ) }
					</span>
				</div>
			),
		},
		{
			name: __( 'Status', 'quizpress' ),
			cell: ( row ) => {
				const questionStatusHandler = ( itemStatus ) => {
					// eslint-disable-next-line

					if ( itemStatus === 'trash' ) {
						dispatch( moveQuestionTrash( row.question_id ) );
					} else {
						dispatch(
							updateQuestion( {
								...row,
								question_status: itemStatus,
							} )
						);
					}
				};

				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?.question_status }
						options={ {
							items: [ ...scheduleStatus, ...restStatus ],
						} }
						onChangeHandler={ questionStatusHandler }
					/>
				);
			},
		},
		{
			name: __( 'Action', 'quizpress' ),
			cell: ( row ) => {
				const publishedActions =
					row.question_status !== 'trash'
						? [
								{
									type: 'button',
									suffix: 'trash',
									label: __( 'Trash', 'quizpress' ),
									icon: (
										<span className="quizpress-icon quizpress-icon--trash" />
									),
									onClick: () =>
										dispatch(
											moveQuestionTrash( row.question_id )
										),
								},
						  ]
						: [];
				const trashActions =
					row.question_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: () => {
										navigate(
											`${ route_path }admin.php?page=quizpress-question&path=question&action=edit&id=${ row.question_id }`
										);
									},
								},
								...publishedActions,
								...trashActions,
							] }
						/>
					</div>
				);
			},
		},
	];

	const handleImportQstCSV = ( values, actions ) => {
		if ( ! values?.upload_file ) {
			dispatch(
				showNotification( {
					message: __( 'Please select a file.', 'quizpress' ),
					isShow: true,
					type: 'error',
				} )
			);
			actions.setSubmitting( false );
			return;
		}

		makeRequest( 'import_quiz', { upload_file: values.upload_file }, true )
			.then( ( res ) => {
				if ( ! res?.length ) {
					dispatch(
						showNotification( {
							message: __(
								'Unable to import questions. Something went wrong.',
								'quizpress'
							),
							isShow: true,
							type: 'error',
						} )
					);
					actions.setSubmitting( false );
					return;
				}

				dispatch( importQuestions( res ) );
				dispatch(
					showNotification( {
						message: __(
							'Questions imported successfully.',
							'quizpress'
						),
						isShow: true,
						type: 'success',
					} )
				);
			} )
			.finally( () => {
				setOpenImportModal( false );
				actions.setSubmitting( false );
			} );
	};

	const subHeaderComponentMemo = useMemo( () => {
		const searchHandler = ( value ) => {
			setOnSearchLoader( true );
			dispatch(
				fetchQuestions( {
					question_status: value,
					page: 1,
					per_page: questionPerPage,
					search: value,
				} )
			).then( () => {
				setOnSearchLoader( false );
				handleNavigate( status, value );
			} );
		};
		const dataFetchHandler = ( itemStatus ) => {
			setDataFetchingStatus( true );
			handleNavigate( itemStatus );
			dispatch(
				fetchQuestions( {
					status: itemStatus,
					page: 1,
					per_page: questionPerPage,
				} )
			).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 className="quizpress-table-sub-header-actions-right--border-double" />

					<Flex gap="12px">
						<QPTooltip
							content={ __(
								'CSV Questions Import',
								'quizpress'
							) }
							noWrap={ true }
						>
							<Button
								height="36px"
								variant="outline"
								borderColor="var(--quizpress-primary)"
								onClick={ () => {
									setOpenImportModal( true );
								} }
							>
								<span className="quizpress-icon quizpress-icon--file-import" />
							</Button>
						</QPTooltip>

						<QPTooltip
							content={ __(
								'CSV Questions Export',
								'quizpress'
							) }
							noWrap={ true }
							position="left"
						>
							<Button
								height="36px"
								variant="outline"
								borderColor="var(--quizpress-primary)"
								onClick={ () => {
									window.location.href = `admin.php?page=quizpress-question&exportType=questions&security=${ quizpress_nonce }`;
								} }
							>
								<span className="quizpress-icon quizpress-icon--file-export" />
							</Button>
						</QPTooltip>
					</Flex>
				</div>
			</>
		);
	}, [ status ] );

	return (
		<>
			<TopBar
				leftContent={ () => (
					<>
						<span className="quizpress-topbar-logo quizpress-icon quizpress-icon--quizpress" />
						<span className="quizpress-icon quizpress-icon--angle-right quizpress-muted" />
						<QPLabel
							as="h2"
							color="#4F46E5"
							type="subtitle"
							fontWeight="medium"
							label={ __( 'Questions', 'quizpress' ) }
						/>
					</>
				) }
				rightContent={ () => (
					<Button
						{ ...primaryBtn }
						onClick={ () =>
							navigate(
								`${ route_path }admin.php?page=quizpress-question&action=add`
							)
						}
					>
						{ __( 'Create New', 'quizpress' ) }
						<span className="quizpress-icon quizpress-icon--plus has-quizpress-blue-bg" />
					</Button>
				) }
			/>
			<Box className="quizpress-page-content">
				<ListTable
					key={ `question-${ questions?.data?.length }` }
					columns={ columns }
					data={ questions?.data ?? [] }
					showSubHeader={ true }
					subHeaderComponent={ subHeaderComponentMemo }
					isRowSelectable={ true }
					showColumnFilter={ false }
					noDataText={ __(
						'Please, create Question to see the available list here.',
						'quizpress'
					) }
					getSelectRowValue={ ( selectedRow ) => {
						setSelectedItems( selectedRow );
						setResetSelectedItems( false );
					} }
					showPagination={ Number( questions?.totalItems ) >= 10 }
					onChangePage={ handlePageChange }
					onChangeItemsPerPage={ handleItemsPage }
					totalItems={ Number( questions?.totalItems ) ?? 10 }
					totalRows={ questions?.data.length }
					dataFetchingStatus={ dataFetchingStatus || onSearchLoader }
					resetSelected={ resetSelectedItems }
					rowsPerPage={ Number( questions?.itemPerPage ) }
					currentPageNumber={ Number( questions?.currentPage ) ?? 1 }
					suffix="quiz-question-table"
				/>
				{ selectedItems.length > 0 && (
					<SnackbarAction
						actionButtons={ snackbarOptions }
						itemsLength={ selectedItems?.length }
						confirmHandler={ setConfirm }
						isActionSelected={ snackbarOption }
						resetHandler={ handleReset }
					/>
				) }
				{ openImportModal && (
					<QuestionsImporter
						isOpen={ openImportModal }
						onClose={ () => setOpenImportModal( false ) }
						handleSubmit={ handleImportQstCSV }
					/>
				) }
			</Box>
		</>
	);
};

export default Question;
