import React, { useEffect, useState, useSyncExternalStore } from 'react';
import { __, sprintf } from '@wordpress/i18n';
import {
	Button,
	Flex,
	Input,
	Span,
	Text,
	Textarea,
	Menu,
	Portal,
	Collapsible,
} from '@chakra-ui/react';
import { Field, useFormikContext } from 'formik';
import QuestionSettings from './QuestionSettings';
import { questionTypeOptions } from '@QPUtils/helper';
import { primaryBtn } from '../../../../../../../assets/scss/chakra/recipe';
import Select from 'react-select';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import SingleChoiceText from '@QPComponents/RenderAnswers/SingleChoiceText';
import SingleChoiceRich from '@QPComponents/RenderAnswers/SingleChoiceRich';
import ImageAnswer from '@QPComponents/RenderAnswers/ImageAnswer';
import ImageTextAnswer from '@QPComponents/RenderAnswers/ImageTextAnswer';
import OptIn from '@QPComponents/RenderAnswers/OptIn';
import TrueFalse from '@QPComponents/RenderAnswers/TrueFalse';
import { isEqual, omit } from 'lodash';
import { useDispatch } from 'react-redux';
import { updateQuiz } from '@QPRedux/Slices/quizSlice/quizSlice';
import { toggleStore } from '../helper';
import ReadOnlyBlank from '@QPComponents/RenderAnswers/ReadOnlyBlank';

