'use strict';

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

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

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

	router.get('/api/invite/sites', async (req, res) => {
		if (!dbAvailable()) return res.status(503).json({ error: 'Database not initialized' });
		try {
			const sites = await database.getInviteSites();
			// Add bot online status
			const result = sites.map(s => ({
				...s,
				players: s.players ? s.players.split(',') : [],
				bot_online: !!(CJbot.bots[s.bot_name] && CJbot.bots[s.bot_name].isReady),
			}));
			res.json({ sites: result });
		} catch (error) {
			console.error('API Error /api/invite/sites:', error);
			res.status(500).json({ error: error.message });
		}
	});

	router.get('/api/invite/bots', (req, res) => {
		try {
			const bots = Object.keys(CJbot.bots);
			res.json({ bots });
		} catch (error) {
			res.status(500).json({ error: error.message });
		}
	});

	router.get('/api/invite/online-players', (req, res) => {
		try {
			const playerSet = new Set();
			for (const bot of Object.values(CJbot.bots)) {
				if (bot.isReady && bot.bot && bot.bot.players) {
					for (const name of Object.keys(bot.bot.players)) {
						playerSet.add(name);
					}
				}
			}
			res.json({ players: [...playerSet].sort() });
		} catch (error) {
			res.status(500).json({ error: error.message });
		}
	});

	router.post('/api/invite/sites', async (req, res) => {
		if (!dbAvailable()) return res.status(503).json({ error: 'Database not initialized' });
		try {
			const { name, label, bot_name, description } = req.body;
			if (!name || !label || !bot_name) {
				return res.status(400).json({ error: 'Missing name, label, or bot_name' });
			}
			await database.addInviteSite(name, label, bot_name, description);
			res.json({ status: 'created' });
		} catch (error) {
			if (error.message && error.message.includes('UNIQUE')) {
				return res.status(409).json({ error: 'Site name already exists' });
			}
			console.error('API Error POST /api/invite/sites:', error);
			res.status(500).json({ error: error.message });
		}
	});

	router.put('/api/invite/sites/:id', async (req, res) => {
		if (!dbAvailable()) return res.status(503).json({ error: 'Database not initialized' });
		try {
			const id = parseInt(req.params.id);
			await database.updateInviteSite(id, req.body);
			res.json({ status: 'updated' });
		} catch (error) {
			console.error('API Error PUT /api/invite/sites/:id:', error);
			res.status(500).json({ error: error.message });
		}
	});

	router.delete('/api/invite/sites/:id', async (req, res) => {
		if (!dbAvailable()) return res.status(503).json({ error: 'Database not initialized' });
		try {
			const id = parseInt(req.params.id);
			await database.deleteInviteSite(id);
			res.json({ status: 'deleted' });
		} catch (error) {
			console.error('API Error DELETE /api/invite/sites/:id:', error);
			res.status(500).json({ error: error.message });
		}
	});

	router.post('/api/invite/sites/:id/players', async (req, res) => {
		if (!dbAvailable()) return res.status(503).json({ error: 'Database not initialized' });
		try {
			const siteId = parseInt(req.params.id);
			const { player_name } = req.body;
			if (!player_name) return res.status(400).json({ error: 'Missing player_name' });
			await database.addInvitePermission(siteId, player_name);
			res.json({ status: 'added' });
		} catch (error) {
			console.error('API Error POST /api/invite/sites/:id/players:', error);
			res.status(500).json({ error: error.message });
		}
	});

	router.delete('/api/invite/sites/:id/players/:player', async (req, res) => {
		if (!dbAvailable()) return res.status(503).json({ error: 'Database not initialized' });
		try {
			const siteId = parseInt(req.params.id);
			const playerName = req.params.player;
			await database.removeInvitePermission(siteId, playerName);
			res.json({ status: 'removed' });
		} catch (error) {
			console.error('API Error DELETE /api/invite/sites/:id/players/:player:', error);
			res.status(500).json({ error: error.message });
		}
	});

	router.post('/api/invite/trigger', async (req, res) => {
		if (!dbAvailable()) return res.status(503).json({ error: 'Database not initialized' });
		try {
			const { siteName, playerName } = req.body;
			if (!siteName || !playerName) {
				return res.status(400).json({ error: 'Missing siteName or playerName' });
			}

			const site = await database.getInviteSiteByName(siteName);
			if (!site) return res.status(404).json({ error: 'Site not found' });

			const allowed = await database.isPlayerAllowedAtSite(siteName, playerName);
			if (!allowed) return res.status(403).json({ error: `${playerName} is not allowed at ${siteName}` });

			const Invite = require('./invite');
			Invite.executeInvite(site.bot_name, playerName)
				.catch(err => console.error('Web invite trigger error:', err));

			res.json({ status: 'triggered', message: `Invite sent for ${playerName} via ${site.bot_name}` });
		} catch (error) {
			console.error('API Error POST /api/invite/trigger:', error);
			res.status(500).json({ error: error.message });
		}
	});

	return router;
}

