'use strict';

define('forum/groups/details', [
	'forum/groups/memberlist',
	'iconSelect',
	'components',
	'coverPhoto',
	'pictureCropper',
	'api',
	'slugify',
	'categorySelector',
	'bootbox',
	'alerts',
	'helpers',
], function (
	memberList,
	iconSelect,
	components,
	coverPhoto,
	pictureCropper,
	api,
	slugify,
	categorySelector,
	bootbox,
	alerts,
	helpers
) {
	const Details = {};
	let groupName;

	Details.init = function () {
		const detailsPage = components.get('groups/container');

		groupName = ajaxify.data.group.name;

		if (ajaxify.data.group.isOwner) {
			Details.prepareSettings();

			coverPhoto.init(
				components.get('groups/cover'),
				function (imageData, position, callback) {
					socket.emit('groups.cover.update', {
						groupName: groupName,
						imageData: imageData,
						position: position,
					}, callback);
				},
				function () {
					pictureCropper.show({
						title: '[[groups:upload-group-cover]]',
						socketMethod: 'groups.cover.update',
						aspectRatio: NaN,
						allowSkippingCrop: true,
						restrictImageDimension: false,
						paramName: 'groupName',
						paramValue: groupName,
					}, function (imageUrlOnServer) {
						imageUrlOnServer = (!imageUrlOnServer.startsWith('http') ? config.relative_path : '') + imageUrlOnServer + '?' + Date.now();
						components.get('groups/cover').css('background-image', 'url(' + imageUrlOnServer + ')');
					});
				},
				removeCover
			);
		}

		memberList.init();

		handleMemberInvitations();

		components.get('groups/activity').find('.content img:not(.not-responsive)').addClass('img-fluid');

		detailsPage.on('click', '[data-action]', function () {
			const btnEl = $(this);
			const userRow = btnEl.parents('[data-uid]');
			const ownerFlagEl = userRow.find('[component="groups/owner/icon"]');
			const isOwner = !!parseInt(userRow.attr('data-isowner'), 10);
			const uid = userRow.attr('data-uid');
			const action = btnEl.attr('data-action');

			switch (action) {
				case 'toggleOwnership':
					api[isOwner ? 'del' : 'put'](`/groups/${ajaxify.data.group.slug}/ownership/${uid}`, {}).then(() => {
						ownerFlagEl.toggleClass('invisible');
					}).catch(alerts.error);
					break;

				case 'kick':
					bootbox.confirm('[[groups:details.kick-confirm]]', function (confirm) {
						if (!confirm) {
							return;
						}

						api.del(`/groups/${ajaxify.data.group.slug}/membership/${uid}`, undefined).then(
							() => {
								userRow.remove();
								$('[component="group/member/count"]').text(
									helpers.humanReadableNumber(ajaxify.data.group.memberCount - 1)
								);
							}
						).catch(alerts.error);
					});
					break;

				case 'update':
					Details.update();
					break;

				case 'delete':
					Details.deleteGroup();
					break;

				case 'join':
					api.put('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined).then(
						() => ajaxify.refresh()
					).catch(alerts.error);
					break;

				case 'leave':
					api.del('/groups/' + ajaxify.data.group.slug + '/membership/' + (uid || app.user.uid), undefined).then(
						() => ajaxify.refresh()
					).catch(alerts.error);
					break;

				case 'accept':
					api.put(`/groups/${ajaxify.data.group.slug}/pending/${uid}`).then(
						() => {
							userRow.remove();
							memberList.refresh();
							updatePendingAlertVisibility();
						}
					).catch(alerts.error);
					break;

				case 'reject':
					api.del(`/groups/${ajaxify.data.group.slug}/pending/${uid}`).then(
						() => {
							userRow.remove();
							memberList.refresh();
							updatePendingAlertVisibility();
						}
					).catch(alerts.error);
					break;

				case 'acceptInvite':
					api.put(`/groups/${ajaxify.data.group.slug}/invites/${app.user.uid}`).then(() => {
						if (uid) {
							userRow.remove();
							memberList.refresh();
						} else {
							ajaxify.refresh();
						}
					}).catch(alerts.error);
					break;

				case 'rescindInvite': // falls through
				case 'rejectInvite':
					api.del(`/groups/${ajaxify.data.group.slug}/invites/${uid || app.user.uid}`).then(() => {
						if (uid) {
							userRow.remove();
							updateInviteAlertVisibility();
							memberList.refresh();
						} else {
							ajaxify.refresh();
						}
					}).catch(alerts.error);
					break;

				case 'acceptAll': // falls throughs
				case 'rejectAll': {
					const listEl = document.querySelector('[component="groups/pending"]');
					if (!listEl) {
						return;
					}

					const method = action === 'acceptAll' ? 'put' : 'del';
					let uids = Array.prototype.map.call(listEl.querySelectorAll('[data-uid]'), el => parseInt(el.getAttribute('data-uid'), 10));
					uids = uids.filter((uid, idx) => uids.indexOf(uid) === idx);

					Promise.all(uids.map(async uid => api[method](`/groups/${ajaxify.data.group.slug}/pending/${uid}`))).then(() => {
						ajaxify.refresh();
					}).catch(alerts.error);
					break;
				}
			}
		});
	};

	Details.prepareSettings = function () {
		const settingsFormEl = components.get('groups/settings');
		const labelColorValueEl = settingsFormEl.find('[name="labelColor"]');
		const textColorValueEl = settingsFormEl.find('[name="textColor"]');
		const iconBtn = settingsFormEl.find('[data-action="icon-select"]');
		const previewEl = settingsFormEl.find('.badge');
		const previewElText = settingsFormEl.find('.badge-text');
		const previewIcon = previewEl.find('i');
		const userTitleEl = settingsFormEl.find('[name="userTitle"]');
		const userTitleEnabledEl = settingsFormEl.find('[name="userTitleEnabled"]');
		const iconValueEl = settingsFormEl.find('[name="icon"]');

		labelColorValueEl.on('input', function () {
			previewEl.css('background-color', labelColorValueEl.val());
		});

		textColorValueEl.on('input', function () {
			previewEl.css('color', textColorValueEl.val());
		});

		// Add icon selection interface
		iconBtn.on('click', function () {
			iconSelect.init(previewIcon, function () {
				iconValueEl.val(previewIcon.val());
			});
		});

		// If the user title changes, update that too
		userTitleEl.on('keyup', function () {
			previewElText.translateText((userTitleEl.val()));
		});

		// Disable user title customisation options if the the user title itself is disabled
		userTitleEnabledEl.on('change', function () {
			const customOpts = components.get('groups/userTitleOption');

			if (this.checked) {
				customOpts.removeAttr('disabled');
				previewEl.removeClass('hide');
			} else {
				customOpts.attr('disabled', 'disabled');
				previewEl.addClass('hide');
			}
		});

		const cidSelector = categorySelector.init($('.member-post-cids-selector [component="category-selector"]'), {
			onSelect: function (selectedCategory) {
				let cids = ($('#memberPostCids').val() || '').split(',').map(cid => parseInt(cid, 10));
				cids.push(selectedCategory.cid);
				cids = cids.filter((cid, index, array) => array.indexOf(cid) === index);
				$('#memberPostCids').val(cids.join(','));
				cidSelector.selectCategory(0);
			},
		});
	};

	Details.update = function () {
		const settingsFormEl = components.get('groups/settings');
		const checkboxes = settingsFormEl.find('input[type="checkbox"][name]');

		if (settingsFormEl.length) {
			const settings = settingsFormEl.serializeObject();

			// serializeObject doesnt return array for multi selects if only one item is selected
			if (!Array.isArray(settings.memberPostCids)) {
				settings.memberPostCids = $('#memberPostCids').val();
			}

			// Fix checkbox values
			checkboxes.each(function (idx, inputEl) {
				inputEl = $(inputEl);
				if (inputEl.length) {
					settings[inputEl.attr('name')] = inputEl.prop('checked');
				}
			});

			api.put(`/groups/${ajaxify.data.group.slug}`, settings).then(() => {
				if (settings.name !== ajaxify.data.group.name) {
					let pathname = window.location.pathname;
					pathname = pathname.slice(1, pathname.lastIndexOf('/') + 1);
					ajaxify.go(pathname + slugify(settings.name));
				}

				alerts.success('[[groups:event.updated]]');
			}).catch(alerts.error);
		}
	};

	Details.deleteGroup = function () {
		bootbox.confirm('Are you sure you want to delete the group: ' + utils.escapeHTML(groupName), function (confirm) {
			if (confirm) {
				bootbox.prompt('Please enter the name of this group in order to delete it:', function (response) {
					if (response === groupName) {
						api.del(`/groups/${ajaxify.data.group.slug}`, {}).then(() => {
							alerts.success('[[groups:event.deleted, ' + utils.escapeHTML(groupName) + ']]');
							ajaxify.go('groups');
						}).catch(alerts.error);
					}
				});
			}
		});
	};

	function updatePendingAlertVisibility() {
		$('[component="groups/pending/alert"]').toggleClass(
			'hidden',
			$('[component="groups/pending"] tbody tr').length > 0
		);
	}

	function updateInviteAlertVisibility() {
		$('[component="groups/invited/alert"]').toggleClass(
			'hidden',
			$('[component="groups/invited"] tbody tr').length > 0
		);
	}

	function handleMemberInvitations() {
		if (!ajaxify.data.group.isOwner) {
			return;
		}
		async function updateList() {
			const data = await api.get(`/api/groups/${ajaxify.data.group.slug}`);
			const html = await app.parseAndTranslate('groups/details', 'group.invited', { group: data.group });
			$('[component="groups/invited"] tbody').html(html);
			updateInviteAlertVisibility();
			memberList.refresh();
		}
		const searchInput = $('[component="groups/members/invite"]');
		require(['autocomplete'], function (autocomplete) {
			autocomplete.user(searchInput, function (event, selected) {
				api.post(`/groups/${ajaxify.data.group.slug}/invites/${selected.item.user.uid}`).then(() => updateList()).catch(alerts.error);
			});
		});

		$('[component="groups/members/bulk-invite-button"]').on('click', async () => {
			let usernames = $('[component="groups/members/bulk-invite"]').val();
			if (!usernames) {
				return false;
			}

			// Filter out bad usernames
			usernames = usernames.split(',').map(username => slugify(username));
			usernames = await Promise.all(usernames.map(slug => api.head(`/users/bySlug/${slug}`).then(() => slug).catch(() => false)));
			usernames = usernames.filter(Boolean);

			const uids = await Promise.all(usernames.map(slug => api.get(`/users/bySlug/${slug}`).then(({ uid }) => uid)));

			await Promise.all(uids.map(async uid => api.post(`/groups/${ajaxify.data.group.slug}/invites/${uid}`))).then(() => {
				updateList();
			}).catch(alerts.error);
		});
	}

	function removeCover() {
		bootbox.confirm('[[groups:remove-group-cover-confirm]]', function (confirm) {
			if (!confirm) {
				return;
			}

			socket.emit('groups.cover.remove', {
				groupName: ajaxify.data.group.name,
			}, function (err) {
				if (!err) {
					ajaxify.refresh();
				} else {
					alerts.error(err);
				}
			});
		});
	}

	return Details;
});