const QuizQuestions = ( {
	index,
	setCurrentIndex,
	toggleOpen,
	quizValues,
	quizSaveHandler,
} ) => {
	const {
		attributes,
		listeners,
		setNodeRef,
		transform,
		transition,
		isDragging,
	} = useSortable( { id: `qst-${ index }` } );
	const { setFieldValue, handleSubmit, isSubmitting, values } =
		useFormikContext();
	const [ showDescription, isShowDescription ] = useState(
		Boolean( values?.question_content ) ?? false
	);
	const [ showExplanation, isShowExplanation ] = useState(
		Boolean( values?.question_explanation ) ?? false
	);
	const dispatch = useDispatch();

	const currentUnchangedQst =
		quizValues?.questions?.find(
			( qst ) =>
				Number( qst.question_id ) === Number( values?.question_id )
		) ?? {};
	const isQstChanged = ! isEqual(
		omit( values, [ 'question_order', '_globalIndex' ] ),
		omit( currentUnchangedQst, 'question_order' )
	);

	//#7eb4ff --> for disabled primary btn bg color

	const questionType = values?.question_type;
	const answerType = values?.answer_type;

	const answerTypeOptions = [
		...( questionType === 'fill_in_the_blanks'
			? [
					{
						label: __( 'ReadOnly', 'quizpress' ),
						value: 'read_only',
					},
					{
						label: __( 'Sequent (coming soon)', 'quizpress' ),
						value: 'sequent',
						isDisabled: true,
					},
			  ]
			: questionType === 'drop_down'
			? [
					{
						label: __( 'Plain Text', 'quizpress' ),
						value: 'plain_text',
					},
			  ]
			: [
					{
						label: __( 'Plain Text', 'quizpress' ),
						value: 'plain_text',
					},
					{
						label: __( 'Rich Text', 'quizpress' ),
						value: 'rich_text',
					},
					{ label: __( 'Image', 'quizpress' ), value: 'image' },
					{
						label: __( 'Image & Text', 'quizpress' ),
						value: 'image_and_text',
					},
			  ] ),
	];

	const category = 'World cup quiz'; //todo: remove this after redux and category implementation

	const ansName = `answers`;
	const ansVal = values?.answers || [];

	const renderSwitchQuestionType = ( questionType ) => {
		switch ( questionType ) {
			case 'single_choice':
			case 'multiple_choice':
			case 'multiple_choice_horizontal':
			case 'single_choice_horizontal':
			case 'drop_down':
				if ( answerType === 'plain_text' ) {
					return (
						<SingleChoiceText
							ansName={ ansName }
							ansVal={ ansVal }
							type={ questionType }
						/>
					);
				}
				if ( answerType === 'rich_text' ) {
					return (
						<SingleChoiceRich
							ansName={ ansName }
							ansVal={ ansVal }
							type={ questionType }
						/>
					);
				}
				if ( answerType === 'image' ) {
					return (
						<ImageAnswer
							ansName={ ansName }
							ansVal={ ansVal }
							type={ questionType }
						/>
					);
				}
				if ( answerType === 'image_and_text' ) {
					return (
						<ImageTextAnswer
							ansName={ ansName }
							ansVal={ ansVal }
							type={ questionType }
						/>
					);
				}
				break;
			case 'opt_in':
			case 'date':
			case 'paragraph':
			case 'short_answer':
			case 'number':
			case 'file_upload':
				return (
					<OptIn
						type={ questionType }
						ansName={ ansName }
						ansVal={ ansVal }
					/>
				);
			case 'fill_in_the_blanks':
				if ( answerType === 'read_only' ) {
					return (
						<ReadOnlyBlank
							ansName={ ansName }
							ansVal={ ansVal }
							qstVal={ values }
						/>
					);
				}
			// if ( answerType === 'sequent' ) {
			// 	return <SequentBlanks ansName={ansName} ansVal={ansVal} qstVal={ values }/>;
			// }
			case 'true_false':
				return (
					<TrueFalse
						ansName={ ansName }
						ansVal={ ansVal }
						qstVal={ values }
					/>
				);
			// case 'checkbox_grid':
			// case 'radio_grid':
			// 	return <GridRowColumn ansName={ansName} ansVal={ansVal} />;
		}
	};

	useEffect( () => {
		setCurrentIndex( index );
	}, [] );

	const isOpen = useSyncExternalStore( toggleStore.subscribe, () =>
		toggleStore.isOpen( quizValues.id, `qst-${ index }` )
	);

	const isShowAnsOptions =
		questionType === 'single_choice' ||
		questionType === 'multiple_choice' ||
		questionType === 'multiple_choice_horizontal' ||
		questionType === 'single_choice_horizontal' ||
		questionType === 'drop_down' ||
		questionType === 'file_upload' ||
		questionType === 'fill_in_the_blanks';

	const currentAnsType =
		answerTypeOptions.find( ( item ) => item.value === answerType ) ?? '';

	const currentQstType = questionTypeOptions
		.flatMap( ( item ) => item.options )
		.find( ( item ) => item.value === questionType );

	const removeQst = ( index ) => {
		const shallowCopy = [ ...quizValues?.questions ];
		const filteredQsts = shallowCopy.filter( ( item, i ) => i !== index );

		dispatch(
			updateQuiz( {
				params: {
					...quizValues,
					meta: {
						...quizValues?.meta,
						quizpress_quiz_questions: filteredQsts.map(
							( item, i ) => ( {
								id: item.question_id,
								title: item.question_title,
							} )
						),
					},
				},
				questions: filteredQsts,
			} )
		);

		quizSaveHandler( 'questions', filteredQsts );
		toggleStore.updateStore( quizValues.id, index, 'delete' );
	};

	return (
		<Flex
			direction="column"
			width="100%"
			ref={ setNodeRef }
			style={ {
				transform: CSS.Transform.toString( transform ),
				transition,
				opacity: isDragging ? 0.5 : 1,
			} }
		>
			<Collapsible.Root
				display="flex"
				flexDirection="column"
				open={ isOpen }
			>
				<Collapsible.Trigger
					as={ Flex }
					bg="var(--quizpress-background)"
					width="full"
					p={ 3 }
					borderRadius={ ! isOpen ? '4px' : '4px 4px 0 0' }
					boxShadow="var(--quizpress-shadow)"
					alignItems="center"
					justifyContent="space-between"
					cursor="pointer"
					onClick={ ( e ) => {
						e.stopPropagation();
						toggleOpen( `qst-${ index }` );
					} }
				>
					<Flex gap={ 3 } alignItems="center">
						<Button
							{ ...attributes }
							{ ...listeners }
							variant="ghost"
							onClick={ ( e ) => {
								e.stopPropagation();
							} }
						>
							<Span className="quizpress-icon quizpress-icon--move" />
						</Button>
						<Flex direction="column" gap={ 1 }>
							<Text
								fontSize="1rem"
								fontWeight="600"
								m={ 0 }
								color="var(--quizpress-primary)"
							>
								{ ! values.question_title
									? __( 'Untitled Question', 'quizpress' )
									: sprintf(
											//translate: %s question title
											__( '%s', 'quizpress' ),
											values.question_title
									  ) }
							</Text>
							{ ! isOpen && (
								<Flex alignItems="center" gap={ 4 }>
									<Text className="quizpress-sub-title-muted">
										{ sprintf(
											//translate: %s question type
											__(
												'Question Type: %s',
												'quizpress'
											),
											currentQstType?.label
										) }
									</Text>
									{ currentAnsType && (
										<Text className="quizpress-sub-title-muted">
											{ sprintf(
												//translate: %s answer type
												__(
													'Answer Type: %s',
													'quizpress'
												),
												currentAnsType?.label
											) }
										</Text>
									) }
								</Flex>
							) }
						</Flex>
					</Flex>

					<Flex gap={ 3 } alignItems="center">
						{ isOpen ? (
							<Button
								{ ...primaryBtn }
								disabled={ ! isQstChanged || isSubmitting }
								loading={ isSubmitting }
								onClick={ ( e ) => {
									e.stopPropagation();
									handleSubmit();
								} }
							>
								{ __( 'Save', 'quizpress' ) }
							</Button>
						) : (
							<Span className="quizpress-icon quizpress-icon--square-pen" />
						) }
						<Menu.Root
							closeOnSelect={ false }
							positioning={ {
								placement: 'left-start',
								gutter: 4,
							} }
						>
							<Menu.Trigger asChild>
								<Span
									onClick={ ( e ) => e.stopPropagation() }
									cursor="pointer"
									className="quizpress-icon quizpress-icon--menu-vertical"
								/>
							</Menu.Trigger>

							<Portal>
								<Menu.Positioner>
									<Menu.Content>
										<Menu.Item
											value="Edit"
											onClick={ ( e ) => {
												e.stopPropagation();
												toggleOpen( `qst-${ index }` );
											} }
											closeOnSelect={ false }
										>
											<Span className="quizpress-icon quizpress-icon--square-pen" />
											{ __( 'Edit', 'quizpress' ) }
										</Menu.Item>

										<Menu.Item
											color="#FF4D4D"
											value="Remove"
											onClick={ ( e ) => {
												e.stopPropagation();
												removeQst( index );
											} }
											closeOnSelect={ true }
										>
											<Span className="quizpress-icon quizpress-icon--close quizpress-danger" />
											{ __( 'Remove', 'quizpress' ) }
										</Menu.Item>
									</Menu.Content>
								</Menu.Positioner>
							</Portal>
						</Menu.Root>
					</Flex>
				</Collapsible.Trigger>
				<Collapsible.Content
					display="flex"
					flexDirection="column"
					bg="var(--quizpress-background)"
					boxShadow="var(--quizpress-shadow)"
					borderRadius="0 0 4px 4px"
				>
					<Flex
						width="full"
						gap={ 6 }
						alignItems="stretch"
						padding="24px 24px 0 24px"
					>
						<Flex
							borderRight="1px solid var(--quizpress-border-color)"
							gap={ 3 }
							direction="column"
							width="65%"
							padding="0 24px 24px 0"
						>
							<Flex direction="column" gap="12px">
								<Flex direction="column" gap="8px">
									<Text
										as="label"
										className="quizpress-title quizpress-title-required"
									>
										{ __( 'QuestionTitle', 'quizpress' ) }
										<Span className="quizpress-title-required--sign">
											*
										</Span>
									</Text>
									<Field
										as={ Input }
										name={ `question_title` }
										placeholder={ __(
											'Enter title',
											'quizpress'
										) }
										defaultValue=""
										className="quizpress-input"
									/>
								</Flex>
								{ ! showDescription ? (
									<Text
										cursor="pointer"
										onClick={ () =>
											isShowDescription( true )
										}
										color="blue.500"
										p={ 0 }
										fontWeight="500"
										fontSize="0.875rem"
										justifyContent="left"
										margin={ 0 }
									>
										{ __(
											'+ Add Description',
											'quizpress'
										) }
									</Text>
								) : (
									<Flex direction="column" gap="8px">
										<Flex justifyContent="space-between">
											<Text className="quizpress-title">
												{ __(
													'Description',
													'quizpress'
												) }
											</Text>
											<Button
												onClick={ () =>
													isShowDescription( false )
												}
												height="16px"
												variant="ghost"
											>
												{ __( 'close', 'quizpress' ) }
											</Button>
										</Flex>
										<Field
											as={ Textarea }
											className="quizpress-textarea"
											name={ `question_content` }
											placeholder={ __(
												'Enter description',
												'quizpress'
											) }
											rows={ 4 }
										/>
									</Flex>
								) }
								{ ! showExplanation ? (
									<Text
										cursor="pointer"
										onClick={ () =>
											isShowExplanation( true )
										}
										color="blue.500"
										p={ 0 }
										fontWeight="500"
										fontSize="0.875rem"
										justifyContent="left"
										margin={ 0 }
									>
										{ __(
											'+ Add Explanation',
											'quizpress'
										) }
									</Text>
								) : (
									<Flex direction="column" gap="8px">
										<Flex justifyContent="space-between">
											<Text className="quizpress-title">
												{ __(
													'Explanation',
													'quizpress'
												) }
											</Text>
											<Button
												onClick={ () =>
													isShowExplanation( false )
												}
												height="16px"
												variant="ghost"
											>
												{ __( 'close', 'quizpress' ) }
											</Button>
										</Flex>
										<Field
											as={ Textarea }
											className="quizpress-textarea"
											name="question_explanation"
											placeholder={ __(
												'Enter explanation',
												'quizpress'
											) }
											rows={ 4 }
										/>
									</Flex>
								) }
							</Flex>

							{ /* it will change based on answer type */ }
							<Flex direction="column" gap={ 1 }>
								{ questionType !== 'fill_in_the_blanks' && (
									<Text className="quizpress-title">
										{ __( 'Answers', 'quizpress' ) }
									</Text>
								) }
								{ renderSwitchQuestionType( questionType ) }
							</Flex>
						</Flex>

						{ /* Answer type, question type and category */ }
						<Flex
							flexDirection="column"
							width={ '35%' }
							gap={ 4 }
							marginBottom="24px"
						>
							<Flex
								border="1px solid var(--quizpress-border-color)"
								direction="column"
								borderRadius="4px"
								p={ 6 }
							>
								<Flex direction="column" gap={ 3 } width="100%">
									{ /* Question type */ }
									<Flex
										as="label"
										direction="column"
										gap={ 2 }
										width="100%"
									>
										<Text className="quizpress-title">
											{ __(
												'Question type',
												'quizpress'
											) }
										</Text>
										<Field
											as={ Select }
											name={ `question_type` }
											placeholder={ __(
												'Select question type',
												'quizpress'
											) }
											className="quizpress-select"
											classNamePrefix="quizpress-select"
											isSearchable={ true }
											isClearable={ true }
											options={ questionTypeOptions }
											value={ currentQstType }
											onChange={ ( option ) => {
												setFieldValue(
													`question_type`,
													option.value
												);
												if (
													option.value ===
													'fill_in_the_blanks'
												) {
													setFieldValue(
														`answers`,
														[]
													);
													setFieldValue(
														`answer_type`,
														'read_only'
													);
												}
												if ( ! isShowAnsOptions ) {
													setFieldValue(
														`answer_type`,
														''
													);
												}
											} }
										/>
									</Flex>
									{ /* Answer type */ }
									{ isShowAnsOptions && (
										<Flex
											as="label"
											direction="column"
											gap={ 2 }
											width="100%"
										>
											<Text className="quizpress-title">
												{ __(
													'Answer Option',
													'quizpress'
												) }
											</Text>
											<Select
												name={ `answer_type` }
												placeholder={ __(
													'Select answer option',
													'quizpress'
												) }
												className="quizpress-select"
												classNamePrefix="quizpress-select"
												isSearchable={ true }
												isClearable={ true }
												options={ answerTypeOptions }
												value={ currentAnsType }
												onChange={ ( option ) => {
													setFieldValue(
														`answer_type`,
														option.value
													);
												} }
											/>
										</Flex>
									) }

									{ /* todo: Category here */ }
								</Flex>
							</Flex>
							{ /* Question Settings */ }
							<QuestionSettings quizValues={ quizValues } />
						</Flex>
					</Flex>
				</Collapsible.Content>
			</Collapsible.Root>
		</Flex>
	);
};

export default QuizQuestions;
