import { InputChangeProps, GenerateFieldProps } from '../types/types';

import { regexOnlyNumbers } from './validations';

const handleKeyEvent = (
	event: KeyboardEvent,
	{ validationType, maxLength, customHandleChange }: InputChangeProps
) => {
	const target = event.target as HTMLInputElement;
	const formattedValue = regexOnlyNumbers(target.value);

	switch (validationType) {
		case 'holderName': {
			customHandleChange(target.value);
			break;
		}
		case 'expirationDate': {
			if (
				target.value.length === 2 &&
				(event.code === 'Backspace' || event.code === 'Delete')
			) {
				customHandleChange(target.value.substring(0, 1));
				target.value = target.value.substring(0, 1);
				break;
			}

			const expDate = target.value
				.replace(
					/[^\d/]/g,
					'' // Allow only digits and `/`
				)
				.replace(
					/\/\//g,
					'/' // Prevent entering more than 1 `/`
				)
				.replace(
					/^(\d{2})(\d)/,
					'$1/$2' // Auto-add `/` after 2 digits
				);

			customHandleChange(expDate.substring(0, maxLength));
			target.value = expDate.substring(0, maxLength);
			break;
		}
		case 'cvv': {
			target.value = formattedValue.substring(0, maxLength);
			customHandleChange(formattedValue.substring(0, maxLength));
			break;
		}
		case 'cardNumber': {
			const splitNumbers = (formattedValue || '').match(/.{1,4}/g);

			if (!splitNumbers) {
				customHandleChange(formattedValue.substring(0, maxLength));
				target.value = formattedValue.substring(0, maxLength);
				break;
			}

			customHandleChange(splitNumbers.join(' ').substring(0, maxLength));
			target.value = splitNumbers.join(' ').substring(0, maxLength);
			break;
		}
		default: {
			break;
		}
	}
};

export const generateField = ({
	type = 'text',
	wrapper,
	id,
	maxLength,
	validationType,
	eventType,
	customHandleChange,
	inputAddornment
}: GenerateFieldProps) => {
	if (id) {
		const existing = wrapper.querySelector(`#${id}`);
		if (existing) wrapper.removeChild(existing);

		const fieldInput = document.createElement('input');
		fieldInput.id = id;
		fieldInput.type = type;
		fieldInput.placeholder = wrapper.getAttribute('data-placeholder') || '';
		fieldInput.addEventListener(eventType || 'input', (event) =>
			handleKeyEvent(event as KeyboardEvent, {
				validationType,
				maxLength,
				customHandleChange: customHandleChange ? customHandleChange : () => {}
			})
		);

		if (maxLength) {
			fieldInput.max = String(maxLength);
		}

		wrapper.append(fieldInput);
	}

	const errorWrapper = document.createElement('span');
	errorWrapper.classList.add('form-field-error');

	wrapper.classList.add('form-field');
	wrapper.append(errorWrapper);

	if (inputAddornment) {
		const addornmentWrapper = document.createElement('div');

		addornmentWrapper.classList.add('form-field-addornment');
		addornmentWrapper.innerHTML = inputAddornment;
		wrapper.append(addornmentWrapper);
	}
};
