/**
 * List table layout: horizontal scroll wrapper, sticky header, freeze columns.
 */
(function () {
	'use strict';

	var cfg = window.wppsAdminColumnsListTable || {};
	var WRAPPER_ID = 'wpps-list-table-wrapper';
	var CONTAINER_CLASS = 'wpps-list-table-scroll-container';
	var SHADOW_CLASS = 'wpps-list-table-scroll-shadow';

	function isWrapperEnabled() {
		return !cfg.disableHorizontalScroll;
	}

	function getWrapper() {
		return document.getElementById(WRAPPER_ID);
	}

	function getListTable() {
		var wrapper = getWrapper();
		if (wrapper) {
			return wrapper.querySelector('.wp-list-table');
		}

		return document.querySelector('.wp-list-table');
	}

	function getAdminBarHeight() {
		var adminBar = document.getElementById('wpadminbar');
		if (!adminBar) {
			return 0;
		}

		return adminBar.getBoundingClientRect().height || 0;
	}

	function getScrollContainer() {
		var wrapper = getWrapper();
		if (!wrapper || !wrapper.parentElement) {
			return null;
		}

		if (wrapper.parentElement.classList.contains(CONTAINER_CLASS)) {
			return wrapper.parentElement;
		}

		return null;
	}

	function ensureScrollShadowMarkup() {
		var wrapper = getWrapper();
		if (!wrapper) {
			return;
		}

		var container = getScrollContainer();
		if (!container) {
			container = document.createElement('div');
			container.className = CONTAINER_CLASS;
			wrapper.parentNode.insertBefore(container, wrapper);
			container.appendChild(wrapper);
		}

		if (!container.querySelector('.' + SHADOW_CLASS)) {
			var shadow = document.createElement('div');
			shadow.className = SHADOW_CLASS;
			shadow.setAttribute('aria-hidden', 'true');
			container.appendChild(shadow);
		}

		if (!wrapper.dataset.wppsScrollShadowBound) {
			wrapper.addEventListener('scroll', updateHScrollClass, { passive: true });
			wrapper.dataset.wppsScrollShadowBound = '1';
		}
	}

	function updateHScrollClass() {
		if (!isWrapperEnabled()) {
			return;
		}

		var wrapper = getWrapper();
		var table = wrapper ? wrapper.querySelector('.wp-list-table') : null;
		if (!wrapper || !table) {
			return;
		}

		ensureScrollShadowMarkup();

		var container = getScrollContainer();
		var isScrollable = table.offsetWidth > wrapper.clientWidth;

		if (isScrollable) {
			wrapper.classList.add('h-scrollable');
			if (container) {
				container.classList.add('has-scroll');
			}
		} else {
			wrapper.classList.remove('h-scrollable');
			if (container) {
				container.classList.remove('has-scroll');
			}
		}
	}

	function clearFrozenColumns(listTable) {
		if (!listTable) {
			return;
		}

		listTable.querySelectorAll('.wpps-acc-frozen, .wpps-acc-last-frozen').forEach(function (cell) {
			cell.classList.remove('wpps-acc-frozen');
			cell.classList.remove('wpps-acc-last-frozen');
			cell.style.left = '';
		});
	}

	function applyFrozenColumns() {
		if (!isWrapperEnabled()) {
			return;
		}

		var wrapper = getWrapper();
		var listTable = wrapper ? wrapper.querySelector('.wp-list-table') : null;
		if (!wrapper || !listTable) {
			return;
		}

		clearFrozenColumns(listTable);
		updateHScrollClass();

		if (!wrapper.classList.contains('h-scrollable')) {
			return;
		}

		var freezeDataColumns = parseInt(cfg.freezeFirstColumns, 10) || 0;
		if (freezeDataColumns < 1) {
			return;
		}
		if (freezeDataColumns > 5) {
			freezeDataColumns = 5;
		}

		var headRow = listTable.tHead && listTable.tHead.rows.length
			? listTable.tHead.rows[0]
			: listTable.querySelector('thead tr');
		if (!headRow || !headRow.cells || !headRow.cells.length) {
			return;
		}

		var freezeTotalCells = Math.min(1 + freezeDataColumns, headRow.cells.length);
		if (freezeTotalCells <= 0) {
			return;
		}

		var leftOffsets = [];
		var currentLeft = 0;

		for (var i = 0; i < freezeTotalCells; i++) {
			leftOffsets[i] = currentLeft;
			var headCell = headRow.cells[i];
			if (!headCell) {
				break;
			}
			currentLeft += headCell.getBoundingClientRect().width;
		}

		function applyToRow(row) {
			if (!row || !row.cells || !row.cells.length) {
				return;
			}
			if (row.classList && (row.classList.contains('inline-edit-row') || row.classList.contains('no-items'))) {
				return;
			}

			for (var j = 0; j < freezeTotalCells; j++) {
				var cell = row.cells[j];
				if (!cell) {
					continue;
				}

				cell.classList.add('wpps-acc-frozen');
				cell.style.left = leftOffsets[j] + 'px';

				if (j === freezeTotalCells - 1) {
					cell.classList.add('wpps-acc-last-frozen');
				} else {
					cell.classList.remove('wpps-acc-last-frozen');
				}
			}
		}

		if (listTable.tHead && listTable.tHead.rows) {
			Array.prototype.forEach.call(listTable.tHead.rows, applyToRow);
		}
		if (listTable.tBodies && listTable.tBodies.length) {
			Array.prototype.forEach.call(listTable.tBodies, function (tbody) {
				if (tbody && tbody.rows) {
					Array.prototype.forEach.call(tbody.rows, applyToRow);
				}
			});
		}
		if (listTable.tFoot && listTable.tFoot.rows) {
			Array.prototype.forEach.call(listTable.tFoot.rows, applyToRow);
		}
	}

	function initFreezeHeaderRow() {
		var listTable = getListTable();
		if (!listTable) {
			return null;
		}

		var head = listTable.tHead || listTable.querySelector('thead');
		if (!head) {
			return null;
		}

		var ticking = false;

		function update() {
			ticking = false;

			if (!cfg.freezeHeaderRow) {
				listTable.classList.remove('wpps-acc-freeze-header-row');
				head.style.transform = '';
				return;
			}

			listTable.classList.add('wpps-acc-freeze-header-row');

			if (!listTable.offsetParent) {
				return;
			}

			var topOffset = getAdminBarHeight();
			var tableRect = listTable.getBoundingClientRect();
			var headRect = head.getBoundingClientRect();

			if (tableRect.bottom <= topOffset || tableRect.top >= window.innerHeight) {
				head.style.transform = '';
				return;
			}

			var maxTranslate = Math.max(0, tableRect.height - headRect.height);
			var desired = Math.max(0, topOffset - tableRect.top);
			var translateY = Math.min(desired, maxTranslate);

			head.style.transform = translateY ? 'translate3d(0,' + translateY + 'px,0)' : '';
		}

		function requestUpdate() {
			if (ticking) {
				return;
			}
			ticking = true;
			window.requestAnimationFrame(update);
		}

		requestUpdate();
		window.addEventListener('scroll', requestUpdate, { passive: true });
		window.addEventListener('resize', requestUpdate);

		return requestUpdate;
	}

	function initListTableWrapper() {
		if (!isWrapperEnabled()) {
			return;
		}

		var listTableWrapper = document.getElementById(WRAPPER_ID);
		var listTable = document.querySelector('.wp-list-table');

		if (!listTableWrapper || !listTable) {
			return;
		}

		if (!listTableWrapper.contains(listTable)) {
			var container = listTableWrapper.closest('.' + CONTAINER_CLASS);
			if (container) {
				listTable.parentNode.insertBefore(container, listTable);
			} else {
				listTable.parentNode.insertBefore(listTableWrapper, listTable);
			}
			listTableWrapper.appendChild(listTable);
		}

		if (!listTableWrapper.dataset.wppsScrollShadowBound) {
			listTableWrapper.addEventListener('scroll', updateHScrollClass, { passive: true });
			listTableWrapper.dataset.wppsScrollShadowBound = '1';
		}

		ensureScrollShadowMarkup();
		updateHScrollClass();
		applyFrozenColumns();
	}

	function initRowEnhancements(row) {
		if (!row || row.nodeType !== 1 || row.getAttribute('data-wpps-acc-inited') === '1') {
			return;
		}

		row.setAttribute('data-wpps-acc-inited', '1');
		updateHScrollClass();
		applyFrozenColumns();
	}

	function observeListTable() {
		if (!isWrapperEnabled() || typeof MutationObserver === 'undefined') {
			return;
		}

		var list = document.getElementById('the-list');
		if (!list) {
			return;
		}

		var observer = new MutationObserver(function (mutations) {
			mutations.forEach(function (mutation) {
				if (!mutation.addedNodes || !mutation.addedNodes.length) {
					return;
				}

				Array.prototype.forEach.call(mutation.addedNodes, function (node) {
					if (!node || node.nodeType !== 1) {
						return;
					}

					if (node.id && node.id.indexOf('post-') === 0) {
						initRowEnhancements(node);
					}

					if (node.querySelectorAll) {
						node.querySelectorAll('tr[id^="post-"]').forEach(function (row) {
							initRowEnhancements(row);
						});
					}
				});
			});
		});

		observer.observe(list, { childList: true });
	}

	function bindResponsiveToggleFix() {
		document.addEventListener('click', function (event) {
			var toggle = event.target.closest('.wp-list-table .column-primary .toggle-row');
			if (!toggle) {
				return;
			}

			var row = toggle.closest('tr.hentry');
			if (!row) {
				return;
			}

			var checkColumn = row.querySelector('th.check-column');
			var primaryColumn = row.querySelector('td.column-primary');
			if (checkColumn && primaryColumn) {
				checkColumn.insertAdjacentElement('afterend', primaryColumn);
			}

			window.setTimeout(applyFrozenColumns, 0);
		});
	}

	function init() {
		initListTableWrapper();
		var requestFreezeHeaderUpdate = initFreezeHeaderRow();
		observeListTable();
		bindResponsiveToggleFix();

		var resizeTimer = null;
		window.addEventListener('resize', function () {
			if (resizeTimer) {
				window.clearTimeout(resizeTimer);
			}
			resizeTimer = window.setTimeout(function () {
				updateHScrollClass();
				applyFrozenColumns();
				if (requestFreezeHeaderUpdate) {
					requestFreezeHeaderUpdate();
				}
			}, 150);
		});
	}

	if (document.readyState === 'loading') {
		document.addEventListener('DOMContentLoaded', init);
	} else {
		init();
	}
})();
