import assert from 'node:assert';
import {createServer} from 'node:http';
import {parse as parseQueryString} from 'node:querystring';

const webhook = process.argv[2] || process.env.WEBHOOK_URL;
assert(webhook, 'give me a webhook url please');

const port = process.env.PORT || 80;

createServer(async (request, response) => {
	const host = (process.env.TRUST_X_FORWARDED_HOST && request.headers['x-forwarded-host']) || `localhost:${port}`;
	const proto = (process.env.TRUST_X_FORWARDED_PROTO && request.headers['x-forwarded-proto']) || 'http';
	const url = new URL(`${proto}://${host}${request.url}`);

	/** @type {import('node:http').OutgoingHttpHeaders} */
	const cors = {
		'Vary': 'Origin',
		'Access-Control-Allow-Origin': request.headers['origin'] || '*',
	}

	try {
		assert(url.pathname === '/send', 'you seem lost');
		if (request.method === 'OPTIONS') {
			response.writeHead(request.headers['Access-Control-Request-Method'] === 'POST' ? 204 : 400, {
				...cors,
				'Access-Control-Allow-Methods': 'POST',
			}).end();
		}
		assert(request.method === 'POST', 'we dont do that here');
		assert(
			(
				request.headers['content-type']?.startsWith('application/x-www-form-urlencoded')
				|| request.headers['content-type']?.startsWith('application/json')
			),
			'what the fuck am i looking at',
		);

		const body = await new Promise((resolve, reject) => {
			let chunks = [];
			request.on('data', chunk => chunks.push(chunk));
			request.on('end', () => {
				resolve(Buffer.concat(chunks).toString('utf-8'));
			});
			request.on('error', () => {
				request.removeAllListeners('data');
				request.removeAllListeners('end');
				reject(new Error('hello????'));
			});
		});

		let {title, content, color} =
			request.headers['content-type'].includes('application/json')
				? JSON.parse(body)
				: parseQueryString(body);

		assert(
			(
				(typeof content === 'string' && content.length > 0)
				&& (title == null || typeof title === 'string')
				&& (color == null || typeof color === 'string')
			),
			"jesse what the fuck are you talking about",
		);
		assert((title == null || title.length <= 256) && (content.length <= 4096), "quit yapping");

		if (color === '#000000') {
			color = undefined;
		} else if (color != null) {
			assert(color[0] === '#', 'what are you trying to do here');
			color = parseInt(color.slice(1), 16);
			assert(!isNaN(color) && color > 0 && color <= 0xFFFFFF, 'ok now youre just making shit up');
		}

		if (request.headers['accept'].startsWith('application/json')) {
			response.writeHead(204, {'Content-Type': 'application/json', ...cors}).end();
		} else {
			response.writeHead(200, {'Content-Type': 'text/html'});
			response.end(`<html><body><h1>submitted!</h1><script>document.write('<p><button onclick="window.history.back()">&laquo; go back</button></p>')</script></body></html>`);
		}

		const ip = (
			(process.env.TRUST_X_FORWARDED_FOR && request.headers['x-forwarded-for']?.split(',')[0].trim())
			|| (process.env.TRUST_X_REAL_IP && request.headers['x-real-ip'])
			|| request.socket.remoteAddress
			|| 'the void'
		);

		fetch(process.env.WEBHOOK_URL, {
			method: 'POST',
			headers: {
				'Content-Type': 'application/json',
			},
			body: JSON.stringify({
				embeds: [{
					title,
					description: content,
					color,
					footer: {text: `${ip} • ${url}`},
					timestamp: new Date().toISOString(),
				}],
			}),
		});
	} catch (error) {
		if (request.headers['accept']?.startsWith('application/json')) {
			response.writeHead(400, {'Content-Type': 'application/json', ...cors});
			response.end(JSON.stringify({error: error.message || 'you done fucked up'}));
		} else {
			response.writeHead(400, {'Content-Type': 'text/html'});
			response.end(`<html><body><h1>you done fucked up</h1><pre>${error.message}</pre></body></html>`);
		}
	}
}).listen(port);