/* global cartcueAdmin, jQuery */
(function ($) {
	'use strict';

	var cfg = window.cartcueAdmin || {};
	var actions = cfg.actions || {};
	var inserterCfg = cfg.actionInserter || {};
	var playUx = cfg.playUx || {};
	var icons = playUx.actionIcons || {};
	var strings = inserterCfg.strings || {};
	var groups = inserterCfg.groups || [];
	var slugGroups = inserterCfg.slugGroups || {};
	var slugKeywords = inserterCfg.keywords || {};

	var $popover = null;
	var $search = null;
	var anchorEl = null;
	var onSelectCallback = null;
	var messagePickerSlugs = null;

	function defaultGroups() {
		return [
			{ id: 'messages', label: strings.messages || 'Messages' },
			{ id: 'woocommerce', label: strings.woocommerce || 'WooCommerce' },
			{ id: 'customer', label: strings.customer || 'Customer' },
			{ id: 'integrations', label: strings.integrations || 'Integrations' },
			{ id: 'workflow', label: strings.workflow || 'Workflow' },
			{ id: 'actions', label: strings.actions || 'Actions' }
		];
	}

	function inferGroup(slug) {
		if (slugGroups[slug]) {
			return slugGroups[slug];
		}
		if (/^(send_email|send_sms|send_whatsapp)$/.test(slug)) {
			return 'messages';
		}
		if (/^(create_coupon|change_order_status|add_order_note|change_customer_role|grant_membership|cancel_membership|add_points|remove_points)$/.test(slug)) {
			return 'woocommerce';
		}
		if (/^(add_customer_tag|remove_customer_tag)$/.test(slug)) {
			return 'customer';
		}
		if (/^(webhook|slack_notification|trigger_another_play)$/.test(slug)) {
			return slug === 'trigger_another_play' ? 'workflow' : 'integrations';
		}
		if (/^(fluentcrm|mailchimp|activecampaign|klaviyo|mailpoet)_/.test(slug)) {
			return 'integrations';
		}
		return 'actions';
	}

	function itemKeywords(slug) {
		if (slugKeywords[slug]) {
			return slugKeywords[slug];
		}
		var label = actions[slug] ? actions[slug].label : slug;
		return [slug.replace(/_/g, ' '), label.toLowerCase()];
	}

	function buildCatalog() {
		var items = [];
		Object.keys(actions).forEach(function (slug) {
			if (!actions[slug]) {
				return;
			}
			items.push({
				slug: slug,
				label: actions[slug].label,
				group: inferGroup(slug),
				keywords: itemKeywords(slug),
				icon: actions[slug].icon || icons[slug] || 'ti-bolt',
				isPro: !!actions[slug].is_pro,
				upgradeHtml: actions[slug].upgrade_html || ''
			});
		});
		return items;
	}

	function ensurePopover() {
		if ($popover && $popover.length) {
			return $popover;
		}

		var searchId = 'ap-action-inserter-search';
		$popover = $(
			'<div class="ap-action-inserter-popover" id="ap-action-inserter-popover" hidden role="dialog" aria-modal="true">' +
				'<div class="block-editor-inserter__menu ap-automation-inserter">' +
					'<div class="block-editor-inserter__main-area">' +
						'<div class="block-editor-inserter__content">' +
							'<div class="block-editor-inserter__search-wrap">' +
								'<span class="block-editor-inserter__search-icon" aria-hidden="true">' +
									'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="20" height="20" fill="currentColor">' +
										'<path d="M13 5c-3.3 0-6 2.7-6 6 0 1.4.5 2.7 1.3 3.7l-3.8 3.8 1.1 1.1 3.8-3.8c1 .8 2.3 1.3 3.7 1.3 3.3 0 6-2.7 6-6S16.3 5 13 5zm0 10.5c-2.5 0-4.5-2-4.5-4.5s2-4.5 4.5-4.5 4.5 2 4.5 4.5-2 4.5-4.5 4.5z"></path>' +
									'</svg>' +
								'</span>' +
								'<input type="search" class="block-editor-inserter__search" id="' + searchId + '" autocomplete="off" placeholder="' + escAttr(strings.searchPlaceholder || 'Search') + '">' +
							'</div>' +
							'<div class="block-editor-inserter__block-list ap-action-inserter-list"></div>' +
						'</div>' +
					'</div>' +
				'</div>' +
			'</div>'
		);

		$search = $popover.find('#' + searchId);
		$('body').append($popover);

		$search.on('input', function () {
			renderList(String($(this).val() || ''));
		});

		$popover.on('click', '.block-editor-block-types-list__item', function () {
			var $btn  = $(this);
			var slug  = $btn.data('actionSlug');
			var group = $btn.data('actionGroup');
			if (group === 'message') {
				openMessagePicker($btn.data('messageSlugs'));
				return;
			}
			if ($btn.data('actionPro')) {
				showActionUpgradeGate(slug);
				return;
			}
			if (slug) {
				selectSlug(slug);
			}
		});

		$(document).on('mousedown.apActionInserter', function (e) {
			if (!$popover || $popover.prop('hidden')) {
				return;
			}
			var $target = $(e.target);
			if ($popover.is($target) || $popover.has($target).length) {
				return;
			}
			if (anchorEl && (anchorEl === e.target || $.contains(anchorEl, e.target))) {
				return;
			}
			close();
		});

		$(document).on('keydown.apActionInserter', function (e) {
			if (!$popover || $popover.prop('hidden')) {
				return;
			}
			if (e.key === 'Escape') {
				e.preventDefault();
				close();
			}
		});

		$(window).on('resize scroll.apActionInserter', function () {
			if (!$popover || $popover.prop('hidden') || !anchorEl) {
				return;
			}
			positionPopover(anchorEl);
		});

		return $popover;
	}

	function escAttr(str) {
		return String(str)
			.replace(/&/g, '&amp;')
			.replace(/"/g, '&quot;')
			.replace(/</g, '&lt;')
			.replace(/>/g, '&gt;');
	}

	function availableMessageSlugs() {
		var base = Array.isArray(cfg.messageActionSlugs) && cfg.messageActionSlugs.length
			? cfg.messageActionSlugs.slice()
			: ['send_email', 'send_sms', 'send_whatsapp'];
		return base.filter(function (slug) {
			return !!actions[slug];
		});
	}

	function filterItems(query) {
		var q = query.trim().toLowerCase();
		var catalog = buildCatalog();
		if (!q) {
			return catalog;
		}
		return catalog.filter(function (item) {
			var hay = item.keywords.concat([item.label]).join(' ').toLowerCase();
			return hay.indexOf(q) !== -1;
		});
	}

	function renderItemButton(item) {
		var proBadge = item.isPro
			? '<span class="ap-pro-badge">' + escAttr(strings.proBadge || 'Pro') + '</span>'
			: '';
		return (
			'<div class="block-editor-block-types-list__list-item">' +
				'<button type="button" class="block-editor-block-types-list__item' + (item.isPro ? ' is-pro' : '') + '" data-action-slug="' + escAttr(item.slug) + '"' + (item.isPro ? ' data-action-pro="1"' : '') + '>' +
					'<span class="block-editor-block-types-list__item-icon">' +
						'<span class="block-editor-block-icon"><i class="ti ' + escAttr(item.icon) + '" aria-hidden="true"></i></span>' +
					'</span>' +
					'<span class="block-editor-block-types-list__item-title">' + escAttr(item.label) + '</span>' +
					proBadge +
				'</button>' +
			'</div>'
		);
	}

	function renderMessageGroupButton(messageSlugs) {
		var label = playUx.sendMessageLabel || strings.sendMessage || 'Send a message';
		return (
			'<div class="block-editor-block-types-list__list-item">' +
				'<button type="button" class="block-editor-block-types-list__item" data-action-group="message" data-message-slugs="' + escAttr(messageSlugs.join(',')) + '">' +
					'<span class="block-editor-block-types-list__item-icon">' +
						'<span class="block-editor-block-icon"><i class="ti ti-message" aria-hidden="true"></i></span>' +
					'</span>' +
					'<span class="block-editor-block-types-list__item-title">' + escAttr(label) + '</span>' +
				'</button>' +
			'</div>'
		);
	}

	function renderList(query) {
		var $list = $popover.find('.ap-action-inserter-list');
		var items = filterItems(query);
		var groupDefs = groups.length ? groups : defaultGroups();
		var groupMap = {};
		var messageSlugs = availableMessageSlugs();
		var useMessageGroup = messageSlugs.length > 1 && !query.trim();

		groupDefs.forEach(function (g) {
			groupMap[g.id] = { label: g.label, items: [] };
		});

		items.forEach(function (item) {
			if (useMessageGroup && messageSlugs.indexOf(item.slug) !== -1) {
				return;
			}
			if (!groupMap[item.group]) {
				groupMap[item.group] = { label: item.group, items: [] };
			}
			groupMap[item.group].items.push(item);
		});

		var html = '';
		groupDefs.forEach(function (g) {
			var bucket = groupMap[g.id];
			if (!bucket || !bucket.items.length) {
				if (g.id === 'messages' && useMessageGroup && messageSlugs.length) {
					html += renderSection(g.label, [renderMessageGroupButton(messageSlugs)]);
				}
				return;
			}
			var rowHtml = [];
			if (g.id === 'messages' && useMessageGroup && messageSlugs.length) {
				bucket.items = [{ slug: '__message_group__' }].concat(bucket.items);
			}
			var displayItems = bucket.items.filter(function (it) {
				return it.slug !== '__message_group__';
			});
			var buttons = [];
			if (g.id === 'messages' && useMessageGroup && messageSlugs.length) {
				buttons.push(renderMessageGroupButton(messageSlugs));
			}
			displayItems.forEach(function (it) {
				buttons.push(renderItemButton(it));
			});
			if (!buttons.length) {
				return;
			}
			html += renderSection(g.label, buttons);
		});

		if (!html) {
			html = '<div class="block-editor-inserter__no-results">' +
				escAttr(strings.noResults || 'No results found.') +
			'</div>';
		}

		$list.html(html);
	}

	function renderSection(title, buttonHtmlArr) {
		return (
			'<div class="block-editor-inserter__panel-header">' +
				'<h2 class="block-editor-inserter__panel-title"><div>' + escAttr(title) + '</div></h2>' +
			'</div>' +
			'<div class="block-editor-inserter__panel-content">' +
				'<div role="listbox" aria-orientation="vertical" class="block-editor-block-types-list" aria-label="' + escAttr(title) + '">' +
					buttonHtmlArr.join('') +
				'</div>' +
			'</div>'
		);
	}

	function openMessagePicker(slugsCsv) {
		var slugs = String(slugsCsv || '').split(',').map(function (s) { return s.trim(); }).filter(Boolean);
		if (!slugs.length) {
			return;
		}
		messagePickerSlugs = slugs;
		var buttons = slugs.map(function (slug) {
			if (!actions[slug]) {
				return '';
			}
			return renderItemButton({
				slug: slug,
				label: actions[slug].label,
				icon: actions[slug].icon || icons[slug] || 'ti-message',
				isPro: !!actions[slug].is_pro,
				upgradeHtml: actions[slug].upgrade_html || ''
			});
		}).filter(Boolean);

		var $list = $popover.find('.ap-action-inserter-list');
		$list.html(
			'<div class="ap-action-inserter-back">' +
				'<button type="button" class="ap-btn ap-btn-ghost ap-btn-sm ap-action-inserter-back-btn">' +
					escAttr(strings.back || '← Back') +
				'</button>' +
			'</div>' +
			renderSection(strings.chooseChannel || 'Choose channel', buttons)
		);

		$list.find('.ap-action-inserter-back-btn').on('click', function (e) {
			e.preventDefault();
			messagePickerSlugs = null;
			renderList($search.val() || '');
		});
	}

	function showActionUpgradeGate(slug) {
		var html  = (actions[slug] && actions[slug].upgrade_html) || '';
		var $list = $popover.find('.ap-action-inserter-list');
		var back  =
			'<div class="ap-action-inserter-back">' +
				'<button type="button" class="ap-btn ap-btn-ghost ap-btn-sm ap-action-inserter-back-btn">' +
					'\u2190 ' + escAttr(strings.back || 'Back') +
				'</button>' +
			'</div>';
		$list.html(back + '<div class="ap-action-inserter-progate">' + html + '</div>');
		$list.find('.ap-action-inserter-back-btn').on('click', function (e) {
			e.preventDefault();
			renderList(String($search.val() || ''));
		});
	}

	function positionPopover(anchor) {
		if (!anchor || !$popover || !$popover.length) {
			return;
		}
		var rect = anchor.getBoundingClientRect();
		var popW = $popover.outerWidth() || 365;
		var popH = $popover.outerHeight() || 320;
		var top = rect.bottom + 8;
		var left = rect.left + rect.width / 2 - popW / 2;

		if (!rect.width && !rect.height) {
			top = Math.max(8, (window.innerHeight - popH) / 2);
			left = Math.max(8, (window.innerWidth - popW) / 2);
		} else {
			left = Math.max(8, Math.min(left, window.innerWidth - popW - 8));
			if (rect.bottom + popH + 16 > window.innerHeight && rect.top > popH + 16) {
				top = rect.top - popH - 8;
			}
			top = Math.max(8, Math.min(top, window.innerHeight - popH - 8));
		}

		$popover.css({ position: 'fixed', top: top + 'px', left: left + 'px' });
	}

	function selectSlug(slug) {
		if (typeof onSelectCallback === 'function') {
			onSelectCallback(slug);
		}
		close();
	}

	function setBodyOpen(isOpen) {
		document.body.classList.toggle('is-ap-action-inserter-open', isOpen);
		if (isOpen) {
			$('.ap-action-type-grid').attr('hidden', 'hidden');
		}
	}

	function open(anchor, callback) {
		anchorEl = anchor;
		onSelectCallback = callback;
		messagePickerSlugs = null;
		ensurePopover();
		renderList('');
		$search.val('');
		setBodyOpen(true);
		$popover.prop('hidden', false).attr('aria-hidden', 'false');
		positionPopover(anchor);
		window.requestAnimationFrame(function () {
			positionPopover(anchor);
		});
		window.setTimeout(function () {
			$search.trigger('focus');
		}, 0);
	}

	function close() {
		if (!$popover) {
			return;
		}
		$popover.prop('hidden', true).attr('aria-hidden', 'true');
		setBodyOpen(false);
		anchorEl = null;
		onSelectCallback = null;
		messagePickerSlugs = null;
		$(document).trigger('apActionInserterClose');
	}

	function isOpen() {
		return $popover && !$popover.prop('hidden');
	}

	window.apActionInserter = {
		open: open,
		close: close,
		isOpen: isOpen,
		buildTriggerButton: function (label) {
			var txt = label || strings.chooseAction || 'Take action';
			return $(
				'<button type="button" class="ap-btn ap-btn-ghost ap-action-inserter-trigger">' +
					'<span class="ap-action-inserter-trigger__icon" aria-hidden="true">+</span> ' +
					escAttr(txt) +
				'</button>'
			);
		}
	};
}(jQuery));
