import type { App, Response, NextFunction } from '@tinyhttp/app';
import { prisma } from '../config/database.js';
import { authMiddleware } from '../middleware/auth.js';
import { AuthenticatedRequest, UserRole } from '../types/index.js';

const adminMiddleware = async (req: AuthenticatedRequest, res: Response, next?: NextFunction) => {
	try {
		const user = await prisma.user.findUnique({
			where: { id: req.user!.id }
		});
		if (!user || user.role !== UserRole.Admin) {
			return res.status(403).json({ error: 'Forbidden', status: 403 });
		}
		return next?.();
	} catch (error) {
		console.error('Error fetching user:', error);
		return res.status(500).json({ error: 'Internal Server Error', status: 500 });
	}
};

export function setupSiteContentRoutes(app: App) {
	// Public endpoint - Get all site content (for frontend info.js)
	app.get('/api/site-content', async (req, res) => {
		try {
			const locale = (req.query['locale'] as string) || 'en';

			const content = await prisma.siteContent.findMany({
				where: {
					locale: locale,
				},
				select: {
					key: true,
					value: true,
					locale: true,
					updatedAt: true,
				},
			});

			// Convert to key-value object for easier consumption
			const contentMap: Record<string, string> = {};
			content.forEach((item) => {
				contentMap[item.key] = item.value;
			});

			return res.json({
				locale,
				content: contentMap,
				lastUpdated: content.length > 0 ? content[0]!.updatedAt : new Date(),
			});
		} catch (error) {
			console.error('Error fetching site content:', error);
			return res.status(500).json({ error: 'Failed to fetch site content', status: 500 });
		}
	});

	// Admin endpoint - Get all content for editing
	app.get(
		'/api/admin/site-content',
		authMiddleware,
		adminMiddleware,
		async (_req, res) => {
			try {
				const content = await prisma.siteContent.findMany({
					orderBy: [{ locale: 'asc' }, { key: 'asc' }],
				});

				return res.json({ content });
			} catch (error) {
				console.error('Error fetching site content:', error);
				return res.status(500).json({ error: 'Failed to fetch site content', status: 500 });
			}
		}
	);

	// Admin endpoint - Update or create content
	app.post(
		'/api/admin/site-content',
		authMiddleware,
		adminMiddleware,
		async (req: AuthenticatedRequest, res) => {
			try {
				const { key, value, locale = 'en' } = req.body;

				if (!key || value === undefined) {
					return res.status(400).json({ error: 'Key and value are required', status: 400 });
				}

				// Validate key format (alphanumeric, dots, underscores only)
				if (!/^[a-zA-Z0-9._]+$/.test(key)) {
					return res
						.status(400)
						.json({ error: 'Invalid key format. Use only letters, numbers, dots, and underscores', status: 400 });
				}

				const content = await prisma.siteContent.upsert({
					where: {
						key: key,
					},
					update: {
						value: value,
						locale: locale,
					},
					create: {
						key: key,
						value: value,
						locale: locale,
					},
				});

				return res.json({ content });
			} catch (error) {
				console.error('Error updating site content:', error);
				return res.status(500).json({ error: 'Failed to update site content', status: 500 });
			}
		}
	);

	// Admin endpoint - Bulk update content
	app.post(
		'/api/admin/site-content/bulk',
		authMiddleware,
		adminMiddleware,
		async (req: AuthenticatedRequest, res) => {
			try {
				const { items } = req.body;

				if (!Array.isArray(items)) {
					return res.status(400).json({ error: 'Items must be an array', status: 400 });
				}

				// Validate all items
				for (const item of items) {
					if (!item.key || item.value === undefined) {
						return res.status(400).json({ error: 'Each item must have key and value', status: 400 });
					}
					if (!/^[a-zA-Z0-9._]+$/.test(item.key)) {
						return res
							.status(400)
							.json({ error: `Invalid key format: ${item.key}`, status: 400 });
					}
				}

				// Perform bulk upsert
				const results = await Promise.all(
					items.map((item: { key: string; value: string; locale?: string }) =>
						prisma.siteContent.upsert({
							where: {
								key: item.key,
							},
							update: {
								value: item.value,
								locale: item.locale || 'en',
							},
							create: {
								key: item.key,
								value: item.value,
								locale: item.locale || 'en',
							},
						})
					)
				);

				return res.json({ updated: results.length, content: results });
			} catch (error) {
				console.error('Error bulk updating site content:', error);
				return res.status(500).json({ error: 'Failed to bulk update site content', status: 500 });
			}
		}
	);

	// Admin endpoint - Delete content
	app.delete(
		'/api/admin/site-content/:key',
		authMiddleware,
		adminMiddleware,
		async (req, res) => {
			try {
				const key = req.params['key'];
				if (!key) {
					return res.status(400).json({ error: 'Key is required', status: 400 });
				}

				await prisma.siteContent.delete({
					where: {
						key: key,
					},
				});

				return res.json({ success: true });
			} catch (error) {
				console.error('Error deleting site content:', error);
				return res.status(500).json({ error: 'Failed to delete site content', status: 500 });
			}
		}
	);

	// Admin endpoint - Initialize default content
	app.post(
		'/api/admin/site-content/initialize',
		authMiddleware,
		adminMiddleware,
		async (_req, res) => {
			try {
				// Default content structure
				const defaultContent = [
					// English content
					{ key: 'site.title', value: 'openplace', locale: 'en' },
					{ key: 'modal.overview.title', value: 'Overview', locale: 'en' },
					{
						key: 'modal.overview.videoUrl',
						value: 'https://www.youtube.com/embed/xOXtd-WzRxA?si=fHz8Z6ecXGYrDhkN',
						locale: 'en',
					},
					{ key: 'modal.paintFaster.title', value: 'How to paint faster', locale: 'en' },
					{
						key: 'modal.paintFaster.mobile',
						value:
							'When painting, click on the button on the top right corner of the screen. This will lock the screen but it\'ll also enable painting by moving your finger over the map.',
						locale: 'en',
					},
					{
						key: 'modal.paintFaster.desktop',
						value: 'Hold SPACE and move your cursor over the map.',
						locale: 'en',
					},
					{ key: 'modal.mapLagging.title', value: 'My map is lagging', locale: 'en' },
					{
						key: 'modal.mapLagging.text',
						value: 'Follow the instructions to enable hardware acceleration:',
						locale: 'en',
					},
					{
						key: 'modal.mapLagging.link',
						value: 'https://help.constructiononline.com/en/scheduling-webgl-and-hardware-acceleration',
						locale: 'en',
					},
					{ key: 'modal.rules.title', value: 'Rules', locale: 'en' },
					{ key: 'modal.rules.badge', value: 'Important', locale: 'en' },
					{
						key: 'modal.rules.item.0',
						value:
							'📜 All users are responsible for the content they post. The platform reserves the right of final interpretation.',
						locale: 'en',
					},
					{
						key: 'modal.rules.item.1',
						value:
							'🛑 Any violation may result in immediate removal of content and permanent ban of the account',
						locale: 'en',
					},
					{
						key: 'modal.rules.item.2',
						value:
							'😈 Do not paint over other artworks using random colors or patterns just to mess things up',
						locale: 'en',
					},
					{
						key: 'modal.rules.item.3',
						value: '🙅 Disclosing other\'s personal information is not allowed',
						locale: 'en',
					},
					{
						key: 'modal.rules.footer',
						value: 'Violations of these rules may result in suspension of your account.',
						locale: 'en',
					},
					{ key: 'modal.footer.email', value: 'contact@wplace.live', locale: 'en' },
					{ key: 'modal.footer.discord.url', value: 'https://discord.gg/ZRC4DnP9Z2', locale: 'en' },
					{ key: 'modal.footer.discord.text', value: 'Feedback and bugs', locale: 'en' },
					{
						key: 'modal.footer.github.url',
						value: 'https://github.com/openplaceteam',
						locale: 'en',
					},
					{ key: 'modal.footer.github.text', value: 'Github', locale: 'en' },
					{
						key: 'modal.footer.instagram.url',
						value: 'https://www.instagram.com/wplace.live/',
						locale: 'en',
					},
					{ key: 'modal.footer.instagram.text', value: 'Instagram', locale: 'en' },
					{ key: 'modal.footer.terms.text', value: 'Terms', locale: 'en' },
					{
						key: 'modal.footer.terms.url',
						value: 'https://wplace.live/terms/terms-of-service',
						locale: 'en',
					},
					{ key: 'modal.footer.privacy.text', value: 'Privacy', locale: 'en' },
					{
						key: 'modal.footer.privacy.url',
						value: 'https://wplace.live/terms/privacy',
						locale: 'en',
					},

					// Chinese content
					{ key: 'site.title', value: 'openplace', locale: 'zh' },
					{ key: 'modal.overview.title', value: '概述', locale: 'zh' },
					{
						key: 'modal.overview.videoUrl',
						value: 'https://www.youtube.com/embed/xOXtd-WzRxA?si=fHz8Z6ecXGYrDhkN',
						locale: 'zh',
					},
					{ key: 'modal.paintFaster.title', value: '如何画得更快？', locale: 'zh' },
					{
						key: 'modal.paintFaster.mobile',
						value: '在绘制时候按住按钮屏幕右上角。这将锁定屏幕，但也可以通过在地图上移动手指来绘画.',
						locale: 'zh',
					},
					{ key: 'modal.paintFaster.desktop', value: '按住空格并且移动鼠标.', locale: 'zh' },
					{ key: 'modal.mapLagging.title', value: '地图卡顿', locale: 'zh' },
					{ key: 'modal.mapLagging.text', value: '请按照说明启用硬件加速：', locale: 'zh' },
					{
						key: 'modal.mapLagging.link',
						value: 'https://help.constructiononline.com/en/scheduling-webgl-and-hardware-acceleration',
						locale: 'zh',
					},
					{ key: 'modal.rules.title', value: '规则', locale: 'zh' },
					{ key: 'modal.rules.badge', value: '重要', locale: 'zh' },
					{
						key: 'modal.rules.item.0',
						value: '📜 所有用户对其发布的内容负责。平台保留最终解释权。',
						locale: 'zh',
					},
					{
						key: 'modal.rules.item.1',
						value: '🛑 任何违规行为可能导致内容立即删除和账户永久封禁',
						locale: 'zh',
					},
					{
						key: 'modal.rules.item.2',
						value: '😈 请勿使用随机颜色或图案覆盖其他作品',
						locale: 'zh',
					},
					{ key: 'modal.rules.item.3', value: '🙅 不允许泄露他人个人信息', locale: 'zh' },
					{ key: 'modal.rules.footer', value: '违反会导致你被封禁。', locale: 'zh' },
					{ key: 'modal.footer.email', value: 'contact@wplace.live', locale: 'zh' },
					{ key: 'modal.footer.discord.url', value: 'https://discord.gg/ZRC4DnP9Z2', locale: 'zh' },
					{ key: 'modal.footer.discord.text', value: '反馈和错误报告', locale: 'zh' },
					{
						key: 'modal.footer.github.url',
						value: 'https://github.com/openplaceteam',
						locale: 'zh',
					},
					{ key: 'modal.footer.github.text', value: 'Github', locale: 'zh' },
					{
						key: 'modal.footer.instagram.url',
						value: 'https://www.instagram.com/wplace.live/',
						locale: 'zh',
					},
					{ key: 'modal.footer.instagram.text', value: 'Instagram', locale: 'zh' },
					{ key: 'modal.footer.terms.text', value: '条款', locale: 'zh' },
					{
						key: 'modal.footer.terms.url',
						value: 'https://wplace.live/terms/terms-of-service',
						locale: 'zh',
					},
					{ key: 'modal.footer.privacy.text', value: '隐私', locale: 'zh' },
					{
						key: 'modal.footer.privacy.url',
						value: 'https://wplace.live/terms/privacy',
						locale: 'zh',
					},
				];

				// Use bulk upsert to avoid duplicates
				const results = await Promise.all(
					defaultContent.map((item) =>
						prisma.siteContent.upsert({
							where: {
								key: item.key,
							},
							update: {
								value: item.value,
								locale: item.locale,
							},
							create: item,
						})
					)
				);

				return res.json({ initialized: results.length, content: results });
			} catch (error) {
				console.error('Error initializing site content:', error);
				return res.status(500).json({ error: 'Failed to initialize site content', status: 500 });
			}
		}
	);
}
