import { Application } from 'express';
import { Resource } from 'express-automatic-routes';
import { SystemAuditLog } from '#models/SystemAuditLog';
import { Req, Res } from '#interfaces/IApi';
import verify from '#middlewares/auth';
import { requireAdmin } from '#middlewares/auth';
import { auditAccessLogger } from '#middlewares/audit-access-logger';
import { queryModifier } from '#middlewares/query-modifier';
import Logger from '#utils/logger';
import auditMetrics from '#utils/auditMetrics';

export default (_express: Application) => {
	return <Resource>{
		get: {
			middleware: [verify, requireAdmin, queryModifier, auditAccessLogger('EXPORTED')],
			handler: async (req: Req, res: Res) => {
				try {
					const { maxRecords = 10000 } = req.query;
					const { filters } = req.payload || {};

					// Validate maxRecords
					const exportLimit = Math.min(parseInt(maxRecords as string), 10000);

					const where: any = filters || {};

					const logs = await SystemAuditLog.findAll({
						where,
						order: [['created_at', 'DESC']],
						limit: exportLimit,
					});

					// Convert to CSV
					const headers = [
						'created_at',
						'action',
						'module',
						'actor_id',
						'actor_name',
						'actor_email',
						'actor_role',
						'entity_type',
						'entity_id',
						'description',
						'severity',
						'ip_address',
						'success',
						'failure_reason',
					];

					const csvRows = logs.map((log) => {
						return headers
							.map((header) => {
								const value = (log as any)[header];
								// Escape quotes and wrap in quotes if contains comma or quote
								const stringValue = value !== null && value !== undefined ? String(value) : '';
								if (stringValue.includes(',') || stringValue.includes('"') || stringValue.includes('\n')) {
									return `"${stringValue.replace(/"/g, '""')}"`;
								}
								return stringValue;
							})
							.join(',');
					});

					const csvContent = [headers.join(','), ...csvRows].join('\n');

					Logger.info(`Exported ${logs.length} audit logs to CSV`);

					// Record metric
					try {
						auditMetrics.auditLogExports.inc({ format: 'csv', record_count: logs.length.toString() });
					} catch {
						// Metrics optional, don't fail if not available
					}

					res.setHeader('Content-Type', 'text/csv');
					res.setHeader('Content-Disposition', `attachment; filename=audit-export-${Date.now()}.csv`);
					return res.send(csvContent);
				} catch (error) {
					return res.error(error);
				}
			},
		},
	};
};
