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 setupRulesRoutes(app: App) {
	// Public endpoint - Get rules for display
	app.get('/api/rules', async (req, res) => {
		try {
			const locale = (req.query['locale'] as string) || 'en';

			const rules = await prisma.rule.findMany({
				where: {
					locale: locale,
					enabled: true,
				},
				orderBy: {
					order: 'asc',
				},
				select: {
					id: true,
					text: true,
					order: true,
				},
			});

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

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

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

	// Admin endpoint - Create or update a rule
	app.post(
		'/api/admin/rules',
		authMiddleware,
		adminMiddleware,
		async (req: AuthenticatedRequest, res) => {
			try {
				const { id, text, locale = 'en', order, enabled = true } = req.body;

				if (!text || order === undefined) {
					return res.status(400).json({ error: 'Text and order are required', status: 400 });
				}

				let rule;
				if (id) {
					// Update existing rule
					rule = await prisma.rule.update({
						where: { id },
						data: {
							text,
							locale,
							order,
							enabled,
						},
					});
				} else {
					// Create new rule
					rule = await prisma.rule.create({
						data: {
							text,
							locale,
							order,
							enabled,
						},
					});
				}

				return res.json({ rule });
			} catch (error) {
				console.error('Error saving rule:', error);
				return res.status(500).json({ error: 'Failed to save rule', status: 500 });
			}
		}
	);

	// Admin endpoint - Delete a rule
	app.delete(
		'/api/admin/rules/:id',
		authMiddleware,
		adminMiddleware,
		async (req, res) => {
			try {
				const id = parseInt(req.params['id'] || '');
				if (isNaN(id)) {
					return res.status(400).json({ error: 'Invalid rule ID', status: 400 });
				}

				await prisma.rule.delete({
					where: { id },
				});

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

	// Admin endpoint - Initialize default rules
	app.post(
		'/api/admin/rules/initialize',
		authMiddleware,
		adminMiddleware,
		async (_req, res) => {
			try {
				const defaultRules = [
					// English rules
					{
						text: '😈 Do not paint over other artworks using random colors or patterns just to mess things up',
						locale: 'en',
						order: 0,
						enabled: true,
					},
					{
						text: '🚫 No inappropriate content (+18, hate speech, inappropriate links, highly suggestive material, ...)',
						locale: 'en',
						order: 1,
						enabled: true,
					},
					{
						text: '🧑‍🤝‍🧑 Do not paint with more than one account',
						locale: 'en',
						order: 2,
						enabled: true,
					},
					{
						text: '🤖 Use of bots is not allowed',
						locale: 'en',
						order: 3,
						enabled: true,
					},
					{
						text: "🙅 Disclosing other's personal information is not allowed",
						locale: 'en',
						order: 4,
						enabled: true,
					},
					{
						text: '✅ Painting over other artworks to complement them or create a new drawing is allowed',
						locale: 'en',
						order: 5,
						enabled: true,
					},
					{
						text: '✅ Griefing political party flags or portraits of politicians is allowed',
						locale: 'en',
						order: 6,
						enabled: true,
					},

					// Portuguese rules
					{
						text: '😈 Não desenhe sobre outras obras usando cores ou padrões aleatórios apenas para estragar as coisas',
						locale: 'pt',
						order: 0,
						enabled: true,
					},
					{
						text: '🚫 Sem conteúdo inapropriado (+18, discurso de ódio, links inapropriados, material altamente sugestivo, ...)',
						locale: 'pt',
						order: 1,
						enabled: true,
					},
					{
						text: '🧑‍🤝‍🧑 Não desenhe com mais de uma conta',
						locale: 'pt',
						order: 2,
						enabled: true,
					},
					{
						text: '🤖 O uso de bots não é permitido',
						locale: 'pt',
						order: 3,
						enabled: true,
					},
					{
						text: '🙅 A divulgação de informações pessoais de terceiros não é permitida',
						locale: 'pt',
						order: 4,
						enabled: true,
					},
					{
						text: '✅ Desenhar sobre outras artes para complementar ou criar novas artes é permitido',
						locale: 'pt',
						order: 5,
						enabled: true,
					},
					{
						text: '✅ Desenhar sobre bandeiras de partidos e retratos de políticos é permitido',
						locale: 'pt',
						order: 6,
						enabled: true,
					},
				];

				const results = await Promise.all(
					defaultRules.map((rule) =>
						prisma.rule.create({
							data: rule,
						})
					)
				);

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