import config from 'config';
import path from 'path';
import { Reader } from '@maxmind/geoip2-node';

import initLogger from '../logger.js';

const logger = initLogger();
const regions = config.restrictions.regions;

export default async function initRestrictionHandler() {
	const reader = await Reader.open('assets/GeoLite2-City.mmdb');

	function getRestriction(req) {
		if (req.session.restriction && req.session.country && req.session.restrictionIp === req.userIp) {
			return {
				restriction: req.session.restriction,
				country: req.session.country,
			};
		}

		const location = reader.city(req.userIp);
		const country = location.country.isoCode;
		const subdivision = location.subdivisions?.[0]?.isoCode;

		if (regions[country]?.[subdivision]) {
			// state or province restriction
			return {
				restriction: config.restrictions.modes[regions[country][subdivision]],
				country,
			};
		}

		if (regions[country]) {
			// country restriction
			return {
				restriction: config.restrictions.modes[regions[country]],
				country,
			};
		}

		return {
			restriction: null,
			country,
		};
	}

	function restrictionHandler(req, res, next) {
		if (!config.restrictions.enabled) {
			next();
			return;
		}

		try {
			const { restriction, country } = getRestriction(req);

			if (restriction === 'block' || req.path === '/sfw/') {
				res.render(path.join(import.meta.dirname, '../../assets/sfw.ejs'), {
					noVpn: config.restrictions.noVpn.includes(country),
				});

				return;
			}

			if (req.session.restriction !== restriction) {
				req.session.restrictionIp = req.userIp;
				req.session.restriction = restriction;
				req.session.country = country;
			}

			req.restriction = restriction;
			req.country = country;
		} catch (error) {
			logger.error(`Failed Maxmind IP lookup for ${req.ip}: ${error.message}`);
		}

		next();
	}

	return restrictionHandler;
}
