'use strict';

const express = require('express');
const { CJbot } = require('../../model/minecraft');

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

	router.get('/api/ai/status', (req, res) => {
		try {
			const result = {};
			for (const [name, bot] of Object.entries(CJbot.bots)) {
				const ai = bot.plunginsLoaded['Ai'];
				if (!ai) continue;
				const config = ai.__getConfig();
				result[name] = {
					connected: bot.isReady,
					provider: config.provider || 'unknown',
					model: config.model || 'unknown',
					interval: ai.intervalLength,
					promptName: ai.promptName || 'unknown',
					active: !!ai._active,
				};
			}
			res.json({ bots: result });
		} catch (error) {
			console.error('API Error /api/ai/status:', error);
			res.status(500).json({ error: error.message });
		}
	});

	// Get list of all bots (for UI)
	router.get('/api/ai/bots', (req, res) => {
		try {
			const bots = [];
			for (const [name, bot] of Object.entries(CJbot.bots)) {
				const ai = bot.plunginsLoaded['Ai'];
				bots.push({
					name: name,
					hasAI: !!ai,
					hasMemory: !!(ai && ai.memoryDB)
				});
			}
			res.json({ bots });
		} catch (error) {
			console.error('API Error /api/ai/bots:', error);
			res.status(500).json({ error: error.message });
		}
	});

	// Get all players with memories (shared across all bots)
	router.get('/api/ai/memories/players', async (req, res) => {
		try {
			// Get players from any bot's memoryDB (they're shared now)
			let players = [];
			for (const [name, bot] of Object.entries(CJbot.bots)) {
				const ai = bot.plunginsLoaded['Ai'];
				if (ai && ai.memoryDB) {
					players = await ai.memoryDB.getAllKnownPlayers();
					break;
				}
			}
			res.json({ players });
		} catch (error) {
			console.error('API Error /api/ai/memories/players:', error);
			res.status(500).json({ error: error.message });
		}
	});

	// Get memories for a specific player
	router.get('/api/ai/memories/:botName/:playerName', async (req, res) => {
		try {
			const { botName, playerName } = req.params;
			const bot = CJbot.bots[botName];
			if (!bot) {
				return res.status(404).json({ error: 'Bot not found' });
			}
			const ai = bot.plunginsLoaded['Ai'];
			if (!ai || !ai.memoryDB) {
				return res.status(404).json({ error: 'AI or memory DB not loaded' });
			}
			const memories = await ai.memoryDB.getAllPlayerMemories(playerName);
			res.json({ bot: botName, player: playerName, memories });
		} catch (error) {
			console.error('API Error /api/ai/memories/:bot/:player:', error);
			res.status(500).json({ error: error.message });
		}
	});

	// Set or update a player memory
	router.post('/api/ai/memories/:botName/:playerName', async (req, res) => {
		try {
			const { botName, playerName } = req.params;
			const { key, value } = req.body;
			if (!key || !value) {
				return res.status(400).json({ error: 'key and value are required' });
			}
			const bot = CJbot.bots[botName];
			if (!bot) {
				return res.status(404).json({ error: 'Bot not found' });
			}
			const ai = bot.plunginsLoaded['Ai'];
			if (!ai || !ai.memoryDB) {
				return res.status(404).json({ error: 'AI or memory DB not loaded' });
			}
			await ai.memoryDB.setPlayerMemory(playerName, key, value);
			res.json({ success: true, bot: botName, player: playerName, key, value });
		} catch (error) {
			console.error('API Error /api/ai/memories/:bot/:player POST:', error);
			res.status(500).json({ error: error.message });
		}
	});

	// Delete a player memory
	router.delete('/api/ai/memories/:botName/:playerName/:key', async (req, res) => {
		try {
			const { botName, playerName, key } = req.params;
			const bot = CJbot.bots[botName];
			if (!bot) {
				return res.status(404).json({ error: 'Bot not found' });
			}
			const ai = bot.plunginsLoaded['Ai'];
			if (!ai || !ai.memoryDB) {
				return res.status(404).json({ error: 'AI or memory DB not loaded' });
			}
			await ai.memoryDB.deletePlayerMemory(playerName, key);
			res.json({ success: true, bot: botName, player: playerName, key });
		} catch (error) {
			console.error('API Error /api/ai/memories/:bot/:player/:key DELETE:', error);
			res.status(500).json({ error: error.message });
		}
	});

	// Get bot directives
	router.get('/api/ai/directives/:botName', async (req, res) => {
		try {
			const { botName } = req.params;
			const bot = CJbot.bots[botName];
			if (!bot) {
				return res.status(404).json({ error: 'Bot not found' });
			}
			const ai = bot.plunginsLoaded['Ai'];
			if (!ai || !ai.memoryDB) {
				return res.status(404).json({ error: 'AI or memory DB not loaded' });
			}
			const directives = await ai.memoryDB.getAllDirectives();
			res.json({ bot: botName, directives });
		} catch (error) {
			console.error('API Error /api/ai/directives/:bot:', error);
			res.status(500).json({ error: error.message });
		}
	});

	// Set or update a directive
	router.post('/api/ai/directives/:botName', async (req, res) => {
		try {
			const { botName } = req.params;
			const { key, value } = req.body;
			if (!key || !value) {
				return res.status(400).json({ error: 'key and value are required' });
			}
			const bot = CJbot.bots[botName];
			if (!bot) {
				return res.status(404).json({ error: 'Bot not found' });
			}
			const ai = bot.plunginsLoaded['Ai'];
			if (!ai || !ai.memoryDB) {
				return res.status(404).json({ error: 'AI or memory DB not loaded' });
			}
			await ai.memoryDB.setDirective(key, value);
			res.json({ success: true, bot: botName, key, value });
		} catch (error) {
			console.error('API Error /api/ai/directives/:bot POST:', error);
			res.status(500).json({ error: error.message });
		}
	});

	// Get general memories
	router.get('/api/ai/general-memories/:botName', async (req, res) => {
		try {
			const { botName } = req.params;
			const bot = CJbot.bots[botName];
			if (!bot) {
				return res.status(404).json({ error: 'Bot not found' });
			}
			const ai = bot.plunginsLoaded['Ai'];
			if (!ai || !ai.memoryDB) {
				return res.status(404).json({ error: 'AI or memory DB not loaded' });
			}
			const memories = await ai.memoryDB.getAllGeneralMemories();
			res.json({ bot: botName, memories });
		} catch (error) {
			console.error('API Error /api/ai/general-memories/:bot:', error);
			res.status(500).json({ error: error.message });
		}
	});

	// Set or update a general memory
	router.post('/api/ai/general-memories/:botName', async (req, res) => {
		try {
			const { botName } = req.params;
			const { key, value } = req.body;
			if (!key || !value) {
				return res.status(400).json({ error: 'key and value are required' });
			}
			const bot = CJbot.bots[botName];
			if (!bot) {
				return res.status(404).json({ error: 'Bot not found' });
			}
			const ai = bot.plunginsLoaded['Ai'];
			if (!ai || !ai.memoryDB) {
				return res.status(404).json({ error: 'AI or memory DB not loaded' });
			}
			await ai.memoryDB.setGeneralMemory(key, value);
			res.json({ success: true, bot: botName, key, value });
		} catch (error) {
			console.error('API Error /api/ai/general-memories/:bot POST:', error);
			res.status(500).json({ error: error.message });
		}
	});

	return router;
}

