const { Op } = require("sequelize");
const ApiError = require("../errorClass");
const database = require("../../../database");
const apiTypes = require("../typeChecker");

const router = require('express').Router();

async function checkSyntaxArgs(req, res) {
	const checker = new apiTypes.TypeChecker(false);
	
	await checker.checkAdditional(req.query.id, apiTypes.AuthorType, 'id');
	await checker.checkAdditional(req.query.offset, apiTypes.IntType, 'offset');
	await checker.checkAdditional(req.query.count, apiTypes.IntType, 'count');
	await checker.checkAdditional(req.query.min_date, apiTypes.IntType, 'min_date');
	await checker.checkAdditional(req.query.max_date, apiTypes.IntType, 'max_date');
	await checker.checkAdditional(req.query.q, apiTypes.StrType, 'q');
	
	const result = await checker.calculate();
	if (!result.success) {
		throw new ApiError("UNSYNTAX_PARAMS_OR_MISSED_REQUIRED_PARAMS", result);
	}
}

router.get('/get-authors', async (req, res, next) => {
	try {
		await checkSyntaxArgs(req, res);
		
		const offset = req.query.offset === undefined ? 0 : +req.query.offset;
		const countFromNull =
			req.query.count === undefined ? undefined : offset + +req.query.count;
		
		// Выборка по времени
		const requiredTimeSearch = req.query.min_date || req.query.max_date;
		const minDate = req.query.min_date === undefined ? 0 : +req.query.min_date;
		const maxDate = req.query.max_date === undefined ? 9999999999 : +req.query.max_date;
		
		let result = (
			await database.authors.findAll(
				req.query.id === undefined
					? {
						order: [
							['id', 'ASC'],
							['name', 'ASC'],
						],
						attributes: ['id', 'name', 'time'],
						...(requiredTimeSearch ? ({
							// Запрос на выборку по времени
							where : {
								time : {
									[Op.gte] : minDate,
									[Op.lte] : maxDate
								}
							}
						}) : {}),
						raw : true
					}
					: {
						order: [
							['id', 'ASC'],
							['name', 'ASC'],
						],
						attributes: ['id', 'name', 'time'],
						where : {
							id: +req.query.id,
							...(requiredTimeSearch ? ({
								// Запрос на выборку по времени
								time : {
									[Op.gte] : minDate,
									[Op.lte] : maxDate
								}
							}) : {})
						},
						raw : true
					},
			)
		).map((i) => ({
			id: i.id,
			name: i.name,
			date: i.time,
		}));

		if (req.query?.q !== undefined) {
			result = result.filter((i) => {
				const search = req.query.q.toLowerCase();
				return i.name.toLowerCase().includes(search);
			});
		}

		result = result.slice(offset, countFromNull);
		res.result({
			count: result.length,
			items: result,
		});
	}
	catch (err) {
		return next(err);
	}
});

router.use('/get-authors', async (req, res, next) => {
	try {
		return next(new ApiError("METHOD_MUST_BE_GET", { method : 'get-authors' }));
	}
	catch (err) {
		return next(err);
	}
});

module.exports = router;