import { Request, Response } from 'express';
import validator from 'joi'; // DOCS: https://joi.dev/api
import { Prisma } from '@prisma/client';

// MARK: GET products
const schema_get = validator
	.object({
		sort: validator
			.string()
			.valid(...Object.keys(Prisma.ProductsScalarFieldEnum))
			.default('id'),

		order: validator.string().valid('asc', 'desc').default('asc'),
		take: validator.number().min(1).max(512),
		skip: validator.number().min(0),
		// This regex ensures that the search string does not contain consecutive asterisks (**) and is at least 3 characters long.
		search: validator.string().min(3).max(20).regex(new RegExp('^(?!.*\\*{2,}).*$')),
		id: validator.number().positive().precision(0),
		gtin: validator
			.string()
			.min(8)
			.max(14)
			.trim()
			.regex(new RegExp(/^[0-9]+$/))
	})
	// Allow only id, gtin, search or none of them
	// xor does not work because id, gtin and search fields are not mandatory
	.without('id', ['gtin', 'search'])
	.without('gtin', ['id', 'search'])
	.without('search', ['id', 'gtin']);

// MARK: CREATE products
const schema_post = validator.object({
	gtin: validator
		.string()
		.min(8)
		.max(14)
		.trim()
		.regex(new RegExp(/^[0-9]+$/))
		.required(),
	name: validator.string().min(1).max(32).required(),
	price: validator.number().positive().allow(0).precision(2).required(), // TODO: Check if 0 is allowed (https://github.com/hapijs/joi/issues/772)
	stock: validator.number().precision(0).required(),
	visible: validator.boolean().default(true)
});

// MARK: UPDATE products
const schema_patch = validator
	.object({
		id: validator.number().positive().precision(0).required(),
		gtin: validator
			.string()
			.min(8)
			.max(14)
			.trim()
			.regex(new RegExp(/^[0-9]+$/)),
		name: validator.string().min(1).max(32),
		price: validator.number().positive().allow(0).precision(2), // TODO: Check if 0 is allowed (https://github.com/hapijs/joi/issues/772)
		stock: validator.number().precision(0),
		visible: validator.boolean()
	})
	.or('gtin', 'name', 'price', 'stock', 'visible');

// MARK: DELETE products
const schema_del = validator.object({
	id: validator.number().positive().precision(0)
});

// Describe all schemas
const schema_get_desc = schema_get.describe();
const schema_post_desc = schema_post.describe();
const schema_patch_desc = schema_patch.describe();
const schema_del_desc = schema_del.describe();

// GET route
export default async function get(req: Request, res: Response) {
	res.status(200).json({
		GET: schema_get_desc,
		POST: schema_post_desc,
		PATCH: schema_patch_desc,
		DELETE: schema_del_desc
	});
}

export { schema_get, schema_post, schema_patch, schema_del };
