import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';

import {
	API,
	current_user_can,
	current_user_id,
	namespace,
	is_admin,
	handleSliceSuccess,
	handleSliceError,
	makeRequest,
} from '@QPUtils/helper';
import { __ } from '@wordpress/i18n';

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

		// if (!is_admin || current_user_can.manage_options === false)
		// 	params = { ...params, author: current_user_id };
		if ( search ) {
			params = { ...params, search };
		}

		return await API.get( namespace + 'quizpress_quiz', {
			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 getQuiz = createAsyncThunk(
	'quizpress/getQuiz',
	async ( { ID, isEditable = false }, thunkAPI ) => {
		// const queryString = is_plain_permalink ? '&' : '?';
		const queryString = isEditable ? '?context=edit' : '';
		return await API.get(
			// namespace + 'quizpress_quiz/' + ID + queryString + 'context=edit'
			namespace + 'quizpress_quiz/' + ID + queryString
		)
			.then( ( res ) => {
				if ( res.status === 200 ) {
					// handleSliceSuccess(thunkAPI, res.data.message);
					return res.data;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

export const getFrontendQuiz = createAsyncThunk(
	'quizpress/getFrontendQuiz',
	async ( ID, thunkAPI ) => {
		// const queryString = is_plain_permalink ? '&' : '?';
		return await API.get(
			// namespace + 'quizpress_quiz/' + ID + queryString + 'context=edit'
			namespace + 'render_quiz/' + ID
		)
			.then( ( res ) => {
				if ( res.status === 200 ) {
					// handleSliceSuccess(thunkAPI, res.data.message);
					return res.data;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

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

export const updateQuiz = createAsyncThunk(
	'quizpress/updateQuiz',
	async ( { params, questions = [] }, thunkAPI ) => {
		return await API.post(
			namespace + 'quizpress_quiz/' + params.id,
			params
		)
			.then( ( res ) => {
				if ( res.status === 200 ) {
					handleSliceSuccess(
						thunkAPI,
						res.data.message ||
							__( 'Quiz updated successfully!', 'quizpress' )
					);
					return {
						data: res.data,
						questions,
					};
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

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

export const moveQuizToTrash = createAsyncThunk(
	'quizpress/moveQuizToTrash',
	async ( formData, thunkAPI ) => {
		// return await API.post(
		// 	`${namespace}quizpress_quiz/${Number(formData.id)}`, { force: false, status: 'trash' },
		// )
		return await makeRequest( 'admin/update_quizpress_quiz_status', {
			quiz_id: formData.id,
			status: 'trash',
		} )
			.then( ( res ) => {
				if ( res ) {
					handleSliceSuccess(
						thunkAPI,
						res?.data?.message ||
							__(
								'Quiz moved to trash successfully!',
								'quizpress'
							)
					);
					return formData;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

export const deleteQuiz = createAsyncThunk(
	'quizpress/deleteQuiz',
	async ( id, thunkAPI ) => {
		return await API.delete(
			namespace + 'quizpress_quiz/' + id + '?force=true'
		)
			.then( ( res ) => {
				if ( res.status === 200 ) {
					handleSliceSuccess(
						thunkAPI,
						res.data.message ||
							__( 'Quiz deleted permanently!', 'quizpress' )
					);
					return res.data.previous;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

export const getQuizLeaderboard = createAsyncThunk(
	'quizpress/getQuizLeaderboard',
	async ( id, thunkAPI ) => {
		return await API.get( namespace + 'leaderboard/' + id )
			.then( ( res ) => {
				if ( res.status === 200 ) {
					return res.data;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

export const deleteQuizAttempts = createAsyncThunk(
	'quizpress/deleteQuizAttempts',
	async ( id, thunkAPI ) => {
		return await API.delete(
			namespace + 'attempts/' + id + '/attempts',
			{ headers: { 'X-HTTP-Method-Override': 'DELETE' } },
			{ force: true }
		)
			.then( ( res ) => {
				if ( res.status === 200 ) {
					return res.data;
				}
			} )
			.catch( ( err ) => {
				return handleSliceError( thunkAPI, err );
			} );
	}
);

const quizSlice = createSlice( {
	name: 'quizzes',
	initialState: {
		data: [],
		totalItems: 0,
		currentPage: 1,
		loading: false,
		itemPerPage: 10,
		leaderBoards: [],
	},
	reducers: {
		updateQuizCurrentPage: ( state, actions ) => {
			state.currentPage = actions.payload;
		},
		updateQuizItemPerPage: ( state, actions ) => {
			state.itemPerPage = actions.payload;
		},
	},
	extraReducers: ( builder ) => {
		builder
			.addCase( fetchQuizzes.fulfilled, ( state, action ) => {
				const { data, totalItems, status, currentPage, itemPerPage } =
					action.payload;
				state.data = data;
				state.totalItems = totalItems;
				state.currentPage = currentPage;
				state.itemPerPage = itemPerPage;
			} )
			// get new quiz
			.addCase( getQuiz.fulfilled, ( state, action ) => {
				state.loading = false;
				state.data = [ action.payload ];
			} )
			// create new quiz
			.addCase( createQuiz.fulfilled, ( state, action ) => {
				state.data = [ action.payload, ...state.data ];
			} )
			// update quiz
			.addCase( updateQuiz.fulfilled, ( state, action ) => {
				state.data = state.data.map( ( item ) => {
					if (
						Number( item.id ) === Number( action.payload.data.id )
					) {
						return {
							...action.payload.data,
							questions: action.payload.questions,
						};
					}
					return item;
				} );
			} )
			// Restore quiz
			.addCase( restoreQuiz.fulfilled, ( state, action ) => {
				state.data = state.data.map( ( item ) => {
					if ( Number( item.id ) === Number( action.payload.id ) ) {
						return { ...item, ...action.payload };
					}
					return item;
				} );
			} )
			// Move quiz To Trash
			.addCase( moveQuizToTrash.fulfilled, ( state, action ) => {
				state.data = state.data.map( ( item ) => {
					if ( Number( item.id ) === Number( action.payload.id ) ) {
						return { ...item, status: 'trash' };
					}
					return item;
				} );
			} )
			// Delete quiz
			.addCase( deleteQuiz.fulfilled, ( state, action ) => {
				state.data = state.data.filter(
					( item ) =>
						Number( item.id ) !== Number( action.payload.id )
				);
			} )

			/**
			 * Frontend
			 * Get Frontend Quiz
			 */
			.addCase( getFrontendQuiz.fulfilled, ( state, action ) => {
				state.loading = false;
				state.data = [ action.payload ];
			} )

			.addCase( getQuizLeaderboard.fulfilled, ( state, action ) => {
				if ( ! state.leaderBoards.length ) {
					state.leaderBoards = [ action.payload ];
					return;
				}

				const foundQuiz = state.leaderBoards.find(
					( item ) =>
						Number( item.quiz_id ) ===
						Number( action.payload.quiz_id )
				);
				if ( ! foundQuiz ) {
					state.leaderBoards = [
						action.payload,
						...state.leaderBoards,
					];
					return;
				}

				state.leaderBoards = state.leaderBoards.map( ( item ) => {
					if (
						Number( item.quiz_id ) ===
						Number( action.payload.quiz_id )
					) {
						return { ...item, ...action.payload };
					}
					return item;
				} );
			} );
	},
} );

export const { updateQuizCurrentPage, updateQuizItemPerPage } =
	quizSlice.actions;
export default quizSlice.reducer;
