/**
 * Copyright © Volker Schukai and all contributing authors, {{copyRightYear}}. All rights reserved.
 * Node module: @schukai/monster
 *
 * This source code is licensed under the GNU Affero General Public License version 3 (AGPLv3).
 * The full text of the license can be found at: https://www.gnu.org/licenses/agpl-3.0.en.html
 *
 * For those who do not wish to adhere to the AGPLv3, a commercial license is available.
 * Acquiring a commercial license allows you to use this software without complying with the AGPLv3 terms.
 * For more information about purchasing a commercial license, please contact Volker Schukai.
 *
 * SPDX-License-Identifier: AGPL-3.0
 */

import { generateUniqueConfigKey } from "../../host/util.mjs";

/**
 * @private
 * @return {string}
 */
export function getFilterConfigKey() {
	return generateUniqueConfigKey("datatable", this?.id, "filter");
}

/**
 * @private
 * @return {string}
 */
export function getStoredFilterConfigKey() {
	return generateUniqueConfigKey("datatable", this?.id, "stored-filter");
}

/**
 * @private
 * @param {String} str
 * @param {String} field
 * @return {String}
 * @throws {Error} if no field is defined
 */
export function parseDateInput(str, field) {
	if (!str) {
		return "";
	}

	if (!field) {
		throw new Error("no field is defined");
	}

	// Define the supported formats
	//let formats = ['DD-MM-YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'YYYY/MM/DD', 'DD.MM.YYYY'];
	const formats = ["YYYY-MM-DD"];
	// Determine the current date format of the localization
	const currentDateFormat = new Intl.DateTimeFormat()
		.format(new Date())
		.replace(/\d/g, "D");
	//  formats.push(currentDateFormat);

	// Run through the supported formats and try to parse the date
	for (let i = 0; i < formats.length; i++) {
		const format = formats[i];
		// Replace the corresponding placeholders in the format string with regular expressions

		try {
			const pattern = format
				.replace("DD", "\\d{2}")
				.replace("MM", "\\d{2}")
				.replace("YYYY", "\\d{4}");
			const rangePattern =
				"(?<from>" + pattern + ")\\s*-\\s*(?<to>" + pattern + ")";

			const rangeRegex = new RegExp("^" + rangePattern + "$", "g");

			if (rangeRegex.test(str)) {
				rangeRegex.lastIndex = 0;

				const rangeResult = rangeRegex.exec(str);

				if (!rangeResult) {
					continue;
				}

				const from = rangeResult?.groups?.from;
				const to = rangeResult?.groups?.to;

				if (from && to) {
					return (
						"(" +
						field +
						">='" +
						from +
						" 00:00:00' AND " +
						field +
						"<='" +
						to +
						" 23:59:59')"
					);
				}

				if (from) {
					return "(" + field + ">='" + from + " 00:00:00')";
				} else if (to) {
					return "(" + field + "<='" + to + "' 23:59:59')";
				}

				return "false";
			}

			const prefix = str.substring(0, 1) === "-";
			const suffix = str.substring(str.length - 1, str.length) === "-";

			if (prefix) {
				str = str.substring(1, str.length);
			} else if (suffix) {
				str = str.substring(0, str.length - 1);
			}

			const regex = new RegExp("^(?<date>" + pattern + ")$", "g");
			if (regex.test(str)) {
				regex.lastIndex = 0;
				const result = regex.exec(str);

				if (!result) {
					continue;
				}

				const date = result?.groups?.date;
				if (date) {
					if (prefix) {
						return "(" + field + "<='" + date + " 23:59:59')";
					} else if (suffix) {
						return "(" + field + ">='" + date + "' 00:00:00')";
					}
					return (
						"(" +
						field +
						">='" +
						date +
						" 00:00:00' AND " +
						field +
						"<='" +
						date +
						" 23:59:59')"
					);
				} else {
					return "false";
				}
			}
		} catch (e) {}
	}

	return "false";
}
