<script lang="ts">
import { onMount } from 'svelte';
import DateInput from '$lib/shared/primitives/DateInput.svelte';
import type { DatePrecision } from '$lib/shared/utils/documentDate';

/**
 * Compact date + precision field: the {@link DateInput} primitive paired with a
 * precision <select> offering a caller-chosen subset of precisions. Shared base of
 * PersonLifeDateField (birth/death) and RelationshipDateField (from/to).
 *
 * Distinct from {@link DatePrecisionField} — that one is the full document/timeline
 * field (all seven precisions, German free-text entry, RANGE end-date disclosure).
 * This one is the restricted, single-input variant for the person-family forms.
 *
 * All copy (legend, precision labels, hint, the select's accessible name) and the
 * offered precisions are injected by the caller so this stays domain-agnostic.
 */
let {
	name,
	legend,
	precisionLabel,
	hint,
	precisions,
	initialIso = '',
	initialPrecision = null,
	inputClass = '',
	selectClass = ''
}: {
	name: string;
	legend: string;
	precisionLabel: string;
	hint: string;
	precisions: { value: DatePrecision; label: string }[];
	initialIso?: string | null;
	initialPrecision?: string | null;
	inputClass?: string;
	selectClass?: string;
} = $props();

let iso = $state('');
let errorMessage = $state<string | null>(null);
let inputEl = $state<HTMLInputElement | undefined>();
let precision = $state<DatePrecision>('DAY');

// Seed once at mount so a later load() rerun does not stomp an in-progress edit.
onMount(() => {
	if (initialIso) {
		iso = initialIso;
	}
	const offered = precisions.some((p) => p.value === initialPrecision);
	if (offered) {
		precision = initialPrecision as DatePrecision;
	} else if (initialIso) {
		// A stored non-offered precision (SEASON/RANGE/APPROX) seeds as YEAR so an
		// untouched save does not silently claim DAY precision for the stored date.
		precision = 'YEAR';
	}
});

// A partial date leaves the hidden ISO empty — block native submission until the
// date is completed or fully emptied, so a save can never silently clear a date.
$effect(() => {
	inputEl?.setCustomValidity(errorMessage ?? '');
});

const controlCls =
	'block min-h-[44px] w-full rounded border border-line px-3 py-2 font-serif text-ink focus:outline-none focus-visible:ring-2 focus-visible:ring-focus-ring';
</script>

<fieldset>
	<legend class="mb-1 block text-xs font-bold tracking-widest text-ink-3 uppercase">
		{legend}
	</legend>
	<div class="flex flex-col gap-2 sm:flex-row">
		<div class="flex-1">
			<DateInput
				bind:value={iso}
				bind:errorMessage={errorMessage}
				bind:inputEl={inputEl}
				name={name}
				id={name}
				placeholder="TT.MM.JJJJ"
				ariaLabel={legend}
				ariaDescribedby={errorMessage ? `${name}-error` : undefined}
				class="{controlCls} {inputClass}"
			/>
			{#if errorMessage}
				<p id="{name}-error" class="mt-1 font-sans text-xs text-red-600">{errorMessage}</p>
			{/if}
		</div>
		<div class="flex-1">
			<select
				id="{name}Precision"
				name="{name}Precision"
				aria-label="{legend}: {precisionLabel}"
				bind:value={precision}
				class="{controlCls} {selectClass}"
			>
				{#each precisions as p (p.value)}
					<option value={p.value}>{p.label}</option>
				{/each}
			</select>
		</div>
	</div>
	<p class="mt-1 font-sans text-xs text-ink-3">{hint}</p>
</fieldset>
