/* eslint no-param-reassign: "error" */
import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import type { AxiosResponse } from 'axios';
import axios from 'axios';

import environment from '../../Environments/environment';
import type { InvitedUserInterface } from '../../Pages/Account/Pages/ManageUsers/Components/ManageUsersPage';

const { apiUrl, backendRoutes } = environment;

interface InvitesState {
	selectedInvitee?: { [key: string]: string } | null;
	selectedInvite: InvitedUserInterface | null;
	invitesList: InvitedUserInterface[] | null;
	deleteStatus: null | 'pending' | 'success' | 'error';
}

const initialState: InvitesState = {
	selectedInvitee: null,
	selectedInvite: null,
	invitesList: null,
	deleteStatus: null
};

const invitesSlice = createSlice({
	name: 'companies',
	initialState,
	reducers: {
		selectInvite: (state, action) => {
			state.selectedInvite = action.payload;
		}
	},
	extraReducers: (builder) => {
		builder
			.addCase(fetchInviteData.fulfilled, (state, action) => {
				if (action.payload) {
					state.invitesList = action.payload;
				}
			})
			.addCase(fetchInvitationData.fulfilled, (state, action) => {
				if (action.payload) {
					state.selectedInvitee = action.payload;
				}
			})
			.addCase(acceptInvitation.fulfilled, (state, action) => {
				if (action.payload as [InvitedUserInterface, string]) {
					const [invitationData, invitationId] = action.payload;
					if (state.invitesList) {
						state.invitesList = state.invitesList.map((invite) =>
							invite.invite_uuid === invitationId
								? (invitationData as InvitedUserInterface)
								: invite
						);
						// state.invitesList = cL;
						console.log(' - update invite response:', invitationData);
					}
				}
			})
			.addCase(resendInvitation.fulfilled, (state, action) => {
				if (action.payload) {
					if (state.invitesList) {
						state.invitesList = state.invitesList.map((invite) =>
							invite._id === (action.payload as unknown as InvitedUserInterface)._id
								? (action.payload as unknown as InvitedUserInterface)
								: invite
						);
						console.log(' - resend invite response:', action.payload);
					}
				}
			})
			.addCase(acceptInvitation.rejected, (state, action) => {
				if (action.payload) {
					// Handle the error here, you can store it in the state or display it to the user
					throw new Error((action.payload as any).error);
				}
			})
			.addCase(deleteInvitedUser.pending, (state) => {
				state.deleteStatus = 'pending';
			})
			.addCase(deleteInvitedUser.fulfilled, (state, action) => {
				if (action.payload as [InvitedUserInterface, string]) {
					const [, invite_uuid] = action.payload;
					// if (state.invitesList) {
					// 	const updatedInvites = state.invitesList.filter(
					// 		(invite) => invite.invite_uuid !== invite_uuid
					// 	);

					// 	state.deleteStatus = 'success';
					// 	// Return new state with updated invitesList
					// 	return {
					// 		...state,
					// 		invitesList: updatedInvites
					// 	};
					// }
					if (state.invitesList) {
						state.invitesList = state.invitesList.filter(
							(invite) => invite.invite_uuid !== invite_uuid
						);
					}
					state.deleteStatus = 'success';
				}
			})
			.addCase(deleteInvation.fulfilled, (state, action) => {
				if (action.payload as [InvitedUserInterface, string]) {
					const [, invite_uuid] = action.payload;
					if (state.invitesList) {
						const updatedInvites = state.invitesList.filter(
							(invite) => invite.invite_uuid !== invite_uuid
						);

						// Return new state with updated invitesList
						return {
							...state,
							invitesList: updatedInvites
						};
					}
				}
			});
	}
});

export const fetchInviteData = createAsyncThunk(
	'invites/fetchinvitesList',
	async (payload: { selectedCompanyId: string }) => {
		// fetch associated invitees data for selected company
		const invites = await axios
			.get(`${apiUrl}${backendRoutes.account.getInvites}?companyId=${payload.selectedCompanyId}`)
			.then((response) => {
				if (response.status === 200) {
					return response.data;
				}
				// eslint-disable-next-line no-alert
				alert('an error occurred while retrieving the list of invites for the selected company');
			})
			.catch((e) => {
				// eslint-disable-next-line no-console
				console.error(e);
			});
		return invites;
	}
);

