<script lang="ts">
	import Label from './Label.svelte';
	import StyledRawInput from './StyledRawInput.svelte';
	import { generateIdentifier } from './util';
	import type { ClassValue } from 'svelte/elements';
	import type { ComponentProps } from 'svelte';

	interface Props extends ComponentProps<typeof StyledRawInput> {
		id?: string;
		label?: string;
		value?: string;
		invalidMessage?: string | null;
		ref?: HTMLInputElement | null;
		asterisk?: boolean | null;
		class?: ClassValue | null | undefined;
	}

	let {
		id = generateIdentifier('text-input'),
		label,
		value = $bindable(''),
		invalidMessage = 'Field is required',
		ref = $bindable<HTMLInputElement | null>(null),
		asterisk = null,
		class: classValue,
		forceInvalid = false,
		...others
	}: Props = $props();

	let valid: boolean = $state(true);
	let displayAsterisk = $derived(
		asterisk === true || (asterisk !== false && others.validate && others.validate.required)
	);

	export const focus = () => {
		if (ref) ref.focus();
	};
</script>

<div class={['w-full', classValue]}>
	{#if label}
		<Label for={id}>
			{label}
			{#if displayAsterisk}
				<span class="text-red-500">*</span>
			{/if}
		</Label>
	{/if}

	<StyledRawInput
		{id}
		bind:value
		bind:ref
		onvalidate={(e) => {
			valid = e.detail.valid;
		}}
		{forceInvalid}
		{...others}
	/>

	{#if others.validate && invalidMessage !== null}
		<div class={['opacity-0 transition-opacity', (!valid || forceInvalid) && 'opacity-100']}>
			<Label for={id} error>
				{invalidMessage}
			</Label>
		</div>
	{/if}
</div>
