---
import type { HookType } from '@astro-reactive/common';

export interface Props {
	hook?: HookType;
	displayErrorMessages?: boolean;
}

const { hook = 'all', displayErrorMessages = false } = Astro.props;
---

<input hidden name="hook" id="hook" value={hook} />
<input
	hidden
	name="displayErrorMessages"
	id="displayErrorMessages"
	value={displayErrorMessages.toString()}
/>

<script>
	// TODO: selectors should by unique IDs generated by our library
	// TODO: implement type guards pls 😱
	// TODO: create deserializer util
	// TODO: handle hooks / when to attach event listeners
	// const form = document.querySelector('form');

	import type { ValidatorRules } from '@astro-reactive/common';
	import { clearErrors, validate } from './core';

	// const hook: HookType = (document.getElementById('hook') as HTMLInputElement).value as HookType;
	const inputs = [...document.querySelectorAll('body *[data-validation-on]')] as HTMLInputElement[];

	inputs?.forEach((input) => {
		input.addEventListener(input.dataset?.validationOn ?? 'blur', (e: Event) => {
			// NOTE: event target attribute names are converted to lowercase
			const element = e.target as HTMLInputElement;
			const attributeNames = element?.getAttributeNames() || [];
			const validators = attributeNames
				.filter((attribute) => attribute.includes('data-validator-'))
				.map((attribute) => {
					const limit = element.getAttribute(attribute);
					return {
						validator: `${attribute}:${limit}`,
						category: element.getAttribute(`${attribute}-category`),
					};
				})
				.filter((val) => val.category !== null); // Filter out validators without a category

			const value =
				element.type === 'checkbox' ? (element.checked ? 'checked' : '') : element.value;
			const errors = validate(value, validators as ValidatorRules);

			// set element hasErrors
			if (errors.length) {
				element.parentElement?.setAttribute(`data-validator-${errors[0]?.category}`, 'true');
				element.setAttribute(`data-validator-${errors[0]?.category}`, 'true');
				element.classList.add(`has-errors`);
				// TODO: display error messages
			} else {
				element.parentElement?.removeAttribute(`data-validator-${errors[0]?.category}`);
				element.removeAttribute(`data-validator-${errors[0]?.category}`);
				element.classList.remove(`has-${errors[0]?.category}`);
			}
		});

		input.addEventListener('input', clearErrors);
	});
</script>
