'use strict';

const express = require('express');
const settings = require('./manager');
const Database = require('../storage/database');

function createRouter() {
	const router = express.Router();

	function dbAvailable() {
		return Database && Database.db;
	}

	// ---- Global settings ----

	router.get('/api/settings', async (req, res) => {
		try {
			const all = settings.getAll();
			const registry = settings.getRegistry();
			const result = registry.map(r => ({
				...r,
				value: all[r.key],
			}));
			res.json({ settings: result });
		} catch (error) {
			console.error('API Error /api/settings:', error);
			res.status(500).json({ error: error.message });
		}
	});

	router.get('/api/settings/:category', async (req, res) => {
		try {
			const values = settings.getAllByCategory(req.params.category);
			const registry = settings.getRegistry().filter(r => r.category === req.params.category);
			const result = registry.map(r => ({
				...r,
				value: values[r.key],
			}));
			res.json({ settings: result });
		} catch (error) {
			res.status(500).json({ error: error.message });
		}
	});

	router.put('/api/settings/:key', async (req, res) => {
		if (!dbAvailable()) return res.status(503).json({ error: 'Database not initialized' });
		try {
			const { key } = req.params;
			const { value } = req.body;
			if (value === undefined) {
				return res.status(400).json({ error: 'Missing value' });
			}
			const newValue = await settings.set(key, value);
			res.json({ key, value: newValue });
		} catch (error) {
			console.error('API Error /api/settings/:key:', error);
			res.status(500).json({ error: error.message });
		}
	});

	// ---- Bot settings ----

	router.get('/api/bot-settings', async (req, res) => {
		try {
			const names = settings.getBotNames();
			const botReg = settings.getBotSettingsRegistry();
			const bots = names.map(name => {
				const s = settings.getBotSettings(name);
				const flat = { name };
				// Add metadata from registry for each key
				for (const br of botReg) {
					flat[br.key] = { value: s ? s[br.key] : null, type: br.type, label: br.label, description: br.description };
				}
				return flat;
			});
			res.json({ bots, registry: botReg });
		} catch (error) {
			console.error('API Error /api/bot-settings:', error);
			res.status(500).json({ error: error.message });
		}
	});

	router.get('/api/bot-settings/:botName', async (req, res) => {
		try {
			const s = settings.getBotSettings(req.params.botName);
			if (!s) return res.status(404).json({ error: `Unknown bot: ${req.params.botName}` });
			const botReg = settings.getBotSettingsRegistry();
			const result = { name: req.params.botName };
			for (const br of botReg) {
				result[br.key] = { value: s[br.key], type: br.type, label: br.label, description: br.description };
			}
			res.json(result);
		} catch (error) {
			res.status(500).json({ error: error.message });
		}
	});

	router.put('/api/bot-settings/:botName/:key', async (req, res) => {
		if (!dbAvailable()) return res.status(503).json({ error: 'Database not initialized' });
		try {
			const { botName, key } = req.params;
			const { value } = req.body;
			if (value === undefined) return res.status(400).json({ error: 'Missing value' });
			const newValue = await settings.setBotSetting(botName, key, value);
			res.json({ botName, key, value: newValue });
		} catch (error) {
			console.error('API Error /api/bot-settings/:botName/:key:', error);
			res.status(500).json({ error: error.message });
		}
	});

	return router;
}

