// Tailwind-styled DataTable with buttons dropdown and bulk delete hook.
function fire_datatable(req_url, tableId = "DataTables") {
	const selector = "#" + tableId;
	if (!$(selector).length) return;
	const $table = $(selector);
	const currentSourceUrl = $table.attr("data-erp-datatable-source-url") || "";
	if ($.fn.dataTable && $.fn.dataTable.isDataTable(selector)) {
		if (!currentSourceUrl || currentSourceUrl !== req_url) {
			$table.DataTable().clear().destroy(false);
			$table.find("tbody").empty();
			$table.removeAttr("data-erp-datatable-source-url");
		} else {
			$table.attr("data-erp-datatable-source-url", req_url);
			return $table.DataTable();
		}
	}
	const $wrapper = $table.closest(".dataTables_wrapper");
	if ($wrapper.length && !$.fn.dataTable.isDataTable(selector)) {
		$wrapper.find(".dt-layout-row, .dataTables_info, .dataTables_paginate, .dataTables_length, .dataTables_filter, .dt-buttons").remove();
		if ($wrapper.attr("id") === tableId + "_wrapper") {
			$table.insertBefore($wrapper);
			$wrapper.remove();
		}
	}

	function cloneRequestPayload(requestData) {
		return JSON.parse(JSON.stringify(requestData || {}));
	}

	function normalizeRequestPayload(requestData) {
		const payload = cloneRequestPayload(requestData);
		delete payload.draw;
		delete payload.csrf_token;
		return payload;
	}

	function isDefaultFirstPageRequest(requestData) {
		const payload = normalizeRequestPayload(requestData);
		const start = parseInt(payload.start || 0, 10) || 0;
		const length = parseInt(payload.length || tables_pagination_limit, 10) || tables_pagination_limit;
		const searchValue = payload.search && payload.search.value ? String(payload.search.value).trim() : "";
		const ordered = Array.isArray(payload.order) && payload.order.length > 0;
		return start === 0 && length === tables_pagination_limit && searchValue === "" && !ordered;
	}

	function readPreloadedResponse(url, requestData) {
		const preloadBuckets = window.erpDatatablePreload || {};
		const tableBucket = preloadBuckets[tableId] || {};
		if (!isDefaultFirstPageRequest(requestData)) {
			return null;
		}
		if (!tableBucket[url]) {
			return null;
		}
		const payload = tableBucket[url];
		delete tableBucket[url];
		return payload;
	}

	function normalizeResponseForRequest(payload, requestData) {
		if (!payload || !Array.isArray(payload.data)) {
			return null;
		}
		const response = cloneRequestPayload(payload);
		response.draw = parseInt(requestData.draw || response.draw || 1, 10) || 1;
		response.recordsTotal = parseInt(response.recordsTotal || 0, 10) || 0;
		response.recordsFiltered = parseInt(response.recordsFiltered || 0, 10) || 0;
		return response;
	}

	window.erpWarmDatatableCache = function(url, requestData, payload, targetTableId = "DataTables") {
		return;
	};

	window.erpInvalidateDatatableCache = function() {
		return;
	};

	const length_options = [10, 25, 50, 100];
	const length_options_names = [10, 25, 50, 100];
	if ($.inArray(tables_pagination_limit, length_options) === -1) {
		length_options.push(tables_pagination_limit);
		length_options_names.push(tables_pagination_limit);
	}
	length_options.sort((a, b) => a - b);
	length_options_names.sort((a, b) => a - b);

	const buttonExportOptions = {
		format: {
			body: function (data) {
				return $.trim((data || "").replace(/(<([^>]+)>)/gi, ""));
			},
		},
		columns: ":not(:last-child)",
	};

	function customizePdfExport(doc) {
		const tableNode = Array.isArray(doc.content)
			? doc.content.find(function (node) {
				return node && node.table && Array.isArray(node.table.body);
			})
			: null;

		const body = tableNode && tableNode.table && Array.isArray(tableNode.table.body)
			? tableNode.table.body
			: [];
		const columnCount = body.length && Array.isArray(body[0]) ? body[0].length : 0;

		doc.pageSize = "A4";
		doc.pageOrientation = columnCount > 5 ? "landscape" : "portrait";
		doc.pageMargins = [8, 12, 8, 12];
		doc.defaultStyle = {
			fontSize: 9,
			color: "#0f172a",
		};

		doc.styles = doc.styles || {};
		doc.styles.title = {
			alignment: "center",
			fontSize: 18,
			bold: true,
			color: "#0f172a",
			margin: [0, 0, 0, 8],
		};
		doc.styles.tableHeader = {
			bold: true,
			fontSize: 10,
			color: "#ffffff",
			fillColor: "#334155",
			alignment: "left",
			margin: [0, 6, 0, 6],
		};

		if (tableNode) {
			tableNode.layout = {
				hLineColor: function () {
					return "#dbe2ea";
				},
				vLineColor: function () {
					return "#e2e8f0";
				},
				hLineWidth: function () {
					return 0.8;
				},
				vLineWidth: function () {
					return 0.8;
				},
				paddingLeft: function () {
					return 2;
				},
				paddingRight: function () {
					return 2;
				},
				paddingTop: function () {
					return 2;
				},
				paddingBottom: function () {
					return 2;
				},
				fillColor: function (rowIndex) {
					if (rowIndex === 0) {
						return "#334155";
					}
					return rowIndex % 2 === 0 ? "#f8fafc" : null;
				},
			};

			if (columnCount > 0) {
				tableNode.table.headerRows = 1;
				tableNode.table.widths = Array(columnCount).fill((100 / columnCount).toFixed(2) + "%");
			}
		}
	}

	const loadedScripts = {};

	function loadScriptOnce(src) {
		if (!src) {
			return Promise.resolve();
		}
		if (loadedScripts[src]) {
			return loadedScripts[src];
		}
		loadedScripts[src] = new Promise(function(resolve, reject) {
			const existing = document.querySelector('script[src="' + src + '"]');
			if (existing) {
				if (existing.dataset.loaded === "1") {
					resolve();
					return;
				}
				existing.addEventListener("load", function() {
					existing.dataset.loaded = "1";
					resolve();
				}, { once: true });
				existing.addEventListener("error", reject, { once: true });
				return;
			}
			const script = document.createElement("script");
			script.src = src;
			script.async = true;
			script.onload = function() {
				script.dataset.loaded = "1";
				resolve();
			};
			script.onerror = reject;
			document.body.appendChild(script);
		});
		return loadedScripts[src];
	}

	function ensureExportDependencies(exportType) {
		const assets = window.erpDataTableAssets || {};
		let chain = Promise.resolve();
		if (!$.fn.dataTable.ext.buttons.csvHtml5 || !$.fn.dataTable.ext.buttons.excelHtml5 || !$.fn.dataTable.ext.buttons.pdfHtml5) {
			chain = chain.then(function() {
				return loadScriptOnce(assets.buttonsHtml5);
			});
		}
		if (exportType === "excelHtml5") {
			chain = chain.then(function() {
				return loadScriptOnce(assets.jszip);
			});
		}
		if (exportType === "pdfHtml5") {
			chain = chain.then(function() {
				return loadScriptOnce(assets.pdfmake);
			}).then(function() {
				return loadScriptOnce(assets.vfsFonts);
			});
		}
		return chain;
	}

	function makeDeferredExportButton(exportType, text, extraConfig) {
		return {
			text: text,
			action: function(e, dt, node, config) {
				const $node = $(node);
				const originalHtml = $node.html();
				$node.prop("disabled", true).addClass("opacity-60");
				$node.html('<span class="inline-flex items-center gap-2"><span class="inline-block h-3 w-3 animate-spin rounded-full border-2 border-current border-r-transparent"></span><span>Loading</span></span>');
				ensureExportDependencies(exportType).then(function() {
					const baseButton = $.fn.dataTable.ext.buttons[exportType];
					if (!baseButton || typeof baseButton.action !== "function") {
						throw new Error("Export button type unavailable");
					}
					const finalConfig = $.extend(true, {}, config, extraConfig || {}, {
						exportOptions: buttonExportOptions
					});
					baseButton.action.call(this, e, dt, node, finalConfig);
				}.bind(this)).catch(function() {
					if (window.toastr && typeof window.toastr.error === "function") {
						window.toastr.error("Could not load export tools");
					}
				}).finally(function() {
					$node.prop("disabled", false).removeClass("opacity-60");
					$node.html(originalHtml);
				});
			}
		};
	}

	function applyResponsiveTableClasses(wrapper) {
		if (!wrapper) return;
		const root = wrapper instanceof Element ? wrapper : wrapper.get(0);
		if (!root) return;

		root.classList.add("flex", "flex-col", "gap-3");

		const widths = root.querySelectorAll(
			".dataTables_filter, .dataTables_length, .dt-buttons, .dataTables_info, .dataTables_paginate"
		);
		// widths.forEach(function (node) {
		// 	node.classList.add("w-full");
		// });

		root.querySelectorAll(".dataTables_length label, .dataTables_filter label").forEach(function (node) {
			node.classList.add("flex", "w-full", "flex-wrap", "items-start", "gap-2");
		});

		root.querySelectorAll(".dataTables_length select, .dt-search-input, .dt-buttons .dt-button").forEach(function (node) {
			node.classList.add("w-full", "sm:w-auto");
		});

		root.querySelectorAll(".dt-buttons").forEach(function (node) {
			node.classList.add("flex", "flex-wrap", "gap-2");
		});

		root.querySelectorAll(".dataTables_paginate").forEach(function (node) {
			node.classList.add("flex", "flex-wrap", "items-center","justify-start", "gap-1");
		});

		root.querySelectorAll(".paginate_button").forEach(function (node) {
			node.classList.add("!ml-0");
		});
	}

	function syncBulkDeleteButtonState(wrapper) {
		if (!wrapper) return;
		const root = wrapper instanceof Element ? wrapper : wrapper.get(0);
		if (!root) return;
		const rowChecks = root.querySelectorAll('tbody input[type="checkbox"]:not(#select_all):not(:disabled)');
		const hasChecked = Array.from(rowChecks).some(function (checkbox) {
			return checkbox.checked;
		});
		const bulkButtons = root.querySelectorAll('.dt-bulk-delete, [id$="BulkDelete"], [id*="BulkDelete"], #bulk_delete');
		bulkButtons.forEach(function (button) {
			if (!button) return;
			// button.classList.toggle('!is-visible', hasChecked);
			// button.classList.toggle('!hidden', !hasChecked);
			button.hidden = !hasChecked;
			button.style.display = hasChecked ? 'inline-flex !important' : 'none !important';
			button.setAttribute('aria-hidden', hasChecked ? 'false' : 'true');
		});
	}

	const dt = $(selector).DataTable({
		retrieve: true,
		autoWidth: false,
		responsive: true,
		processing: true,
		serverSide: true,
		deferRender: true,
		pageLength: tables_pagination_limit,
		aLengthMenu: [length_options, length_options_names],
		dom:
			"<'flex items-center justify-between flex-wrap gap-2 mb-3'<'flex items-center gap-1 dt-left-toolbar'lB><'dt-right'>f>" +
			"rt" +
			"<'flex items-center justify-between flex-wrap gap-2 mt-3'<'text-sm'i><'text-sm'p>>",
		buttons: [
			{
				extend: "collection",
				text: export_lang,
				className: "dt-export",
				buttons: [
					{
						extend: "print",
						text: "Print",
						exportOptions: buttonExportOptions,
					},
					makeDeferredExportButton("excelHtml5", "Excel"),
					makeDeferredExportButton("csvHtml5", "CSV"),
					makeDeferredExportButton("pdfHtml5", "PDF", {
						customize: function (doc) {
							customizePdfExport(doc);
						},
					}),
					{ extend: "colvis", text: "Columns" },
				],
			},
			{
				text: '<span class=""><svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-slate-600" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m0 0A7.5 7.5 0 0112 4.5c2.357 0 4.47 1.07 5.918 2.75M4.582 9H9m10-4v5h-.582m0 0A7.5 7.5 0 0112 19.5 7.5 7.5 0 016.082 16.75M19.418 9H15" /></svg></span>',
				className: "dt-reload",
				action: function (e, dt) {
					dt.ajax.reload(null, false);
				},
			},
			{
				text: '<span class="">' + " " + bulk_delete + "</span>",
				className: "dt-bulk-delete hidden",
				action: function () {
					$(document).trigger("dt:bulkDelete");
				},
			},
		],
		select: true,
		order: [],
		ajax: function (requestData, callback, settings) {
			const csrfConfig = window.erpCsrf || {};
			const csrfTokenName = csrfConfig.tokenName || "csrf_token";
			const csrfCookieName = csrfConfig.cookieName || "csrf_cookie";
			const csrfToken = getCookie(csrfCookieName);
			if (csrfToken) {
				requestData[csrfTokenName] = csrfToken;
			}
			const preloadedPayload = readPreloadedResponse(req_url, requestData);
			if (preloadedPayload) {
				const normalizedPreload = normalizeResponseForRequest(preloadedPayload, requestData);
				if (normalizedPreload) {
					callback(normalizedPreload);
					return;
				}
			}

			if (window.erpTopbar && typeof window.erpTopbar.start === "function") {
				window.erpTopbar.start();
			}
			$.ajax({
				url: req_url,
				type: "POST",
				dataType: "json",
				data: requestData,
				success: function (response) {
					const normalizedResponse = normalizeResponseForRequest(response, requestData);
					if (!normalizedResponse) {
						callback({
							draw: requestData.draw || 1,
							recordsTotal: 0,
							recordsFiltered: 0,
							data: []
						});
						return;
					}
					callback(normalizedResponse);
				},
				error: function (xhr) {
					console.log(xhr.responseText);
					callback({
						draw: requestData.draw || 1,
						recordsTotal: 0,
						recordsFiltered: 0,
						data: []
					});
				},
				complete: function () {
					if (window.erpTopbar && typeof window.erpTopbar.finish === "function") {
						window.erpTopbar.finish();
					}
				}
			});
		},
		fnCreatedRow: function (nRow, aData, iDataIndex) {
			$(nRow).attr("id", "table_" + iDataIndex);
			$(nRow).addClass("custom-row");
			$(nRow).find("td:first").addClass("custom-checkbox");
		},
		drawCallback: function () {
			const $wrapper = $(selector).closest(".dataTables_wrapper");
			if ($.fn.tooltip) {
				$wrapper.find('[data-toggle="tooltip"]').tooltip();
			}
			applyResponsiveTableClasses($wrapper);
			syncBulkDeleteButtonState($wrapper);
			updateIcons($wrapper.get(0));
		},
		oLanguage: {
			sSearch: search_all_column + ": ",
			sLengthMenu: "_MENU_",
			zeroRecords: nothing_found_sorry,
			info: showing + " _START_ " + to + " _END_ " + of + " _TOTAL_ " + entries,
			infoEmpty: no_record_available,
			infoFiltered:
				"(" + filtered_from + " _MAX_ " + total + " " + records + ")",
		},
	});
	$table.attr("data-erp-datatable-source-url", req_url);
	// Custom search input
	dt.on("init", function () {
		const $toolbar = $(selector)
			.closest(".dataTables_wrapper")
			.find(".dt-right");
		if ($toolbar.length) {
			$toolbar.find(".dt-search-box").remove();
			const $search = $(
				'<div class="relative dt-search-box"><input type="search" class="dt-search-input h-9 w-full sm:w-64 rounded-lg border border-slate-200 bg-white pl-9 pr-4 text-sm text-slate-900 shadow-sm transition-all placeholder:text-slate-400 focus:border-slate-600 focus:outline-none focus:ring-2 focus:ring-slate-600/20 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-100 dark:placeholder-gray-500 dark:focus:border-slate-600" placeholder="' +
					search_all_column +
					'"/><span class="dt-search-icon"></span></div>'
			);
			$toolbar.prepend($search);
			$search.find("input").on("keyup change", function () {
				dt.search(this.value).draw();
			});
		}
		const $wrapper = $(selector).closest(".dataTables_wrapper");
		applyResponsiveTableClasses($wrapper);
		updateIcons($wrapper.get(0));
	});
}
function updateIcons(root) {	
	if (window.lucide) {		
		window.lucide.createIcons({ root: root || document.body });
	}
}