const webUI = {
	tabId: 'invites',
	tabLabel: 'Invites',
	tabOrder: 30,
	html: `
		<div id="inviteArea">
			<div style="padding:20px;color:#6b7280;text-align:center">Loading invite sites...</div>
		</div>
	`,
	css: `
		.invite-toolbar{display:flex;gap:8px;margin-bottom:16px;align-items:center;flex-wrap:wrap}
		.invite-toolbar button{background:#2563eb;color:#fff;border:none;padding:8px 16px;border-radius:6px;cursor:pointer;font-size:.85em}
		.invite-toolbar button:hover{background:#1d4ed8}
		.invite-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(380px,1fr));gap:16px}
		.invite-card{background:#1f2937;border:1px solid #374151;border-radius:8px;padding:16px;transition:border-color .2s}
		.invite-card:hover{border-color:#60a5fa}
		.invite-card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}
		.invite-card-header h3{font-size:1em;color:#60a5fa;display:flex;align-items:center;gap:8px}
		.invite-card-header .actions{display:flex;gap:4px}
		.invite-card-header .actions button{background:none;border:1px solid #374151;color:#9ca3af;padding:4px 8px;border-radius:4px;cursor:pointer;font-size:.75em}
		.invite-card-header .actions button:hover{border-color:#60a5fa;color:#60a5fa}
		.invite-card-header .actions button.del:hover{border-color:#ef4444;color:#ef4444}
		.invite-meta{font-size:.8em;color:#9ca3af;margin-bottom:10px}
		.invite-meta span{margin-right:12px}
		.invite-players{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:10px;min-height:28px}
		.player-chip{background:#1e3a5f;color:#60a5fa;padding:3px 8px;border-radius:12px;font-size:.8em;display:flex;align-items:center;gap:4px}
		.player-chip .remove{background:none;border:none;color:#ef4444;cursor:pointer;font-size:.9em;padding:0 2px;line-height:1}
		.player-chip .remove:hover{color:#f87171}
		.invite-add-player{display:flex;gap:4px;margin-bottom:10px}
		.invite-add-player input{flex:1;padding:6px 8px;border:1px solid #374151;border-radius:4px;background:#111827;color:#e5e7eb;font-size:.8em}
		.invite-add-player button{background:#059669;color:#fff;border:none;padding:6px 10px;border-radius:4px;cursor:pointer;font-size:.8em}
		.invite-add-player button:hover{background:#047857}
		.invite-trigger{display:flex;gap:4px;align-items:center}
		.invite-trigger input{flex:1;padding:6px 8px;border:1px solid #374151;border-radius:4px;background:#111827;color:#e5e7eb;font-size:.8em}
		.invite-trigger button{background:#7c3aed;color:#fff;border:none;padding:6px 10px;border-radius:4px;cursor:pointer;font-size:.8em}
		.invite-trigger button:hover{background:#6d28d9}
		.invite-trigger-status{font-size:.8em;min-height:16px;margin-top:4px}
		.invite-modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.6);z-index:100;display:flex;align-items:center;justify-content:center}
		.invite-modal{background:#1f2937;border:1px solid #374151;border-radius:8px;padding:24px;width:400px;max-width:90vw}
		.invite-modal h3{color:#60a5fa;margin-bottom:16px}
		.invite-modal label{display:block;font-size:.85em;color:#9ca3af;margin-bottom:4px;margin-top:12px}
		.invite-modal input,.invite-modal select,.invite-modal textarea{width:100%;padding:8px;border:1px solid #374151;border-radius:6px;background:#111827;color:#e5e7eb;font-size:.85em;box-sizing:border-box}
		.invite-modal textarea{resize:vertical;min-height:60px}
		.invite-modal .modal-actions{display:flex;gap:8px;margin-top:20px;justify-content:flex-end}
		.invite-modal .modal-actions button{padding:8px 16px;border-radius:6px;cursor:pointer;font-size:.85em;border:none}
		.invite-modal .modal-actions .btn-save{background:#2563eb;color:#fff}
		.invite-modal .modal-actions .btn-save:hover{background:#1d4ed8}
		.invite-modal .modal-actions .btn-cancel{background:#374151;color:#e5e7eb}
		.invite-modal .modal-actions .btn-cancel:hover{background:#4b5563}
		.invite-empty{padding:40px 20px;color:#6b7280;text-align:center;font-size:.9em}
	`,
	onTabActive: 'onInviteTabActive',
	js: `
let inviteSites=[], inviteBots=[], inviteLoaded=false, inviteOnlinePlayers=[];

function onInviteTabActive() {
	if (!inviteLoaded) loadInviteSites();
}

async function loadInviteSites() {
	try {
		const [sitesRes, botsRes, playersRes] = await Promise.all([
			fetch('/api/invite/sites'),
			fetch('/api/invite/bots'),
			fetch('/api/invite/online-players')
		]);
		if (!sitesRes.ok || !botsRes.ok) {
			document.getElementById('inviteArea').innerHTML='<div class="invite-empty">Failed to load invite data</div>';
			return;
		}
		const sitesData = await sitesRes.json();
		const botsData = await botsRes.json();
		inviteSites = sitesData.sites || [];
		inviteBots = botsData.bots || [];
		if (playersRes.ok) {
			const playersData = await playersRes.json();
			inviteOnlinePlayers = playersData.players || [];
		}
		inviteLoaded = true;
		renderInviteSites();
	} catch(e) {
		document.getElementById('inviteArea').innerHTML='<div class="invite-empty">Failed to load invite data</div>';
	}
}

function renderInviteSites() {
	const area = document.getElementById('inviteArea');
	let html = '<div class="invite-toolbar">' +
		'<button onclick="showInviteModal()">+ Add Site</button>' +
		'<button onclick="loadInviteSites()" style="background:#374151">Refresh</button>' +
	'</div>';

	if (inviteSites.length === 0) {
		html += '<div class="invite-empty">No invite sites configured</div>';
		area.innerHTML = html;
		return;
	}

	html += '<div class="invite-grid">';
	for (const site of inviteSites) {
		const statusCls = site.bot_online ? 'online' : 'offline';
		const playerChips = (site.players || []).map(p =>
			'<span class="player-chip">' + escHtml(p) +
			' <button class="remove" onclick="removeInvitePlayer(' + site.id + ',\\'' + escHtml(p) + '\\')">&times;</button>' +
			'</span>'
		).join('');

		html += '<div class="invite-card">' +
			'<div class="invite-card-header">' +
				'<h3><span class="bot-status ' + statusCls + '"></span> ' + escHtml(site.label) + ' (' + escHtml(site.name) + ')</h3>' +
				'<div class="actions">' +
					'<button onclick="showInviteModal(' + site.id + ')">Edit</button>' +
					'<button class="del" onclick="deleteInviteSite(' + site.id + ',\\'' + escHtml(site.name) + '\\')">Delete</button>' +
				'</div>' +
			'</div>' +
			'<div class="invite-meta">' +
				'<span>Bot: <strong>' + escHtml(site.bot_name) + '</strong></span>' +
				(site.description ? '<span>' + escHtml(site.description) + '</span>' : '') +
			'</div>' +
			'<div class="invite-players">' + (playerChips || '<span style="color:#6b7280;font-size:.8em">No players</span>') + '</div>' +
			'<div class="invite-add-player">' +
				'<div class="ac-wrap" style="flex:1">' +
					'<input type="text" placeholder="Player name" id="inv-add-' + site.id + '" autocomplete="off" onkeydown="if(event.key===\\'Enter\\')addInvitePlayer(' + site.id + ')">' +
					'<div class="ac-list" id="ac-inv-add-' + site.id + '"></div>' +
				'</div>' +
				'<button onclick="addInvitePlayer(' + site.id + ')">Add</button>' +
			'</div>' +
			'<div class="invite-trigger">' +
				'<div class="ac-wrap" style="flex:1">' +
					'<input type="text" placeholder="Player to invite" id="inv-trig-' + site.id + '" autocomplete="off">' +
					'<div class="ac-list" id="ac-inv-trig-' + site.id + '"></div>' +
				'</div>' +
				'<button onclick="triggerInvite(\\'' + escHtml(site.name) + '\\',' + site.id + ')">Invite</button>' +
			'</div>' +
			'<div class="invite-trigger-status" id="inv-status-' + site.id + '"></div>' +
		'</div>';
	}
	html += '</div>';
	area.innerHTML = html;

	// Wire up autocomplete on player inputs
	for (const site of inviteSites) {
		setupAC('inv-add-' + site.id, 'ac-inv-add-' + site.id,
			q => {
				const lower = q.toLowerCase();
				return inviteOnlinePlayers
					.filter(p => !lower || p.toLowerCase().includes(lower))
					.map(p => ({label: p, value: p}));
			}
		);
		setupAC('inv-trig-' + site.id, 'ac-inv-trig-' + site.id,
			q => {
				const lower = q.toLowerCase();
				return inviteOnlinePlayers
					.filter(p => !lower || p.toLowerCase().includes(lower))
					.map(p => ({label: p, value: p}));
			}
		);
	}
}

function showInviteModal(editId) {
	const site = editId ? inviteSites.find(s => s.id === editId) : null;
	const title = site ? 'Edit Site' : 'Add Site';
	const botOptions = inviteBots.map(b =>
		'<option value="' + escHtml(b) + '"' + (site && site.bot_name === b ? ' selected' : '') + '>' + escHtml(b) + '</option>'
	).join('');

	const overlay = document.createElement('div');
	overlay.className = 'invite-modal-overlay';
	overlay.id = 'inviteModalOverlay';
	overlay.innerHTML = '<div class="invite-modal">' +
		'<h3>' + title + '</h3>' +
		'<label>Short Name (key)</label>' +
		'<input type="text" id="invModalName" value="' + (site ? escHtml(site.name) : '') + '">' +
		'<label>Display Label</label>' +
		'<input type="text" id="invModalLabel" value="' + (site ? escHtml(site.label) : '') + '">' +
		'<label>Bot</label>' +
		'<select id="invModalBot">' + botOptions + '</select>' +
		'<label>Description</label>' +
		'<textarea id="invModalDesc">' + (site ? escHtml(site.description || '') : '') + '</textarea>' +
		'<div class="modal-actions">' +
			'<button class="btn-cancel" onclick="closeInviteModal()">Cancel</button>' +
			'<button class="btn-save" onclick="saveInviteSite(' + (editId || 'null') + ')">Save</button>' +
		'</div>' +
	'</div>';
	document.body.appendChild(overlay);
	overlay.addEventListener('click', e => { if (e.target === overlay) closeInviteModal(); });
}

function closeInviteModal() {
	const el = document.getElementById('inviteModalOverlay');
	if (el) el.remove();
}

async function saveInviteSite(editId) {
	const name = document.getElementById('invModalName').value.trim();
	const label = document.getElementById('invModalLabel').value.trim();
	const bot_name = document.getElementById('invModalBot').value;
	const description = document.getElementById('invModalDesc').value.trim();

	if (!name || !label || !bot_name) { showToast('Fill in name, label, and bot', 'warning'); return; }

	try {
		let r;
		if (editId) {
			r = await fetch('/api/invite/sites/' + editId, {
				method: 'PUT',
				headers: {'Content-Type':'application/json'},
				body: JSON.stringify({ name, label, bot_name, description })
			});
		} else {
			r = await fetch('/api/invite/sites', {
				method: 'POST',
				headers: {'Content-Type':'application/json'},
				body: JSON.stringify({ name, label, bot_name, description })
			});
		}
		const d = await r.json();
		if (!r.ok) { showToast(d.error || 'Failed', 'error'); return; }
		closeInviteModal();
		showToast('Site saved', 'success');
		loadInviteSites();
	} catch(e) { showToast('Network error', 'error'); }
}

async function deleteInviteSite(id, name) {
	if (!confirm('Delete site "' + name + '"? This removes all permissions too.')) return;
	try {
		const r = await fetch('/api/invite/sites/' + id, { method: 'DELETE' });
		if (!r.ok) { const d = await r.json(); showToast(d.error || 'Failed', 'error'); return; }
		showToast('Site deleted', 'success');
		loadInviteSites();
	} catch(e) { showToast('Network error', 'error'); }
}

async function addInvitePlayer(siteId) {
	const input = document.getElementById('inv-add-' + siteId);
	const name = input.value.trim();
	if (!name) return;
	try {
		const r = await fetch('/api/invite/sites/' + siteId + '/players', {
			method: 'POST',
			headers: {'Content-Type':'application/json'},
			body: JSON.stringify({ player_name: name })
		});
		if (!r.ok) { const d = await r.json(); showToast(d.error || 'Failed', 'error'); return; }
		input.value = '';
		showToast('Player added', 'success');
		loadInviteSites();
	} catch(e) { showToast('Network error', 'error'); }
}

async function removeInvitePlayer(siteId, playerName) {
	try {
		const r = await fetch('/api/invite/sites/' + siteId + '/players/' + encodeURIComponent(playerName), { method: 'DELETE' });
		if (!r.ok) { const d = await r.json(); showToast(d.error || 'Failed', 'error'); return; }
		showToast('Player removed', 'success');
		loadInviteSites();
	} catch(e) { showToast('Network error', 'error'); }
}

async function triggerInvite(siteName, siteId) {
	const input = document.getElementById('inv-trig-' + siteId);
	const statusEl = document.getElementById('inv-status-' + siteId);
	const playerName = input.value.trim();
	if (!playerName) { statusEl.textContent = 'Enter player name'; statusEl.style.color = '#ef4444'; return; }
	try {
		statusEl.textContent = 'Sending invite...';
		statusEl.style.color = '#9ca3af';
		const r = await fetch('/api/invite/trigger', {
			method: 'POST',
			headers: {'Content-Type':'application/json'},
			body: JSON.stringify({ siteName, playerName })
		});
		const d = await r.json();
		statusEl.textContent = r.ok ? (d.message || 'Triggered') : (d.error || 'Failed');
		statusEl.style.color = r.ok ? '#10b981' : '#ef4444';
	} catch(e) {
		statusEl.textContent = 'Network error';
		statusEl.style.color = '#ef4444';
	}
}
	`,
};

module.exports = { name: 'Invite', createRouter, webUI };