export const fetchInvitationData = createAsyncThunk(
	'invites/fetchinviteDetails',
	async (payload: { inviteUuid: string }) => {
		// fetch associated invitees data for selected company
		const invites = await axios
			.get(`${apiUrl}${backendRoutes.account.getInvitee}?inviteUuid=${payload.inviteUuid}`)
			.then((response) => {
				if (response.status === 200) {
					return response.data;
				}
				// eslint-disable-next-line no-alert
				alert('an error occurred while retrieving the list of invites for the selected company');
			})
			.catch((e) => {
				// eslint-disable-next-line no-console
				console.error(e);
			});
		return invites;
	}
);

export const acceptInvitation = createAsyncThunk(
	'invitations/accept',
	async (payload: { inviteUuid: string }, { rejectWithValue }) => {
		if (!payload.inviteUuid || payload.inviteUuid === '') {
			return rejectWithValue({ error: 'No invite id provided' });
		}
		try {
			const company: InvitedUserInterface = await axios
				.post(apiUrl + backendRoutes.account.acceptInvitee, {
					inviteUuid: payload.inviteUuid
				})
				.then((response: AxiosResponse<InvitedUserInterface>) => {
					// remove from pending status from localStorage
					console.log('acceptInvitation, remove pedning from LS', response.data);
					localStorage.removeItem('pendingInvitation');

					// parse the response
					return response.data;
				});
			return [company, payload.inviteUuid];
		} catch (error: any) {
			return rejectWithValue({ error: error.message });
		}
	}
);

export const resendInvitation = createAsyncThunk(
	'invitations/resend',
	async (payload: { inviteId: string }, { rejectWithValue }) => {
		console.log('resendInvitation', payload);
		if (!payload.inviteId || payload.inviteId === '') {
			return rejectWithValue({ error: 'No invite id provided' });
		}
		try {
			const company: InvitedUserInterface = await axios
				.post(apiUrl + backendRoutes.account.resendInvite, {
					inviteId: payload.inviteId
				})
				.then(
					(response: AxiosResponse<InvitedUserInterface>) =>
						// return JSON.parse(response.data);
						response.data
				);
			return [company, payload.inviteId];
		} catch (error: any) {
			return rejectWithValue({ error: error.message });
		}
	}
);

export const deleteInvitedUser = createAsyncThunk(
	'invitations/deleteUser',
	async (payload: { inviteUuid: string }, { rejectWithValue }) => {
		if (!payload.inviteUuid || payload.inviteUuid === '') {
			return rejectWithValue({ error: 'No invite id provided' });
		}
		try {
			const company: InvitedUserInterface = await axios
				.delete(apiUrl + backendRoutes.account.deleteInvitedUser, {
					data: { inviteUuid: payload.inviteUuid }
				})
				.then((response: AxiosResponse<InvitedUserInterface>) => response.data);
			return [company, payload.inviteUuid];
		} catch (error: any) {
			return rejectWithValue({ error: error.message });
		}
	}
);

export const deleteInvation = createAsyncThunk(
	'invitations/deleteInvitation',
	async (payload: { inviteUuid: string }, { rejectWithValue }) => {
		if (!payload.inviteUuid || payload.inviteUuid === '') {
			return rejectWithValue({ error: 'No invite id provided' });
		}
		try {
			const company: InvitedUserInterface = await axios
				.delete(apiUrl + backendRoutes.account.deleteInvitation, {
					data: { inviteUuid: payload.inviteUuid }
				})
				.then((response: AxiosResponse<InvitedUserInterface>) => response.data);
			return [company, payload.inviteUuid];
		} catch (error: any) {
			return rejectWithValue({ error: error.message });
		}
	}
);

export const { selectInvite } = invitesSlice.actions;

export default invitesSlice.reducer;