window.erpInitDatatables = function(root) {
	const scope = root && root.querySelector ? root : document;
	const table = scope.querySelector ? scope.querySelector("#DataTables, .DataTables") : null;
	if (!table || typeof list === "undefined" || !list) {
		return null;
	}
	return fire_datatable(list, table.id || "DataTables");
};

$(function () {
	window.erpInitDatatables(document);
});

function getCookie(name) {
	var cookieValue = null;
	if (document.cookie && document.cookie !== "") {
		var csrfConfig = window.erpCsrf || {};
		var names = [name];
		if (csrfConfig.cookieName && names.indexOf(csrfConfig.cookieName) === -1) {
			names.push(csrfConfig.cookieName);
		}
		if (csrfConfig.cookiePrefix) {
			var prefixedName = csrfConfig.cookiePrefix + name;
			if (names.indexOf(prefixedName) === -1) {
				names.push(prefixedName);
			}
			if (csrfConfig.cookieName) {
				var prefixedCookieName = csrfConfig.cookiePrefix + csrfConfig.cookieName;
				if (names.indexOf(prefixedCookieName) === -1) {
					names.push(prefixedCookieName);
				}
			}
		}
		var cookies = document.cookie.split(";");
		for (var i = 0; i < cookies.length; i++) {
			var cookie = jQuery.trim(cookies[i]);
			for (var n = 0; n < names.length; n++) {
				var cookieName = names[n];
				if (cookie.substring(0, cookieName.length + 1) == cookieName + "=") {
					cookieValue = decodeURIComponent(cookie.substring(cookieName.length + 1));
					break;
				}
			}
			if (cookieValue !== null) {
				break;
			}
		}
	}
	return cookieValue;
}

function table_url(url) {
	list = url;
	return fire_datatable(url, "DataTables");
}

function reload_table() {
	const table = $("#DataTables").DataTable();
	table.ajax.reload(null, false);
}