const webUI = {
	tabId: 'settings',
	tabLabel: 'Settings',
	tabOrder: 35,
	html: `
		<div id="settingsArea">
			<div class="settings-layout">
				<div class="settings-sidebar" id="settingsSidebar"></div>
				<div class="settings-main" id="settingsMain">
					<div class="settings-empty">Select a category to view settings</div>
				</div>
			</div>
		</div>
	`,
	css: `
		.settings-layout{display:flex;gap:16px;min-height:400px}
		.settings-sidebar{width:180px;flex-shrink:0;display:flex;flex-direction:column;gap:4px}
		.settings-sidebar-btn{background:transparent;border:1px solid #374151;color:#9ca3af;padding:10px 14px;border-radius:6px;cursor:pointer;text-align:left;font-size:.9em;transition:all .2s}
		.settings-sidebar-btn:hover{border-color:#60a5fa;color:#e5e7eb}
		.settings-sidebar-btn.active{background:#1e40af;border-color:#60a5fa;color:#fff}
		.settings-main{flex:1;min-width:0}
		.settings-empty{padding:40px 20px;color:#6b7280;text-align:center;font-size:.9em}
		.settings-grid{display:flex;flex-direction:column;gap:12px}
		.settings-card{background:#111827;border:1px solid #374151;border-radius:8px;padding:14px 16px;transition:border-color .2s}
		.settings-card:hover{border-color:#60a5fa}
		.settings-card-header{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:8px}
		.settings-card-label{font-weight:600;color:#e5e7eb;font-size:.95em}
		.settings-card-desc{color:#6b7280;font-size:.8em;margin-bottom:10px}
		.settings-card-key{color:#4b5563;font-size:.75em;font-family:monospace}
		.settings-card-body{display:flex;gap:8px;align-items:center}
		.settings-card-body input[type="text"],
		.settings-card-body input[type="number"],
		.settings-card-body input[type="password"]{flex:1;padding:8px 10px;border-radius:6px;border:1px solid #374151;background:#1f2937;color:#e5e7eb;font-size:.9em}
		.settings-card-body input:focus{outline:none;border-color:#60a5fa}
		.settings-card-body textarea{flex:1;padding:8px 10px;border-radius:6px;border:1px solid #374151;background:#1f2937;color:#e5e7eb;font-size:.85em;min-height:80px;resize:vertical;font-family:monospace}
		.settings-card-body textarea:focus{outline:none;border-color:#60a5fa}
		.settings-card-body input[type="checkbox"]{width:18px;height:18px;accent-color:#60a5fa}
		.settings-card-body select{flex:1;padding:8px 10px;border-radius:6px;border:1px solid #374151;background:#1f2937;color:#e5e7eb;font-size:.9em}
		.settings-card-body select:focus{outline:none;border-color:#60a5fa}
		.settings-value-display{flex:1;padding:8px 10px;color:#9ca3af;font-size:.9em;font-family:monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
		.settings-btn-save{padding:8px 16px;border-radius:6px;border:1px solid #059669;background:#065f46;color:#6ee7b7;cursor:pointer;font-size:.85em;white-space:nowrap;transition:all .2s}
		.settings-btn-save:hover{background:#059669;color:#fff}
		.settings-btn-save.saved{background:#059669;color:#fff}
		.settings-toast{position:fixed;bottom:20px;right:20px;background:#059669;color:#fff;padding:12px 20px;border-radius:8px;font-size:.9em;z-index:9999;opacity:0;transform:translateY(10px);transition:all .3s}
		.settings-toast.show{opacity:1;transform:translateY(0)}
		.settings-toast.error{background:#dc2626}
		.prompt-editor{margin-top:12px;border:1px solid #374151;border-radius:8px;overflow:hidden}
		.prompt-editor-layout{display:flex;min-height:300px}
		.prompt-editor-sidebar{width:180px;flex-shrink:0;background:#0f1729;border-right:1px solid #374151;display:flex;flex-direction:column}
		.prompt-editor-sidebar-header{padding:10px 12px;border-bottom:1px solid #374151;display:flex;justify-content:space-between;align-items:center}
		.prompt-editor-sidebar-title{color:#9ca3af;font-size:.75em;text-transform:uppercase;letter-spacing:.5px}
		.prompt-editor-sidebar-list{flex:1;overflow-y:auto;padding:4px}
		.prompt-editor-prompt-item{padding:8px 10px;border-radius:4px;cursor:pointer;color:#9ca3af;font-size:.85em;transition:all .15s;display:flex;justify-content:space-between;align-items:center}
		.prompt-editor-prompt-item:hover{background:#1e293b;color:#e5e7eb}
		.prompt-editor-prompt-item.active{background:#1e40af;color:#fff}
		.prompt-editor-prompt-item .prompt-delete-x{opacity:0;color:#ef4444;font-weight:bold;font-size:1.1em;padding:0 4px;transition:opacity .15s}
		.prompt-editor-prompt-item:hover .prompt-delete-x{opacity:.7}
		.prompt-editor-prompt-item .prompt-delete-x:hover{opacity:1}
		.prompt-editor-content{flex:1;display:flex;flex-direction:column;padding:12px}
		.prompt-editor-content-label{color:#9ca3af;font-size:.8em;margin-bottom:6px}
		.prompt-editor-content textarea{flex:1;min-height:250px;padding:10px;border-radius:6px;border:1px solid #374151;background:#1f2937;color:#e5e7eb;font-size:.85em;font-family:monospace;resize:vertical;line-height:1.5}
		.prompt-editor-content textarea:focus{outline:none;border-color:#60a5fa}
		.prompt-editor-actions{display:flex;gap:8px;margin-top:8px;align-items:center}
		.prompt-editor-vars{font-size:.75em;color:#6b7280;margin-top:6px}
		.prompt-editor-vars code{color:#93c5fd;font-size:.85em}
		.prompt-editor-add-btn{padding:4px 8px;border-radius:4px;border:1px solid #374151;background:transparent;color:#9ca3af;cursor:pointer;font-size:.8em;transition:all .15s}
		.prompt-editor-add-btn:hover{border-color:#60a5fa;color:#e5e7eb}
		.bot-list{display:flex;flex-direction:column;gap:8px}
		.bot-card{background:#111827;border:1px solid #374151;border-radius:8px;overflow:hidden;transition:border-color .2s}
		.bot-card.expanded{border-color:#60a5fa}
		.bot-card-header{display:flex;justify-content:space-between;align-items:center;padding:12px 16px;cursor:pointer;user-select:none;transition:background .15s}
		.bot-card-header:hover{background:#1e293b}
		.bot-card-name{font-weight:600;color:#e5e7eb;font-size:1em}
		.bot-card-summary{font-size:.8em;color:#6b7280;display:flex;gap:12px;flex-wrap:wrap}
		.bot-card-summary span{white-space:nowrap}
		.bot-card-summary .on{color:#6ee7b7}
		.bot-card-summary .off{color:#ef4444}
		.bot-card-arrow{color:#6b7280;transition:transform .2s;font-size:1.2em}
		.bot-card.expanded .bot-card-arrow{transform:rotate(180deg)}
		.bot-card-body{display:none;padding:0 16px 14px;border-top:1px solid #1f2937}
		.bot-card.expanded .bot-card-body{display:block}
		.bot-field{margin-top:10px}
		.bot-field-label{font-size:.8em;color:#9ca3af;margin-bottom:4px}
		.bot-field-row{display:flex;gap:8px;align-items:center}
		.bot-field-row input[type="text"],
		.bot-field-row input[type="number"],
		.bot-field-row input[type="password"]{flex:1;padding:6px 10px;border-radius:6px;border:1px solid #374151;background:#1f2937;color:#e5e7eb;font-size:.85em}
		.bot-field-row input:focus{outline:none;border-color:#60a5fa}
		.bot-field-row textarea{flex:1;padding:6px 10px;border-radius:6px;border:1px solid #374151;background:#1f2937;color:#e5e7eb;font-size:.8em;font-family:monospace;min-height:50px;resize:vertical}
		.bot-field-row textarea:focus{outline:none;border-color:#60a5fa}
		.bot-field-row input[type="checkbox"]{width:16px;height:16px;accent-color:#60a5fa}
		.bot-field-row .mini-save{padding:6px 12px;border-radius:6px;border:1px solid #059669;background:#065f46;color:#6ee7b7;cursor:pointer;font-size:.8em;white-space:nowrap;transition:all .2s}
		.bot-field-row .mini-save:hover{background:#059669;color:#fff}
		.bot-field-row .mini-save.saved{background:#059669;color:#fff}
	`,
	onTabActive: 'onSettingsTabActive',
	js: `
	let settingsData = [];
	let activeCategory = null;
	let botData = [];
	let botRegistry = [];

	function onSettingsTabActive() {
		loadSettingsCategories();
	}

	async function loadSettingsCategories() {
		try {
			const r = await fetch('/api/settings');
			if (!r.ok) throw new Error('Failed to load settings');
			const d = await r.json();
			settingsData = d.settings || [];

			// Build category sidebar
			const cats = {};
			settingsData.forEach(s => {
				if (!cats[s.category]) cats[s.category] = [];
				cats[s.category].push(s);
			});

			// Ensure bots category exists
			cats['bots'] = cats['bots'] || [];

			const catOrder = ['ai', 'storage', 'server', 'farm', 'invites', 'general', 'bots'];
			let sidebarHtml = '';
			const catNames = Object.keys(cats);
			catNames.sort((a, b) => {
				const ia = catOrder.indexOf(a), ib = catOrder.indexOf(b);
				if (ia >= 0 && ib >= 0) return ia - ib;
				if (ia >= 0) return -1;
				if (ib >= 0) return 1;
				return a.localeCompare(b);
			});
			catNames.forEach(cat => {
				const count = cats[cat].length;
				const label = cat === 'bots' ? 'Bots' : cat.charAt(0).toUpperCase()+cat.slice(1);
				const activeClass = activeCategory === cat ? ' active' : (activeCategory === null && cat === catNames[0] ? ' active' : '');
				sidebarHtml += '<button class="settings-sidebar-btn'+activeClass+'" onclick="switchSettingsCategory(\\''+escHtml(cat)+'\\')">'+escHtml(label)+(count > 0 ? ' <span style="color:#6b7280;font-size:.8em">('+count+')</span>' : '')+'</button>';
			});

			document.getElementById('settingsSidebar').innerHTML = sidebarHtml;

			if (!activeCategory) {
				activeCategory = catNames[0] || null;
			}

			if (activeCategory === 'bots') {
				await loadBotSettings();
			} else {
				renderSettings(activeCategory);
			}
		} catch(e) {
			document.getElementById('settingsMain').innerHTML = '<div class="settings-empty">Failed to load settings: '+escHtml(e.message)+'</div>';
		}
	}

	async function switchSettingsCategory(cat) {
		activeCategory = cat;
		const btns = document.querySelectorAll('.settings-sidebar-btn');
		btns.forEach(b => {
			b.classList.remove('active');
			if (b.textContent.trim().startsWith(cat === 'bots' ? 'Bots' : cat.charAt(0).toUpperCase()+cat.slice(1))) b.classList.add('active');
		});

		if (cat === 'bots') {
			await loadBotSettings();
		} else {
			renderSettings(cat);
		}
	}

	async function loadBotSettings() {
		try {
			const r = await fetch('/api/bot-settings');
			if (!r.ok) throw new Error('Failed to load bot settings');
			const d = await r.json();
			botData = d.bots || [];
			botRegistry = d.registry || [];
			renderBotSettings();
		} catch(e) {
			document.getElementById('settingsMain').innerHTML = '<div class="settings-empty">Failed to load bot settings: '+escHtml(e.message)+'</div>';
		}
	}

	function renderBotSettings() {
		if (!botData.length) {
			document.getElementById('settingsMain').innerHTML = '<div class="settings-empty">No bots configured</div>';
			return;
		}

		let html = '<div class="bot-list">';
		botData.forEach(bot => {
			const autoConnect = bot.autoConnect?.value;
			const onDemand = bot.onDemand?.value;
			const isReady = bot.isReady ? ' (online)' : '';
			let summaryParts = [];
			if (autoConnect) summaryParts.push('<span class="on">auto-connect</span>');
			else summaryParts.push('<span class="off">no auto-connect</span>');
			if (onDemand) summaryParts.push('<span class="on">on-demand</span>');
			if (bot.commands?.value && Array.isArray(bot.commands.value)) {
				summaryParts.push('<span>cmds: '+escHtml(bot.commands.value.join(','))+'</span>');
			}

			html += '<div class="bot-card" id="botCard_'+escHtml(bot.name)+'">'+
				'<div class="bot-card-header" onclick="toggleBotCard(\\''+escHtml(bot.name)+'\\')">'+
					'<div>'+
						'<div class="bot-card-name">'+escHtml(bot.name)+isReady+'</div>'+
						'<div class="bot-card-summary">'+summaryParts.join('')+'</div>'+
					'</div>'+
					'<div class="bot-card-arrow">&#9660;</div>'+
				'</div>'+
				'<div class="bot-card-body">';

			botRegistry.forEach(br => {
				const field = bot[br.key];
				if (!field) return;
				let val = field.value;
				if (br.type === 'boolean') val = val === true || val === 'true';
				const displayVal = br.type === 'secret' ? (val ? '***' : '') : val;
				const isSecret = br.type === 'secret';

				let inputHtml;
				if (br.type === 'boolean') {
					inputHtml = '<input type="checkbox" id="bot_'+escHtml(bot.name)+'_'+escHtml(br.key)+'"'+(val ? ' checked' : '')+' onchange="saveBotSetting(\\''+escHtml(bot.name)+'\\',\\''+escHtml(br.key)+'\\',this.checked)">';
				} else if (br.type === 'json') {
					const jsonStr = val ? JSON.stringify(val, null, 2) : '';
					inputHtml = '<textarea id="bot_'+escHtml(bot.name)+'_'+escHtml(br.key)+'" rows="3">'+escHtml(jsonStr)+'</textarea>';
				} else if (isSecret) {
					inputHtml = '<input type="password" id="bot_'+escHtml(bot.name)+'_'+escHtml(br.key)+'" value="'+escHtml(String(val || ''))+'" placeholder="(unchanged)">';
				} else if (br.type === 'number') {
					inputHtml = '<input type="number" id="bot_'+escHtml(bot.name)+'_'+escHtml(br.key)+'" value="'+escHtml(String(val ?? ''))+'">';
				} else {
					inputHtml = '<input type="text" id="bot_'+escHtml(bot.name)+'_'+escHtml(br.key)+'" value="'+escHtml(String(val ?? ''))+'">';
				}

				html += '<div class="bot-field">'+
					'<div class="bot-field-label">'+escHtml(br.label)+' <code style="color:#4b5563">'+escHtml(br.key)+'</code> '+escHtml(br.description ? '- '+br.description : '')+'</div>'+
					'<div class="bot-field-row">'+inputHtml;
				if (br.type !== 'boolean') {
					html += '<button class="mini-save" id="btn_bot_'+escHtml(bot.name)+'_'+escHtml(br.key)+'" onclick="saveBotSetting(\\''+escHtml(bot.name)+'\\',\\''+escHtml(br.key)+'\\',document.getElementById(\\'bot_'+escHtml(bot.name)+'_'+escHtml(br.key)+'\\').value)">Save</button>';
				}
				html += '</div></div>';
			});

			html += '</div></div>';
		});
		html += '</div>';
		document.getElementById('settingsMain').innerHTML = html;
	}

	function toggleBotCard(name) {
		const card = document.getElementById('botCard_'+name);
		if (!card) return;
		card.classList.toggle('expanded');
	}

	async function saveBotSetting(botName, key, value) {
		const btn = document.getElementById('btn_bot_'+botName+'_'+key);
		try {
			const r = await fetch('/api/bot-settings/'+encodeURIComponent(botName)+'/'+encodeURIComponent(key), {
				method: 'PUT',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ value: value })
			});
			if (!r.ok) {
				const err = await r.json().catch(() => ({ error: 'Unknown error' }));
				throw new Error(err.error || 'Failed to save');
			}
			// Update local data
			const bot = botData.find(b => b.name === botName);
			if (bot && bot[key]) {
				bot[key].value = (key === 'password' && value) ? value : value;
			}

			if (btn) {
				btn.classList.add('saved');
				btn.textContent = 'Saved!';
				setTimeout(() => { btn.classList.remove('saved'); btn.textContent = 'Save'; }, 2000);
			}
			// If password field, clear it after save
			if (key === 'password') {
				const inp = document.getElementById('bot_'+botName+'_'+key);
				if (inp) inp.value = '';
			}
			showToast('Saved '+botName+'.'+key);
		} catch(e) {
			showToast('Error: '+e.message, true);
			if (btn) { btn.style.borderColor = '#dc2626'; btn.textContent = 'Error';
				setTimeout(() => { btn.style.borderColor = '#059669'; btn.textContent = 'Save'; }, 3000); }
		}
	}

	function renderSettings(category) {
		if (!category) {
			document.getElementById('settingsMain').innerHTML = '<div class="settings-empty">Select a category</div>';
			return;
		}

		const items = settingsData.filter(s => s.category === category);
		if (items.length === 0) {
			document.getElementById('settingsMain').innerHTML = '<div class="settings-empty">No settings in this category</div>';
			return;
		}

		let html = '<div class="settings-grid">';
		items.forEach(s => {
			const key = escHtml(s.key);
			const label = escHtml(s.label || s.key);
			const desc = escHtml(s.description || '');
			const isSecret = s.type === 'secret';
			let inputHtml = '';

			if (s.key === 'ai.prompts') {
				inputHtml = buildPromptEditor(s);
			} else if (s.key === 'ai.promptName') {
				const prompts = getPromptsMap();
				const names = Object.keys(prompts);
				if (names.length === 0) names.push('asshole');
				inputHtml = '<select id="inp_'+key+'" onchange="saveSetting(\\''+key+'\\', this.value)">'+
					names.map(n => '<option value="'+escHtml(n)+'"'+(String(s.value) === n ? ' selected' : '')+'>'+escHtml(n)+'</option>').join('')+
					'</select>';
			} else if (s.key === 'ai.prompCustom') {
				inputHtml = '<textarea id="inp_'+key+'" rows="4" style="width:100%">'+escHtml(String(s.value ?? ''))+'</textarea>';
			} else if (s.type === 'boolean') {
				const checked = s.value === true ? ' checked' : '';
				inputHtml = '<input type="checkbox" id="inp_'+key+'"'+checked+' onchange="saveSetting(\\''+key+'\\', this.checked)">';
			} else if (isSecret) {
				inputHtml = '<input type="password" id="inp_'+key+'" value="'+escHtml(String(s.value ?? ''))+'" placeholder="(unchanged)">';
			} else if (s.type === 'json') {
				const jsonStr = s.value ? JSON.stringify(s.value, null, 2) : '';
				inputHtml = '<textarea id="inp_'+key+'" rows="4">'+escHtml(jsonStr)+'</textarea>';
			} else if (s.type === 'number') {
				inputHtml = '<input type="number" id="inp_'+key+'" value="'+escHtml(String(s.value ?? ''))+'" step="any">';
			} else {
				inputHtml = '<input type="text" id="inp_'+key+'" value="'+escHtml(String(s.value ?? ''))+'">';
			}

			html += '<div class="settings-card">'+
				'<div class="settings-card-header">'+
					'<div><div class="settings-card-label">'+label+'</div><div class="settings-card-key">'+key+'</div></div>'+
				'</div>'+
				'<div class="settings-card-desc">'+desc+'</div>'+
				'<div class="settings-card-body">'+inputHtml;

			if (s.key === 'ai.prompts') {
				// Prompt editor handles its own save
			} else if (s.key === 'ai.promptName' || s.key === 'ai.prompCustom' || s.type !== 'boolean') {
				html += '<button class="settings-btn-save" onclick="saveSetting(\\''+key+'\\', document.getElementById(\\'inp_'+key+'\\').value)">Save</button>';
			}

			html += '</div></div>';
		});
		html += '</div>';

		document.getElementById('settingsMain').innerHTML = html;

		const promptsItem = items.find(s => s.key === 'ai.prompts');
		if (promptsItem) initPromptEditor(promptsItem);
	}

	async function saveSetting(key, value) {
		const btn = event && event.target ? event.target : null;
		try {
			const r = await fetch('/api/settings/'+encodeURIComponent(key), {
				method: 'PUT',
				headers: { 'Content-Type': 'application/json' },
				body: JSON.stringify({ value: value })
			});
			if (!r.ok) {
				const err = await r.json().catch(() => ({ error: 'Unknown error' }));
				throw new Error(err.error || 'Failed to save');
			}
			const d = await r.json();
			const item = settingsData.find(s => s.key === key);
			if (item) item.value = d.value;

			if (btn) {
				btn.classList.add('saved');
				btn.textContent = 'Saved!';
				setTimeout(() => { btn.classList.remove('saved'); btn.textContent = 'Save'; }, 2000);
			}
			// Clear password field after save
			const isSecret = settingsData.find(s => s.key === key)?.type === 'secret';
			if (isSecret) {
				const inp = document.getElementById('inp_'+key);
				if (inp) inp.value = '';
			}
			showToast('Saved '+key);
		} catch(e) {
			showToast('Error: '+e.message, true);
			if (btn) {
				btn.style.borderColor = '#dc2626'; btn.style.background = '#7f1d1d'; btn.style.color = '#fca5a5'; btn.textContent = 'Error';
				setTimeout(() => { btn.style.borderColor = '#059669'; btn.style.background = '#065f46'; btn.style.color = '#6ee7b7'; btn.textContent = 'Save'; }, 3000);
			}
		}
	}

	let selectedPromptName = null;

	function getPromptsMap() {
		const item = settingsData.find(s => s.key === 'ai.prompts');
		if (item && item.value && typeof item.value === 'object' && !Array.isArray(item.value)) {
			return item.value;
		}
		return {};
	}

	function buildPromptEditor(s) {
		return '<div class="prompt-editor">'+
			'<div class="prompt-editor-layout">'+
				'<div class="prompt-editor-sidebar">'+
					'<div class="prompt-editor-sidebar-header">'+
						'<span class="prompt-editor-sidebar-title">Prompts</span>'+
						'<button class="prompt-editor-add-btn" onclick="addNewPrompt()">+ Add</button>'+
					'</div>'+
					'<div class="prompt-editor-sidebar-list" id="promptEditorList"></div>'+
				'</div>'+
				'<div class="prompt-editor-content">'+
					'<span class="prompt-editor-content-label">Edit template for: <strong id="promptEditorActiveName">none</strong></span>'+
					'<textarea id="promptEditorTextarea" placeholder="Select a prompt from the sidebar or add a new one..."></textarea>'+
					'<div class="prompt-editor-actions">'+
						'<button class="settings-btn-save" onclick="savePromptTemplate()">Save Template</button>'+
						'<span style="font-size:0.75em;color:#6b7280" id="promptEditorSaved"></span>'+
					'</div>'+
					'<div class="prompt-editor-vars">Template variables: <code>\${name}</code> <code>\${interval}</code> <code>\${currentPlayers}</code> <code>\${toolsDocs}</code> <code>\${memoryContext}</code> <code>\${timeInfo}</code> <code>\${custom}</code></div>'+
				'</div>'+
			'</div>'+
		'</div>';
	}

	function initPromptEditor(s) {
		const prompts = getPromptsMap();
		renderPromptList(prompts);
		const names = Object.keys(prompts);
		if (names.length > 0) {
			selectPromptToEdit(names[0]);
		}
	}

	function renderPromptList(prompts) {
		const listEl = document.getElementById('promptEditorList');
		if (!listEl) return;
		const names = Object.keys(prompts);
		listEl.innerHTML = names.map(name =>
			'<div class="prompt-editor-prompt-item'+(name === selectedPromptName ? ' active' : '')+'" onclick="selectPromptToEdit(\\''+escHtml(name)+'\\')">'+
				'<span>'+escHtml(name)+'</span>'+
				'<span class="prompt-delete-x" onclick="event.stopPropagation();deletePrompt(\\''+escHtml(name)+'\\')">&times;</span>'+
			'</div>'
		).join('');
	}

	function selectPromptToEdit(name) {
		selectedPromptName = name;
		const prompts = getPromptsMap();
		document.getElementById('promptEditorActiveName').textContent = name;
		document.getElementById('promptEditorTextarea').value = prompts[name] || '';
		document.getElementById('promptEditorSaved').textContent = '';
		renderPromptList(prompts);
	}

	async function savePromptTemplate() {
		if (!selectedPromptName) return;
		const textarea = document.getElementById('promptEditorTextarea');
		const template = textarea.value;
		const prompts = getPromptsMap();
		prompts[selectedPromptName] = template;
		await saveSetting('ai.prompts', prompts);
		document.getElementById('promptEditorSaved').textContent = 'Saved!';
		setTimeout(() => { document.getElementById('promptEditorSaved').textContent = ''; }, 2000);
	}

	async function addNewPrompt() {
		const name = prompt('New prompt name:');
		if (!name || !name.trim()) return;
		const trimmed = name.trim();
		const prompts = getPromptsMap();
		if (prompts[trimmed]) {
			alert('Prompt "'+trimmed+'" already exists.');
			return;
		}
		prompts[trimmed] = '';
		await saveSetting('ai.prompts', prompts);
		selectedPromptName = trimmed;
		renderPromptList(prompts);
		selectPromptToEdit(trimmed);
		loadSettingsCategories();
	}

	async function deletePrompt(name) {
		const prompts = getPromptsMap();
		if (Object.keys(prompts).length <= 1) {
			alert('Cannot delete the last prompt.');
			return;
		}
		if (!confirm('Delete prompt "'+name+'"?')) return;
		delete prompts[name];
		await saveSetting('ai.prompts', prompts);
		if (selectedPromptName === name) {
			const remaining = Object.keys(prompts);
			selectedPromptName = remaining.length > 0 ? remaining[0] : null;
		}
		if (selectedPromptName) {
			selectPromptToEdit(selectedPromptName);
		}
		renderPromptList(prompts);
		loadSettingsCategories();
	}

	function showToast(msg, isError) {
		let toast = document.getElementById('settingsToast');
		if (!toast) {
			toast = document.createElement('div');
			toast.id = 'settingsToast';
			toast.className = 'settings-toast';
			document.body.appendChild(toast);
		}
		toast.textContent = msg;
		toast.className = 'settings-toast' + (isError ? ' error' : '');
		setTimeout(() => toast.classList.add('show'), 10);
		setTimeout(() => { toast.classList.remove('show'); }, 3000);
	}
	`,
};

module.exports = { createRouter, webUI };
