import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import {
	API,
	handleSliceError,
	handleSliceSuccess,
	makeRequest,
	namespace,
} from '@QPUtils/helper';
import { __ } from '@wordpress/i18n';
import {
	createAnswer,
	deleteAnswer,
	fetchAnswerById,
	fetchAnswerByQuestionId,
	fetchAnswers,
	updateAnswer,
} from './answerActions';

export const createQuestion = createAsyncThunk(
	'quizpress/createQuestion',
	async ( formData, thunkAPI ) => {
		return await API.post( namespace + 'questions', formData )
			.then( ( res ) => {
				if ( res.status === 200 ) {
					handleSliceSuccess(
						thunkAPI,
						res.data.message ||
							__( 'Question created successfully!', 'quizpress' )
					);
					return res.data;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

export const updateQuestion = createAsyncThunk(
	'quizpress/updateQuestion',
	async ( formData, thunkAPI ) => {
		return await API.put(
			namespace + `questions/${ formData?.question_id }`,
			formData
		)
			.then( ( res ) => {
				if ( res.status === 200 ) {
					handleSliceSuccess(
						thunkAPI,
						res.data.message ||
							__( 'Question updated successfully!', 'quizpress' )
					);
					return res.data;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

export const fetchQuestions = createAsyncThunk(
	'quizpress/fetchQuestions',
	async (
		{ status = 'all', page = 1, per_page = 10, search = '' },
		thunkAPI
	) => {
		let params = {
			status: status === 'all' ? 'any' : status,
			page,
			per_page,
		};

		const keyword = search;
		if ( keyword ) {
			params = { ...params, keyword };
		}

		return await API.get( namespace + 'questions', { params } )
			.then( ( res ) => {
				if ( res.status === 200 ) {
					return {
						data: res.data,
						totalItems: Number( res.headers[ 'x-wp-total' ] ),
						currentPage: page,
						itemPerPage: per_page,
						status,
					};
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

export const fetchQuestionById = createAsyncThunk(
	'quizpress/fetchQuestionById',
	async ( id, thunkAPI ) => {
		return await API.get( namespace + `questions/${ id }` )
			.then( ( res ) => {
				if ( res.status === 200 ) {
					// handleSliceSuccess(
					// 	thunkAPI,
					// 	res.data.message ||
					// 	__('Question loaded successfully!', 'quizpress')
					// );
					return res.data;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

export const deleteQuestion = createAsyncThunk(
	'quizpress/deleteQuestion',
	( id, thunkAPI ) => {
		return API.delete(
			namespace + `questions/${ Number( id ) }?force=true`
		)
			.then( ( res ) => {
				if ( res.status === 200 ) {
					handleSliceSuccess(
						thunkAPI,
						res.data.message ||
							__( 'Question deleted successfully!', 'quizpress' )
					);
					return id;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

export const moveQuestionTrash = createAsyncThunk(
	'quizpress/moveQuestionTrash',
	async ( ID, thunkAPI ) => {
		return await API.delete(
			`${ namespace }questions/${ Number( ID ) }?force=false`
		)
			.then( ( res ) => {
				if ( res.status === 200 ) {
					handleSliceSuccess(
						thunkAPI,
						res.data.message ||
							__( 'Question moved to trash!', 'quizpress' )
					);
					return ID;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

export const restoreQuestion = createAsyncThunk(
	'quizpress/restoreQuestion',
	async ( formData, thunkAPI ) => {
		const updatedFormData = { ...formData, question_status: 'draft' };
		return await API.post(
			namespace + 'questions/' + formData.question_id,
			updatedFormData
		)
			.then( ( res ) => {
				if ( res.status === 200 ) {
					handleSliceSuccess(
						thunkAPI,
						res.data.message ||
							__( 'Question restored successfully!', 'quizpress' )
					);
					return res.data;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

export const searchQuestions = createAsyncThunk(
	'quizpress/searchQuestions',
	async ( searchTerm, thunkAPI ) => {
		try {
			return await makeRequest( 'admin/get_question_search', {
				search: searchTerm,
			} ).then( ( res ) => {
				if ( res.status === 200 ) {
					return res;
				}
			} );
		} catch ( error ) {}
	}
);

const quizQuestionSlice = createSlice( {
	name: 'quizQuestion',
	initialState: {
		data: [],
		answers: [],
		itemPerPage: 10,
		currentPage: 1,
		totalItems: 0,
		loading: false,
	},
	reducers: {
		updateQuestionAnswerManually: ( state, actions ) => {
			const { questionId, answers } = actions.payload;
			state.data = state.data.map( ( item ) => {
				if ( Number( item.question_id ) === Number( questionId ) ) {
					return { ...item, answers };
				}
				return item;
			} );
		},
		updateQuestionCurrentPage: ( state, actions ) => {
			state.currentPage = actions.payload;
		},
		updateQuestionItemPerPage: ( state, actions ) => {
			state.itemPerPage = actions.payload;
		},

		importQuestions: ( state, actions ) => {
			state.data = [ ...state.data, ...actions.payload ];
		},
	},
	extraReducers: ( builder ) => {
		builder
			// create a quiz question
			.addCase( createQuestion.fulfilled, ( state, action ) => {
				state.loading = false;
				state.data = [ ...state.data, action.payload ];
			} )
			.addCase( updateQuestion.fulfilled, ( state, action ) => {
				state.loading = false;
				state.data = state.data.map( ( item ) => {
					if (
						Number( item.question_id ) ===
						Number( action.payload.question_id )
					) {
						return { ...item, ...action.payload };
					}
					return item;
				} );
			} )
			.addCase( fetchQuestions.fulfilled, ( state, action ) => {
				state.loading = false;
				state.data = action.payload.data;
				state.currentPage = action.payload.currentPage;
				state.itemPerPage = action.payload.itemPerPage;
				state.totalItems = action.payload.totalItems;
			} )
			.addCase( fetchQuestionById.fulfilled, ( state, action ) => {
				state.loading = false;
				state.data = [ action.payload ];
			} )
			.addCase( moveQuestionTrash.fulfilled, ( state, action ) => {
				state.data = state.data.map( ( item ) => {
					if (
						Number( item.question_id ) === Number( action.payload )
					) {
						return {
							...item,
							question_status: 'trash',
						};
					}
					return item;
				} );
			} )
			.addCase( deleteQuestion.fulfilled, ( state, action ) => {
				state.loading = false;
				state.data = state.data.filter(
					( item ) =>
						Number( item.question_id ) !== Number( action.payload )
				);
			} )

			// create a quiz question
			.addCase( createAnswer.fulfilled, ( state, action ) => {
				state.loading = false;
				state.answers = [ action.payload, ...state.answers ];
			} )
			.addCase( updateAnswer.fulfilled, ( state, action ) => {
				state.loading = false;
				state.answers = state.answers.map( ( item ) => {
					if (
						Number( item.answer_id ) ===
						Number( action.payload.answer_id )
					) {
						return action.payload;
					}
					return item;
				} );
			} )
			.addCase( fetchAnswers.fulfilled, ( state, action ) => {
				state.loading = false;
				state.answers = action.payload;
			} )
			.addCase( fetchAnswerByQuestionId.fulfilled, ( state, action ) => {
				state.loading = false;
				state.answers = action.payload;
			} )
			.addCase( fetchAnswerById.fulfilled, ( state, action ) => {
				state.loading = false;
				state.answers = [ action.payload ];
			} )
			.addCase( deleteAnswer.fulfilled, ( state, action ) => {
				state.loading = false;
				state.answers = state.answers.filter(
					( item ) =>
						Number( item.answer_id ) !== Number( action.payload )
				);
			} )
			.addCase( searchQuestions.fulfilled, ( state, action ) => {
				state.loading = false;
				state.data = [ ...state.data, action.payload ];
			} )
			// Restore questions
			.addCase( restoreQuestion.fulfilled, ( state, action ) => {
				state.data = state.data.map( ( item ) => {
					if (
						Number( item.question_id ) ===
						Number( action.payload.question_id )
					) {
						return { ...item, ...action.payload };
					}
					return item;
				} );
			} );
	},
} );
export const {
	updateQuestionCurrentPage,
	updateQuestionItemPerPage,
	updateQuestionAnswerManually,
	importQuestions,
} = quizQuestionSlice.actions;
export default quizQuestionSlice.reducer;
