---
/**
 * Form embed component for Portable Text blocks.
 *
 * Server-renders the full form with all pages as <fieldset> elements.
 * Without JavaScript, all pages are visible as one long form.
 * The client-side script enhances with multi-page navigation, AJAX, etc.
 */

interface Props {
	node: { formId: string };
}

interface FormField {
	id: string;
	type: string;
	label: string;
	name: string;
	placeholder?: string;
	helpText?: string;
	required: boolean;
	validation?: {
		minLength?: number;
		maxLength?: number;
		min?: number;
		max?: number;
		pattern?: string;
		patternMessage?: string;
		accept?: string;
		maxFileSize?: number;
	};
	options?: Array<{ label: string; value: string }>;
	defaultValue?: string;
	width: "full" | "half";
	condition?: { field: string; op: string; value?: string };
}

interface FormPage {
	title?: string;
	fields: FormField[];
}

interface FormDefinition {
	name: string;
	slug: string;
	pages: FormPage[];
	settings: {
		spamProtection: string;
		submitLabel: string;
		nextLabel?: string;
		prevLabel?: string;
	};
	status: string;
	_turnstileSiteKey?: string | null;
}

const { node } = Astro.props;
const formId = node.formId;

// Fetch form definition server-side
const response = await fetch(
	new URL("/_emdash/api/plugins/emdash-forms/definition", Astro.url),
	{
		method: "POST",
		headers: { "Content-Type": "application/json" },
		body: JSON.stringify({ id: formId }),
	}
);

if (!response.ok) return;

const form = (await response.json()) as FormDefinition;
if (!form || form.status !== "active") return;

const submitUrl = `/_emdash/api/plugins/emdash-forms/submit`;
const isMultiPage = form.pages.length > 1;
const turnstileSiteKey = form._turnstileSiteKey;
const hasFiles = form.pages.some((p: FormPage) =>
	p.fields.some((f: FormField) => f.type === "file")
);

/** Generate an element ID for a field */
function fieldId(name: string): string {
	return `${formId}-${name}`;
}
---

<form
	class="ec-form"
	method="POST"
	action={submitUrl}
	enctype={hasFiles ? "multipart/form-data" : undefined}
	data-form-id={formId}
	data-ec-form
	data-pages={isMultiPage ? form.pages.length : undefined}
>
	{
		form.pages.map((page: FormPage, pageIndex: number) => (
			<fieldset
				class="ec-form-page"
				data-page={pageIndex}
				aria-label={page.title || `Page ${pageIndex + 1}`}
			>
				{isMultiPage && page.title && (
					<legend class="ec-form-page-title">{page.title}</legend>
				)}

				{page.fields.map((field: FormField) => (
					<div
						class:list={[
							"ec-form-field",
							`ec-form-field--${field.type}`,
							field.width === "half" && "ec-form-field--half",
						]}
						data-condition={
							field.condition ? JSON.stringify(field.condition) : undefined
						}
					>
						{field.type !== "hidden" && field.type !== "checkbox" && (
							<label class="ec-form-label" for={fieldId(field.name)}>
								{field.label}
								{field.required && (
									<span class="ec-form-required" aria-label="required">
										*
									</span>
								)}
							</label>
						)}
						{[
							"text",
							"email",
							"tel",
							"url",
							"number",
							"date",
							"hidden",
						].includes(field.type) && (
							<input
								type={field.type as astroHTML.JSX.HTMLInputTypeAttribute}
								class={field.type !== "hidden" ? "ec-form-input" : undefined}
								id={fieldId(field.name)}
								name={field.name}
								placeholder={field.placeholder}
								required={field.required}
								minlength={field.validation?.minLength}
								maxlength={field.validation?.maxLength}
								min={field.validation?.min}
								max={field.validation?.max}
								pattern={field.validation?.pattern}
								value={field.defaultValue}
							/>
						)}
						{field.type === "file" && (
							<input
								type="file"
								class="ec-form-input"
								id={fieldId(field.name)}
								name={field.name}
								required={field.required}
								accept={field.validation?.accept}
							/>
						)}
						{field.type === "textarea" && (
							<textarea
								class="ec-form-input"
								id={fieldId(field.name)}
								name={field.name}
								placeholder={field.placeholder}
								required={field.required}
								minlength={field.validation?.minLength}
								maxlength={field.validation?.maxLength}
							>
								{field.defaultValue || ""}
							</textarea>
						)}
						{field.type === "select" && (
							<select
								class="ec-form-input"
								id={fieldId(field.name)}
								name={field.name}
								required={field.required}
							>
								{(field.options || []).map((o) => (
									<option
										value={o.value}
										selected={o.value === field.defaultValue}
									>
										{o.label}
									</option>
								))}
							</select>
						)}
						{field.type === "radio" && (
							<fieldset class="ec-form-radio-group" role="radiogroup">
								{(field.options || []).map((o) => (
									<label class="ec-form-radio-label">
										<input
											type="radio"
											name={field.name}
											value={o.value}
											checked={o.value === field.defaultValue}
											required={field.required}
										/>{" "}
										{o.label}
									</label>
								))}
							</fieldset>
						)}
						{field.type === "checkbox" && (
							<label class="ec-form-checkbox-label">
								<input
									type="checkbox"
									class="ec-form-input"
									id={fieldId(field.name)}
									name={field.name}
									value={field.defaultValue || "1"}
									required={field.required}
								/>{" "}
								{field.label}
							</label>
						)}
						{field.type === "checkbox-group" && (
							<fieldset class="ec-form-checkbox-group">
								{(field.options || []).map((o) => (
									<label class="ec-form-checkbox-label">
										<input type="checkbox" name={field.name} value={o.value} />{" "}
										{o.label}
									</label>
								))}
							</fieldset>
						)}
						{field.helpText && (
							<span class="ec-form-help">{field.helpText}</span>
						)}
						<span
							class="ec-form-error"
							data-error-for={field.name}
							aria-live="polite"
						/>
					</div>
				))}
			</fieldset>
		))
	}

	{
		form.settings.spamProtection === "honeypot" && (
			<div
				class="ec-form-field"
				style="position:absolute;left:-9999px;"
				aria-hidden="true"
			>
				<label for={`${formId}-_hp`}>Leave blank</label>
				<input
					type="text"
					id={`${formId}-_hp`}
					name="_hp"
					tabindex="-1"
					autocomplete="off"
				/>
			</div>
		)
	}

	{
		form.settings.spamProtection === "turnstile" && turnstileSiteKey && (
			<div
				class="ec-form-turnstile"
				data-ec-turnstile
				data-sitekey={turnstileSiteKey}
			/>
		)
	}

	<input type="hidden" name="formId" value={formId} />

	<div class="ec-form-nav">
		<button type="button" class="ec-form-prev" data-ec-prev hidden>
			{form.settings.prevLabel || "Previous"}
		</button>
		<button type="button" class="ec-form-next" data-ec-next hidden>
			{form.settings.nextLabel || "Next"}
		</button>
		<button type="submit" class="ec-form-submit">
			{form.settings.submitLabel || "Submit"}
		</button>
	</div>

	{
		isMultiPage && (
			<div class="ec-form-progress" data-ec-progress aria-live="polite" />
		)
	}

	<div class="ec-form-status" data-form-status aria-live="polite"></div>
</form>

<script>
	import { initForms } from "@emdash-cms/plugin-forms/client";
	initForms();
</script>
