import { call, put, select } from 'redux-saga/effects';
import { get, post, patch } from 'services/requests';
import { Api } from 'routes/Api';
import { handleError } from 'modules/error-handler';
import { Swal } from 'lib/swal/swal';
import * as actions from 'lib/redux/actions/shops-actions';
import { message, notification } from 'antd';

export function* fetchMultipleShops(): Generator {
	try {
		const res: Record<string, any> = yield call(() => get({
			url: Api.shops
		}));
		yield put(actions.fetchedMultipleShops({ data: res.data }));

	}
	catch (error) {
		yield put(actions.failedFetchMultipleShops({ error: error.message }));

		handleError(error);
	}
}


export function* fetchShop(action): Generator {
	try {
		const res: Record<string, any> = yield call(() => get({
			url: Api.shops + '/' + action.slug
		}));

		yield put(actions.fetchedShop({ data: res.data }));

	}
	catch (error) {
		yield put(actions.failedFetchShop({ error: error.message }));

		handleError(error);
	}
}


export function* createShop(action) {
	try {
		const res = yield call(() => post({
			url: Api.shops,
			data: action.payload
		}));

		yield put(actions.createdShop({ data: res.data }));

		Swal.fire({
			title: 'Success',
			text: 'New Shop Created!',
			imageUrl: res.data.picture,
			imageWidth: 400,
			imageHeight: 200,
			imageAlt: res.data.name,
		});

		notification.open({
			message: res.data.name,
			description: 'Your shop was successfully created, however, it will not be available for use until a moderator verifies it. Kindly give up to 24hours for your shop to be verified.',
			duration: 0
		});
		// .then(() => rdr('/shop/'+res.data.slug+'/manage'));
	}
	catch (error) {
		if (error?.response?.status == 422) {
			return yield put(actions.failedCreateShop({ error: error.response.data?.errors }));
		}

		yield put(actions.failedCreateShop({ error: error.message }));
		return handleError(error);
	}
}


export function* updateShop(action) {
	try {
		const res = yield call(() => post({
			url: Api.shops + '/' + action.payload.get('id'),
			data: action.payload,
		}));

		yield put(actions.updatedShop({ data: res.data }));

		Swal.fire({
			title: 'Success',
			text: 'Shop Details Updated!',
			imageUrl: res.data.picture,
			imageWidth: 400,
			imageHeight: 200,
			imageAlt: res.data.name,
		});
	}
	catch (error) {
		if (error.response.status == 422) {
			return yield put(actions.failedUpdateShop({ error: error.response.data.errors }));
		}

		yield put(actions.failedUpdateShop({ error: error.message }));
		return handleError(error);
	}
}





export function* assignRole(action) {
	const hide = message.loading('Assigning new role to user', 0);
	try {
		const res = yield call(() => post({
			url: Api.shopMembers,
			data: action.payload
		}));
		const getDataToAlter = state => state.shop;
		const dataToAlter = yield select(getDataToAlter);
		dataToAlter.members = dataToAlter.members.map(member => {
			if (member.id == res.data.id) member.roles = res.data.roles;
			return member;
		});

		yield put(actions.fetchedShop({ data: dataToAlter }));
		yield put(actions.assignedRole({ data: res.data }));

		message.success('New role assigned to user');
	}
	catch (error) {
		message.error('Failed to assign role to user');
		return yield put(actions.failedAssignRole({ error: error.message }));
	}
	finally {
		hide();
	}
}


export function* removeRole(action) {
	let customMessages: { loadingMessage: string, successMessage: string };
	if (action.payload.role.split(' ').slice(-1) == 'Member') {
		customMessages = {
			loadingMessage: 'Removing user from shop',
			successMessage: 'User has been removed from shop'
		};
	}
	const hide = customMessages?.loadingMessage ? message.loading(customMessages?.loadingMessage, 0) : message.loading('Removing role from user', 0);
	try {
		const res = yield call(() => post({
			url: Api.shopMembers + '/remove',
			data: action.payload
		}));
		const getDataToAlter = state => state.shop;
		const dataToAlter = yield select(getDataToAlter);
		if (action.payload.role.split(' ').slice(-1) == 'Member') {
			dataToAlter.members = dataToAlter.members.filter(member => member.id !== res.data.id);
		} else {
			dataToAlter.members = dataToAlter.members.map(member => {
				if (member.id == res.data.id) member.roles = res.data.roles;
				return member;
			});
		}


		yield put(actions.fetchedShop({ data: dataToAlter }));
		yield put(actions.removedRole({ data: res.data }));

		customMessages?.successMessage ? message.success(customMessages?.successMessage) : message.success('Role removed from user');
	}
	catch (error) {
		message.error('Failed to remove role from user');
		return yield put(actions.failedRemoveRole({ error: error.message }));
	}
	finally {
		hide();
	}
}


export function* changeRole(action) {
	const hide = message.loading('Updating user role', 0);
	try {
		const res = yield call(() => patch({
			url: Api.shopMembers,
			data: action.payload
		}));
		const getDataToAlter = state => state.shop;
		const dataToAlter = yield select(getDataToAlter);
		dataToAlter.members = dataToAlter.members.map(member => {
			if (member.id == res.data.id) member.roles = res.data.roles;
			return member;
		});

		yield put(actions.fetchedShop({ data: dataToAlter }));
		yield put(actions.changedRole({ data: res.data }));

		message.success('User role updated');
	}
	catch (error) {
		message.error('Failed to update user role');
		return yield put(actions.failedChangeRole({ error: error.message }));
	}
	finally {
		hide();
	}
}


export function* fetchNoneMembers(action): Generator {
	try {
		const getDataToAlter = state => state.shop;
		const shop : any = yield select(getDataToAlter);
		const res: Record<string, any> = yield call(() => get({
			url: Api.shopMembers + '/new/' + action.searchKey + '/' + shop.id
		}));
		yield put(actions.fetchedNoneMembers({ data: res.data }));

	}
	catch (error) {
		yield put(actions.failedFetchNoneMembers({ error: error.message }));
		handleError(error);
	}
}


export function* addShopMember(action): Generator {
	const hide = message.loading('Adding ' + action.payload.member + ' to shop');
	try {
		const res: Record<string, any> = yield call(() => post({
			url: Api.shopMembers + '/new',
			data: action.payload
		}));

		const getDataToAlter = state => state.shop;
		let dataToAlter : any = yield select(getDataToAlter);
		dataToAlter = dataToAlter ? dataToAlter : {members: []};

		dataToAlter.members.unshift(res.data);

		yield put(actions.fetchedShop({ data: dataToAlter }));

		yield put(actions.addedShopMember({ data: res.data }));

		message.success(action.payload.member + ' has been added to the shop');
	}
	catch (error) {
		yield put(actions.failedAddShopMember({ error: error.message }));

		message.error(action.payload.member + ' could not be added to the shop');
	}
	finally {
		hide();
	}
}


export function* fetchShopActivity(action): Generator {
	try {
		const res : any= yield call(() => get({
			url: Api.shops + '/' + action.slug + '/activity'
		}));
		yield put(actions.fetchedShopActivity({ data: res.data }));

	}
	catch (error) {
		yield put(actions.failedFetchShopActivity({ error: error.message }));

		handleError(error);
	}
}
