'use strict';


define('forum/post-queue', [
	'categoryFilter', 'categorySelector', 'api', 'alerts', 'bootbox',
	'accounts/moderate', 'accounts/delete',
], function (
	categoryFilter, categorySelector, api, alerts, bootbox,
	AccountModerate, AccountsDelete
) {
	const PostQueue = {};

	PostQueue.init = function () {
		$('[data-bs-toggle="tooltip"]').tooltip();

		categoryFilter.init($('[component="category/dropdown"]'), {
			privilege: 'moderate',
		});

		handleActions();
		handleBulkActions();
		handleContentEdit('[data-action="editContent"]', '.post-content-editable', 'textarea', '.post-content');
		handleContentEdit('[data-action="editTitle"]', '.topic-title-editable', 'input', '.topic-title');

		$('.posts-list').on('click', '.topic-category[data-editable]', function (e) {
			handleCategoryChange(this);
			e.stopPropagation();
			e.preventDefault();
		});

		$('[component="post/content"] img:not(.not-responsive)').addClass('img-fluid');
	};

	function confirmReject(msg) {
		return new Promise((resolve) => {
			bootbox.confirm(msg, resolve);
		});
	}

	function handleContentEdit(triggerClass, editableClass, inputSelector, displayClass) {
		$('.posts-list').on('click', triggerClass, function () {
			const el = $(this);
			const inputEl = el.parents('[data-id]').find(editableClass);
			const displayEl = el.parents('[data-id]').find(displayClass);
			if (inputEl.length) {
				displayEl.addClass('hidden');
				inputEl.removeClass('hidden').find(inputSelector).focus();
			}
		});

		$('.posts-list').on('blur', editableClass + ' ' + inputSelector, function () {
			const textarea = $(this);
			const preview = textarea.parent().parent().find(displayClass);
			const id = textarea.parents('[data-id]').attr('data-id');
			const titleEdit = triggerClass === '[data-action="editTitle"]';

			socket.emit('posts.editQueuedContent', {
				id: id,
				title: titleEdit ? textarea.val() : undefined,
				content: titleEdit ? undefined : textarea.val(),
			}, function (err, data) {
				if (err) {
					return alerts.error(err);
				}
				if (titleEdit) {
					preview.find('.title-text').text(data.postData.title);
				} else {
					preview.html(data.postData.content);
				}

				textarea.parent().addClass('hidden');
				preview.removeClass('hidden');
			});
		});
	}

	function handleCategoryChange(categoryEl) {
		const $this = $(categoryEl);
		const id = $this.parents('[data-id]').attr('data-id');
		categorySelector.modal({
			onSubmit: function (selectedCategory) {
				Promise.all([
					api.get(`/categories/${selectedCategory.cid}`, {}),
					socket.emit('posts.editQueuedContent', {
						id: id,
						cid: selectedCategory.cid,
					}),
				]).then(function (result) {
					const category = result[0];
					app.parseAndTranslate('post-queue', 'posts', {
						posts: [{
							category: category,
						}],
					}, function (html) {
						if ($this.find('.category-text').length) {
							$this.find('.category-text').text(html.find('.topic-category .category-text').text());
						} else {
							// for backwards compatibility, remove in 1.16.0
							$this.replaceWith(html.find('.topic-category'));
						}
					});
				}).catch(alerts.error);
			},
		});
		return false;
	}

	function handleActions() {
		const listEl = document.querySelector('.posts-list');
		if (listEl) {
			listEl.addEventListener('click', (e) => {
				const subselector = e.target.closest('[data-action]');
				if (subselector) {
					const action = subselector.getAttribute('data-action');
					const uid = subselector.closest('[data-uid]').getAttribute('data-uid');
					switch (action) {
						case 'editCategory': {
							const categoryEl = e.target.closest('[data-id]').querySelector('.topic-category');
							handleCategoryChange(categoryEl);
							break;
						}

						case 'ban':
							AccountModerate.banAccount(uid, ajaxify.refresh);
							break;

						case 'unban':
							AccountModerate.unbanAccount(uid);
							break;

						case 'mute':
							AccountModerate.muteAccount(uid, ajaxify.refresh);
							break;

						case 'unmute':
							AccountModerate.unmuteAccount(uid);
							break;

						case 'delete-account':
							AccountsDelete.account(uid, ajaxify.go.bind(null, 'post-queue'));
							break;

						case 'delete-content':
							AccountsDelete.content(uid, ajaxify.go.bind(null, 'post-queue'));
							break;

						case 'delete-all':
							AccountsDelete.purge(uid, ajaxify.go.bind(null, 'post-queue'));
							break;

						default:
							handleQueueActions.call(e.target);
							break;
					}
				}
			});
		}
	}

	async function handleQueueActions() {
		// accept, reject, notify
		function getMessage() {
			return new Promise((resolve) => {
				const modal = bootbox.dialog({
					title: '[[post-queue:notify-user]]',
					message: '<textarea class="form-control"></textarea>',
					buttons: {
						OK: {
							label: '[[modules:bootbox.send]]',
							callback: function () {
								const val = modal.find('textarea').val();
								if (val) {
									resolve(val);
								}
							},
						},
					},
				});
			});
		}

		const parent = $(this).parents('[data-id]');
		const action = $(this).attr('data-action');
		const id = parent.attr('data-id');
		const listContainer = parent.get(0).parentNode;

		if ((!['accept', 'reject', 'notify'].includes(action)) ||
			(action === 'reject' && !await confirmReject(ajaxify.data.canAccept ? '[[post-queue:confirm-reject]]' : '[[post-queue:confirm-remove]]'))) {
			return;
		}

		socket.emit('posts.' + action, {
			id: id,
			message: action === 'notify' ? await getMessage() : undefined,
		}, function (err) {
			if (err) {
				return alerts.error(err);
			}
			if (action === 'accept' || action === 'reject') {
				parent.remove();
			}

			if (listContainer.childElementCount === 0) {
				if (ajaxify.data.singlePost) {
					ajaxify.go('/post-queue' + window.location.search);
				} else {
					ajaxify.refresh();
				}
			}
		});
		return false;
	}

	function handleBulkActions() {
		$('[component="post-queue/bulk-actions"]').on('click', '[data-action]', async function () {
			const bulkAction = $(this).attr('data-action');
			let queueEls = $('.posts-list [data-id]');
			if (bulkAction === 'accept-selected' || bulkAction === 'reject-selected') {
				queueEls = queueEls.filter(
					(i, el) => $(el).find('input[type="checkbox"]').is(':checked')
				);
			}
			const ids = queueEls.map((i, el) => $(el).attr('data-id')).get();
			const showConfirm = bulkAction === 'reject-all' || bulkAction === 'reject-selected';
			const translationString = ajaxify.data.canAccept ?
				`${bulkAction}-confirm` :
				`${bulkAction.replace(/^reject/, 'remove')}-confirm`;
			if (!ids.length || (showConfirm && !(await confirmReject(`[[post-queue:${translationString}, ${ids.length}]]`)))) {
				return;
			}
			const action = bulkAction.split('-')[0];
			const promises = ids.map(id => socket.emit('posts.' + action, { id: id }));

			Promise.allSettled(promises).then(function (results) {
				const fulfilled = results.filter(res => res.status === 'fulfilled').length;
				const errors = results.filter(res => res.status === 'rejected');
				if (fulfilled) {
					alerts.success(`[[post-queue:bulk-${action}-success, ${fulfilled}]]`);
					ajaxify.refresh();
				}

				errors.forEach(res => alerts.error(res.reason));
			});
		});
	}

	return PostQueue;
});