const webUI = {
	tabId: 'ai',
	tabLabel: 'AI',
	tabOrder: 30,
	html: `
		<div id="aiArea">
			<div class="ai-tabs">
				<button class="ai-tab-btn active" data-tab="status" onclick="switchAiTab('status')">AI Status</button>
				<button class="ai-tab-btn" data-tab="memories" onclick="switchAiTab('memories')">Memories</button>
				<button class="ai-tab-btn" data-tab="directives" onclick="switchAiTab('directives')">Directives</button>
			</div>
			<div id="ai-tab-content">
				<div id="ai-status" class="ai-tab-content active"></div>
				<div id="ai-memories" class="ai-tab-content"></div>
				<div id="ai-directives" class="ai-tab-content"></div>
			</div>
		</div>
	`,
	css: `
		.ai-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:16px}
		.ai-card{background:#111827;border:1px solid #374151;border-radius:8px;padding:16px;transition:border-color .2s}
		.ai-card:hover{border-color:#a78bfa}
		.ai-card h3{font-size:1em;color:#a78bfa;margin-bottom:12px;display:flex;align-items:center;gap:8px}
		.ai-info{font-size:.85em;color:#9ca3af;margin:4px 0}
		.ai-info .ai-label{color:#6b7280;display:inline-block;min-width:80px}
		.ai-info .ai-value{color:#e5e7eb}
		.ai-status-badge{padding:2px 8px;border-radius:10px;font-size:.75em;font-weight:600}
		.ai-status-badge.active{background:#059669;color:#fff}
		.ai-status-badge.inactive{background:#6b7280;color:#fff}
		.ai-empty{padding:40px 20px;color:#6b7280;text-align:center;font-size:.9em}
		.ai-tabs{display:flex;gap:8px;margin-bottom:16px;border-bottom:1px solid #374151;padding-bottom:8px}
		.ai-tab-btn{background:transparent;border:1px solid #374151;color:#9ca3af;padding:8px 16px;border-radius:6px;cursor:pointer;transition:all .2s}
		.ai-tab-btn:hover{border-color:#a78bfa;color:#e5e7eb}
		.ai-tab-btn.active{background:#a78bfa;border-color:#a78bfa;color:#111827}
		.ai-tab-content{display:none}
		.ai-tab-content.active{display:block}
		.memory-card{background:#111827;border:1px solid #374151;border-radius:8px;padding:16px;margin-bottom:12px}
		.memory-card h4{color:#a78bfa;margin:0 0 12px 0;font-size:.95em}
		.memory-entry{display:flex;justify-content:space-between;align-items:center;padding:8px 0;border-bottom:1px solid #1f2937}
		.memory-entry:last-child{border-bottom:none}
		.memory-key{color:#e5e7eb;font-weight:500}
		.memory-value{color:#9ca3af;max-width:60%;overflow:hidden;text-overflow:ellipsis}
		.memory-actions{display:flex;gap:8px}
		.btn-sm{padding:4px 8px;font-size:.75em;border-radius:4px;border:1px solid #374151;background:#1f2937;color:#9ca3af;cursor:pointer}
		.btn-sm:hover{border-color:#a78bfa;color:#e5e7eb}
		.btn-danger{border-color:#dc2626;color:#fca5a5}
		.btn-danger:hover{background:#dc2626;color:#fff}
		.btn-success{border-color:#059669;color:#6ee7b7}
		.btn-success:hover{background:#059669;color:#fff}
		.memory-form{display:flex;gap:8px;flex-wrap:wrap;margin-top:12px}
		.memory-form input{flex:1;min-width:150px;padding:8px;border-radius:4px;border:1px solid #374151;background:#1f2937;color:#e5e7eb}
		.memory-form input:focus{outline:none;border-color:#a78bfa}
		.player-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:12px}
		.player-card{background:#1f2937;border:1px solid #374151;border-radius:6px;padding:12px;cursor:pointer;transition:border-color .2s}
		.player-card:hover{border-color:#a78bfa}
		.player-card.selected{border-color:#a78bfa;background:#2d1f4e}
		.form-group{margin-bottom:12px}
		.form-group label{display:block;color:#6b7280;font-size:.85em;margin-bottom:4px}
		.form-group input,.form-group textarea{width:100%;padding:8px;border-radius:4px;border:1px solid #374151;background:#1f2937;color:#e5e7eb;box-sizing:border-box}
		.form-group textarea{min-height:80px;resize:vertical}
		.bot-select{margin-bottom:16px;padding:8px;border-radius:6px;border:1px solid #374151;background:#1f2937;color:#e5e7eb;min-width:200px}
	`,
	onTabActive: 'onAiTabActive',
	js: `
let aiInterval=null;
let currentAiTab='status';
let selectedBot=null;
let selectedPlayer=null;

function onAiTabActive() {
	// Initialize tab content structure if needed
	var container = document.getElementById('ai-tab-content');
	if (container && !container.querySelector('#ai-status')) {
		container.innerHTML = '<div id="ai-status" class="ai-tab-content active"></div><div id="ai-memories" class="ai-tab-content"></div><div id="ai-directives" class="ai-tab-content"></div>';
	}
	loadAiStatus();
	if (!aiInterval) aiInterval = setInterval(() => { if (currentTab === 'ai') loadAiStatus(); }, 10000);
}

function switchAiTab(tab) {
	currentAiTab = tab;
	var btns = document.querySelectorAll('.ai-tab-btn');
	for (var i = 0; i < btns.length; i++) {
		btns[i].classList.remove('active');
	}
	var activeBtn = document.querySelector('.ai-tab-btn[data-tab="'+tab+'"]');
	if (activeBtn) activeBtn.classList.add('active');
	var contents = document.querySelectorAll('.ai-tab-content');
	for (var i = 0; i < contents.length; i++) {
		contents[i].classList.remove('active');
	}
	var target = document.getElementById('ai-'+tab);
	if (target) target.classList.add('active');
	if (tab === 'memories') loadAiPlayers();
	if (tab === 'directives') loadAiDirectives();
}

async function loadAiStatus() {
	try {
		const r = await fetch('/api/ai/status');
		if (!r.ok) { document.getElementById('ai-status').innerHTML='<div class="ai-empty">Failed to load AI status</div>'; return; }
		const d = await r.json();
		renderAiStatus(d.bots || {});
	} catch(e) {
		document.getElementById('ai-status').innerHTML='<div class="ai-empty">Failed to load AI status: ' + escHtml(e.message) + '</div>';
	}
}

function renderAiStatus(bots) {
	const names = Object.keys(bots);
	if (names.length === 0) {
		document.getElementById('ai-status').innerHTML='<div class="ai-empty">No bots with AI loaded</div>';
		return;
	}

	let html = '<div class="ai-grid">' + names.map(name => {
		const ai = bots[name];
		const badge = ai.active
			? '<span class="ai-status-badge active">Active</span>'
			: '<span class="ai-status-badge inactive">Inactive</span>';
		return '<div class="ai-card">' +
			'<h3><span class="bot-status ' + (ai.connected ? 'online' : 'offline') + '"></span> ' + escHtml(name) + ' ' + badge + '</h3>' +
			'<div class="ai-info"><span class="ai-label">Provider:</span> <span class="ai-value">' + escHtml(ai.provider) + '</span></div>' +
			'<div class="ai-info"><span class="ai-label">Model:</span> <span class="ai-value">' + escHtml(ai.model) + '</span></div>' +
			'<div class="ai-info"><span class="ai-label">Interval:</span> <span class="ai-value">' + ai.interval + 's</span></div>' +
			'<div class="ai-info"><span class="ai-label">Prompt:</span> <span class="ai-value">' + escHtml(ai.promptName) + '</span></div>' +
		'</div>';
	}).join('') + '</div>';
	document.getElementById('ai-status').innerHTML = html;
}

async function loadAiPlayers() {
	try {
		// First get list of all bots (for selecting which bot to edit with)
		const botsR = await fetch('/api/ai/bots');
		if (!botsR.ok) throw new Error('Failed to load bots');
		const botsD = await botsR.json();

		// Then get players with memories (shared across all bots)
		const r = await fetch('/api/ai/memories/players');
		if (!r.ok) throw new Error('Failed to load players');
		const d = await r.json();

		renderAiPlayers(d.players || [], botsD.bots || []);
	} catch(e) {
		document.getElementById('ai-memories').innerHTML='<div class="ai-empty">Failed to load players: ' + escHtml(e.message) + '</div>';
	}
}

function renderAiPlayers(players, allBots) {
	// players is now a flat array (shared memories)
	// allBots is array of {name, hasAI, hasMemory}
	if (!allBots || allBots.length === 0) {
		document.getElementById('ai-memories').innerHTML='<div class="ai-empty">No bots available</div>';
		return;
	}

	let html = '<div class="form-group"><label>Select Bot (for editing):</label><select class="bot-select" onchange="onBotSelect(this.value)">';
	html += '<option value="">-- Select --</option>';
	allBots.forEach(bot => {
		html += '<option value="'+escHtml(bot.name)+'">'+escHtml(bot.name) + (bot.hasAI ? '' : ' (no AI)')+'</option>';
	});
	html += '</select></div>';

	// Player list (shared, no bot filtering)
	if (players && players.length > 0) {
		html += '<div class="player-list">' + players.map(player => {
			const selected = selectedPlayer === player ? 'selected' : '';
			return '<div class="player-card '+selected+'" onclick="selectPlayer(\\''+escHtml(player)+'\\')">'+escHtml(player)+'</div>';
		}).join('') + '</div>';
	} else {
		html += '<div class="ai-empty">No players with stored memories</div>';
	}

	if (selectedPlayer) {
		html += '<div id="playerMemoriesArea" style="margin-top:16px"></div>';
		setTimeout(() => loadPlayerMemories(selectedBot, selectedPlayer), 0);
	}

	document.getElementById('ai-memories').innerHTML = html;
}

function onBotSelect(botName) {
	selectedBot = botName;
}

function selectPlayer(playerName) {
	selectedPlayer = playerName;
	// Re-render to show selection highlight
	loadAiPlayers();
}

async function loadPlayerMemories(botName, playerName) {
	// Memories are shared, but we need a bot selected to edit
	if (!botName) {
		const area = document.getElementById('playerMemoriesArea');
		if (area) {
			area.innerHTML='<div class="ai-empty">Select a bot above to view/edit memories</div>';
		}
		return;
	}
	try {
		const r = await fetch('/api/ai/memories/'+encodeURIComponent(botName)+'/'+encodeURIComponent(playerName));
		if (!r.ok) throw new Error('Failed to load memories');
		const d = await r.json();
		renderPlayerMemories(d.memories || {}, botName, playerName);
	} catch(e) {
		const area = document.getElementById('playerMemoriesArea');
		if (area) {
			area.innerHTML='<div class="ai-empty">Failed to load memories: ' + escHtml(e.message) + '</div>';
		}
	}
}

function renderPlayerMemories(memories, botName, playerName) {
	const area = document.getElementById('playerMemoriesArea');
	if (!area) return; // Element doesn't exist yet

	const keys = Object.keys(memories);
	if (keys.length === 0) {
		area.innerHTML='<div class="ai-empty">No memories stored for '+escHtml(playerName)+'</div>';
		return;
	}

	let html = '<div class="memory-card"><h4>Memories for '+escHtml(playerName)+' (shared)</h4>';
	keys.forEach(key => {
		html += '<div class="memory-entry">'+
			'<span class="memory-key">'+escHtml(key)+'</span>'+
			'<span class="memory-value">'+escHtml(memories[key])+'</span>'+
			'<div class="memory-actions">'+
				'<button class="btn-sm btn-danger" onclick="deleteMemory(\\''+escHtml(botName)+'\\',\\''+escHtml(playerName)+'\\',\\''+escHtml(key)+'\\')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path></svg></button>'+
			'</div></div>';
	});
	html += '</div>';

	html += '<div class="memory-card"><h4>Add Memory</h4><div class="memory-form">'+
		'<input type="text" id="memoryKey" placeholder="Key (e.g., trust_level)">'+
		'<input type="text" id="memoryValue" placeholder="Value">'+
		'<button class="btn-sm btn-success" onclick="addMemory(\\''+escHtml(botName)+'\\',\\''+escHtml(playerName)+'\\')">Add</button>'+
		'</div></div>';

	document.getElementById('playerMemoriesArea').innerHTML = html;
}

async function deleteMemory(botName, playerName, key) {
	if (!confirm('Delete memory "'+key+'" for '+playerName+'?')) return;
	try {
		const r = await fetch('/api/ai/memories/'+encodeURIComponent(botName)+'/'+encodeURIComponent(playerName)+'/'+encodeURIComponent(key), { method: 'DELETE' });
		if (!r.ok) throw new Error('Failed to delete');
		loadPlayerMemories(botName, playerName);
	} catch(e) {
		alert('Failed to delete: ' + e.message);
	}
}

async function addMemory(botName, playerName) {
	const key = document.getElementById('memoryKey').value;
	const value = document.getElementById('memoryValue').value;
	if (!key || !value) { alert('Key and value required'); return; }
	try {
		const r = await fetch('/api/ai/memories/'+encodeURIComponent(botName)+'/'+encodeURIComponent(playerName), {
			method: 'POST',
			headers: { 'Content-Type': 'application/json' },
			body: JSON.stringify({ key, value })
		});
		if (!r.ok) throw new Error('Failed to add');
		document.getElementById('memoryKey').value = '';
		document.getElementById('memoryValue').value = '';
		loadPlayerMemories(botName, playerName);
	} catch(e) {
		alert('Failed to add: ' + e.message);
	}
}

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

		let html = '<div class="form-group"><label>Select Bot:</label><select class="bot-select" onchange="loadBotDirectives(this.value)">';
		html += '<option value="">-- Select --</option>';
		bots.forEach(bot => {
			html += '<option value="'+escHtml(bot.name)+'">'+escHtml(bot.name) + (bot.hasAI ? '' : ' (no AI)')+'</option>';
		});
		html += '</select></div><div id="directivesArea"></div>';
		document.getElementById('ai-directives').innerHTML = html;
	} catch(e) {
		document.getElementById('ai-directives').innerHTML='<div class="ai-empty">Failed to load bots: ' + escHtml(e.message) + '</div>';
	}
}

async function loadBotDirectives(botName) {
	if (!botName) { document.getElementById('directivesArea').innerHTML = ''; return; }
	try {
		const r = await fetch('/api/ai/directives/'+encodeURIComponent(botName));
		if (!r.ok) throw new Error('Failed to load directives');
		const d = await r.json();
		renderBotDirectives(d.directives || {}, botName);
	} catch(e) {
		document.getElementById('directivesArea').innerHTML='<div class="ai-empty">Failed to load: ' + escHtml(e.message) + '</div>';
	}
}

function renderBotDirectives(directives, botName) {
	const keys = Object.keys(directives);
	let html = '<div class="memory-card"><h4>Directives for '+escHtml(botName)+'</h4>';
	if (keys.length === 0) {
		html += '<div class="ai-empty">No directives set</div>';
	} else {
		keys.forEach(key => {
			html += '<div class="memory-entry">'+
				'<span class="memory-key">'+escHtml(key)+'</span>'+
				'<span class="memory-value">'+escHtml(directives[key])+'</span>'+
			'</div>';
		});
	}
	html += '</div>';

	html += '<div class="memory-card"><h4>Add Directive</h4><div class="form-group">'+
		'<label>Key</label><input type="text" id="directiveKey" placeholder="e.g., current_goal">'+
		'</div><div class="form-group">'+
		'<label>Value</label><textarea id="directiveValue" placeholder="Directive value"></textarea>'+
		'</div><button class="btn-sm btn-success" onclick="addDirective(\\''+escHtml(botName)+'\\')">Add</button>'+
		'</div>';

	document.getElementById('directivesArea').innerHTML = html;
}

async function addDirective(botName) {
	const key = document.getElementById('directiveKey').value;
	const value = document.getElementById('directiveValue').value;
	if (!key || !value) { alert('Key and value required'); return; }
	try {
		const r = await fetch('/api/ai/directives/'+encodeURIComponent(botName), {
			method: 'POST',
			headers: { 'Content-Type': 'application/json' },
			body: JSON.stringify({ key, value })
		});
		if (!r.ok) throw new Error('Failed to add');
		document.getElementById('directiveKey').value = '';
		document.getElementById('directiveValue').value = '';
		loadBotDirectives(botName);
	} catch(e) {
		alert('Failed to add: ' + e.message);
	}
}
	`,
};

module.exports = { createRouter, webUI };
