// Tailwind-styled rich text editor (vanilla JS). Enhances any <textarea.tw-editor>
(function () {
	const getIcon = (name, cls = "w-4 h-4") => {
		if (window.tailwindIcon) return window.tailwindIcon(name, cls);
		if (window.lucide && window.lucide.icons && window.lucide.icons[name]) {
			const svg = window.lucide.createElement(window.lucide.icons[name]);
			svg.setAttribute("class", cls);
			return svg.outerHTML;
		}
		return "";
	};

	class TailwindEditor {
		constructor(selector, options = {}) {
			this.textarea = document.querySelector(selector);
			if (!this.textarea) return;
			this.options = { height: options.height || "300px", ...options };
			this.isCodeView = false;
			this.init();
		}

		init() {
			this.container = document.createElement("div");
			this.container.className = "flex flex-col w-full h-full";
			this.container.dataset.editorFor = this.textarea.id;
			this.toolbar = this.createToolbar();
			this.container.appendChild(this.toolbar);
			const contentWrapper = document.createElement("div");
			contentWrapper.className =
				"relative flex-1 bg-white dark:bg-slate-900 transition-colors";
			contentWrapper.style.minHeight = this.options.height;
			this.editor = document.createElement("div");
			this.editor.className =
				"editor-content w-full h-full p-4 outline-none overflow-y-auto custom-scrollbar text-slate-700 dark:text-slate-200 leading-relaxed";
			this.editor.contentEditable = true;
			this.editor.innerHTML = this.textarea.value;
			this.codeView = document.createElement("textarea");
			this.codeView.className =
				"w-full h-full p-4 bg-slate-900 text-slate-100 font-mono text-sm outline-none resize-none hidden absolute top-0 left-0 z-10 custom-scrollbar border-0";
			contentWrapper.appendChild(this.editor);
			contentWrapper.appendChild(this.codeView);
			this.container.appendChild(contentWrapper);
			this.textarea.parentNode.insertBefore(this.container, this.textarea);
			this.textarea.style.display = "none";
			this.textarea._tailwindEditor = this;
			this.bindEvents();
		}

		createToolbar() {
			const toolbar = document.createElement("div");
			toolbar.className =
				"flex flex-wrap items-center gap-1 p-2 bg-slate-50 dark:bg-slate-800 border-b border-slate-200 dark:border-slate-700 sticky top-0 z-20 transition-colors";
			const groups = [
				[
					{ icon: "Undo", cmd: "undo", title: "Undo" },
					{ icon: "Redo", cmd: "redo", title: "Redo" },
				],
				[
					{ icon: "Bold", cmd: "bold", title: "Bold" },
					{ icon: "Italic", cmd: "italic", title: "Italic" },
					{ icon: "Underline", cmd: "underline", title: "Underline" },
					{
						icon: "Strikethrough",
						cmd: "strikethrough",
						title: "Strikethrough",
					},
				],
				[
					{ icon: "AlignLeft", cmd: "justifyLeft", title: "Align Left" },
					{ icon: "AlignCenter", cmd: "justifyCenter", title: "Align Center" },
					{ icon: "AlignRight", cmd: "justifyRight", title: "Align Right" },
					{ icon: "AlignJustify", cmd: "justifyFull", title: "Justify" },
				],
				[
					{ icon: "List", cmd: "insertUnorderedList", title: "Bullet List" },
					{
						icon: "ListOrdered",
						cmd: "insertOrderedList",
						title: "Ordered List",
					},
				],				
				[{ icon: "Code", action: "code", title: "View Source Code" }],
			];
			const formatSelect = document.createElement("select");
			formatSelect.className =
				"h-9 px-2 text-sm bg-white dark:bg-slate-700 border border-slate-200 dark:border-slate-600 rounded-lg shadow-sm focus:outline-none focus:border-blue-500 cursor-pointer text-slate-600 dark:text-slate-200 mr-1";
			["P", "H1", "H2", "H3", "Blockquote"].forEach((tag) => {
				const opt = document.createElement("option");
				opt.value =
					tag === "P"
						? "p"
						: tag === "Blockquote"
						? "blockquote"
						: tag.toLowerCase();
				opt.text = tag === "P" ? "Normal" : tag;
				formatSelect.appendChild(opt);
			});
			formatSelect.onchange = (e) => this.exec("formatBlock", e.target.value);
			toolbar.appendChild(formatSelect);

			const sizeSelect = document.createElement("select");
			sizeSelect.className =
				"h-9 px-2 text-sm bg-white dark:bg-slate-700 border border-slate-200 dark:border-slate-600 rounded-lg shadow-sm focus:outline-none focus:border-blue-500 cursor-pointer text-slate-600 dark:text-slate-200 mr-1";
			const sizes = [
				{ val: "3", label: "14px" },
				{ val: "1", label: "10px" },
				{ val: "2", label: "13px" },
				{ val: "4", label: "16px" },
				{ val: "5", label: "18px" },
				{ val: "6", label: "24px" },
				{ val: "7", label: "36px" },
			];
			sizes.forEach((s) => {
				const opt = document.createElement("option");
				opt.value = s.val;
				opt.text = s.label;
				if (s.val === "3") opt.selected = true;
				sizeSelect.appendChild(opt);
			});
			sizeSelect.onchange = (e) => this.exec("fontSize", e.target.value);
			toolbar.appendChild(sizeSelect);

			groups.forEach((group) => {
				const groupDiv = document.createElement("div");
				groupDiv.className =
					"flex items-center gap-0.5 bg-white dark:bg-slate-700 rounded-lg border border-slate-200 dark:border-slate-600 p-0.5 shadow-sm";
				group.forEach((btn) => {
					const button = document.createElement("button");
					button.type = "button";
					button.className =
						"w-8 h-8 flex items-center justify-center text-slate-600 dark:text-slate-300 hover:bg-blue-50 dark:hover:bg-slate-600 hover:text-blue-600 dark:hover:text-blue-400 rounded transition-colors text-sm";
					button.title = btn.title;
					button.innerHTML = getIcon(btn.icon);
					button.onclick = (e) => {
						e.preventDefault();
						if (btn.cmd) this.exec(btn.cmd);
						else if (btn.action) this.handleAction(btn.action, button);
					};
					groupDiv.appendChild(button);
				});
				toolbar.appendChild(groupDiv);
			});
			return toolbar;
		}

		exec(command, value = null) {
			if (this.isCodeView) return;
			document.execCommand(command, false, value);
			this.editor.focus();
			this.sync();
		}

		handleAction(action, btnElement) {
			if (action === "link") {
				const url = prompt("Enter Link URL:", "https://");
				if (url) this.exec("createLink", url);
			} else if (action === "image") {
				const url = prompt("Enter Image URL:", "https://");
				if (url) this.exec("insertImage", url);
			} else if (action === "code") {
				this.toggleCodeView(btnElement);
			}
		}

		toggleCodeView(btn) {
			this.isCodeView = !this.isCodeView;
			if (this.isCodeView) {
				this.codeView.value = this.editor.innerHTML;
				this.codeView.classList.remove("hidden");
				btn.classList.add("bg-slate-800", "text-white", "dark:bg-slate-900");
				btn.classList.remove(
					"text-slate-600",
					"dark:text-slate-300",
					"hover:bg-blue-50"
				);
			} else {
				this.editor.innerHTML = this.codeView.value;
				this.codeView.classList.add("hidden");
				btn.classList.remove("bg-slate-800", "text-white", "dark:bg-slate-900");
				btn.classList.add(
					"text-slate-600",
					"dark:text-slate-300",
					"hover:bg-blue-50"
				);
				this.sync();
			}
		}

		sync() {
			this.textarea.value = this.isCodeView
				? this.codeView.value
				: this.editor.innerHTML;
		}
		saveSelection() {
			const selection = window.getSelection ? window.getSelection() : null;
			if (!selection || selection.rangeCount === 0) return;
			const range = selection.getRangeAt(0);
			if (this.editor.contains(range.commonAncestorContainer)) {
				this.lastRange = range.cloneRange();
			}
		}
		restoreSelection() {
			if (!this.lastRange || !window.getSelection) return false;
			const selection = window.getSelection();
			selection.removeAllRanges();
			selection.addRange(this.lastRange);
			return true;
		}
		insertText(text) {
			if (this.isCodeView) {
				const startPos = this.codeView.selectionStart || 0;
				const endPos = this.codeView.selectionEnd || startPos;
				this.codeView.value =
					this.codeView.value.substring(0, startPos) +
					text +
					this.codeView.value.substring(endPos);
				this.codeView.selectionStart = this.codeView.selectionEnd =
					startPos + text.length;
				this.codeView.focus();
				this.textarea.value = this.codeView.value;
				return;
			}

			this.editor.focus();
			this.restoreSelection();
			const selection = window.getSelection ? window.getSelection() : null;
			const appendText = () => {
				const textNode = document.createTextNode(text);
				this.editor.appendChild(textNode);
				const range = document.createRange();
				range.setStartAfter(textNode);
				range.collapse(true);
				if (selection) {
					selection.removeAllRanges();
					selection.addRange(range);
				}
				this.saveSelection();
				this.sync();
			};
			if (!selection || selection.rangeCount === 0) {
				appendText();
				return;
			}
			const range = selection.getRangeAt(0);
			if (!this.editor.contains(range.commonAncestorContainer)) {
				appendText();
				return;
			}
			range.deleteContents();
			const textNode = document.createTextNode(text);
			range.insertNode(textNode);
			range.setStartAfter(textNode);
			range.collapse(true);
			selection.removeAllRanges();
			selection.addRange(range);
			this.saveSelection();
			this.sync();
		}
		bindEvents() {
			this.editor.addEventListener("input", () => this.sync());
			this.editor.addEventListener("keyup", () => this.saveSelection());
			this.editor.addEventListener("mouseup", () => this.saveSelection());
			this.editor.addEventListener("blur", () => this.saveSelection());
			this.codeView.addEventListener("input", () => {
				this.textarea.value = this.codeView.value;
			});
			this.editor.addEventListener("click", (e) => {
				if (e.target.tagName === "A") e.preventDefault();
			});
		}
	}

	// // Initialize all editors on the page

	function initEditors(scope) {
		const root = scope || document;
		root.querySelectorAll("textarea.tw-editor").forEach((el) => {
			if (el.dataset.editorReady === "1") return;
			el.dataset.editorReady = "1";
			if (!el.id) {
				el.id = `tw-editor-${Math.random().toString(36).slice(2, 10)}`;
			}
			new TailwindEditor(`#${el.id}`, {
				height: el.getAttribute("data-height") || "300px",
			});
		});
	}

	window.initEditors = initEditors;

	if (
		document.readyState === "interactive" ||
		document.readyState === "complete"
	) {
		initEditors();
	} else {
		document.addEventListener("DOMContentLoaded", () => initEditors());
	}
})();
