<template>
	<form class="dynamic-form">
		<div class="form-container">
			<div class="form-row">
				<div
					v-for="field in fields"
					:key="field.name"
					:class="getFieldColumnClasses(field)"
					class="form-field"
				>
					<!-- Text Input -->
					<div v-if="field.type === 'text'" class="field-wrapper">
						<label v-if="field.label" :for="field.name" class="field-label">
							{{ field.label }}
							<span v-if="field.required" class="required">*</span>
						</label>
						<InputText
							:id="field.name"
							v-model="fieldValues[field.name]"
							:type="field.format || 'text'"
							:placeholder="field.placeholder"
							:disabled="field.disabled || isFormDisabled"
							:readonly="field.readonly"
							:invalid="!!getFieldError(field.name)"
							fluid
							:maxlength="field.maxLength"
							:inputmode="field.inputMode"
							:pattern="field.pattern"
							@keydown="handleKeyDown(field, $event)"
							@input="handleTextInput(field, $event)"
							@blur="
								handleFieldBlur(
									field,
									$event.target ? $event.target.value : fieldValues[field.name],
								)
							"
						/>
						<small v-if="field.helpText" class="field-help">{{
							field.helpText
						}}</small>
						<Message
							v-if="getFieldError(field.name)"
							severity="error"
							size="small"
							variant="simple"
						>
							{{ getFieldError(field.name) }}
						</Message>
					</div>

					<!-- Number Input -->
					<div v-else-if="field.type === 'number'" class="field-wrapper">
						<label v-if="field.label" :for="field.name" class="field-label">
							{{ field.label }}
							<span v-if="field.required" class="required">*</span>
						</label>
						<InputNumber
							:id="field.name"
							v-model="fieldValues[field.name]"
							:placeholder="field.placeholder"
							:disabled="field.disabled || isFormDisabled"
							:readonly="field.readonly"
							:min="field.min"
							:max="field.max"
							:step="field.step"
							:invalid="!!getFieldError(field.name)"
							fluid
							@input="handleFieldChange(field, $event.value)"
							@blur="handleFieldBlur(field, fieldValues[field.name])"
						/>
						<small v-if="field.helpText" class="field-help">{{
							field.helpText
						}}</small>
						<Message
							v-if="getFieldError(field.name)"
							severity="error"
							size="small"
							variant="simple"
						>
							{{ getFieldError(field.name) }}
						</Message>
					</div>

					<!-- Textarea -->
					<div v-else-if="field.type === 'textarea'" class="field-wrapper">
						<label v-if="field.label" :for="field.name" class="field-label">
							{{ field.label }}
							<span v-if="field.required" class="required">*</span>
						</label>
						<Textarea
							:id="field.name"
							v-model="fieldValues[field.name]"
							:placeholder="field.placeholder"
							:disabled="field.disabled || isFormDisabled"
							:readonly="field.readonly"
							:rows="field.rows || 3"
							:invalid="!!getFieldError(field.name)"
							fluid
							:autoResize="field.autoResize !== false"
							@input="
								handleFieldChange(
									field,
									$event.target ? $event.target.value : $event,
								)
							"
							@blur="
								handleFieldBlur(
									field,
									$event.target ? $event.target.value : fieldValues[field.name],
								)
							"
						/>
						<small v-if="field.helpText" class="field-help">{{
							field.helpText
						}}</small>
						<Message
							v-if="getFieldError(field.name)"
							severity="error"
							size="small"
							variant="simple"
						>
							{{ getFieldError(field.name) }}
						</Message>
					</div>

					<!-- Select Dropdown -->
					<div v-else-if="field.type === 'select'" class="field-wrapper">
						<label v-if="field.label" :for="field.name" class="field-label">
							{{ field.label }}
							<span v-if="field.required" class="required">*</span>
						</label>
						<Select
							:id="field.name"
							v-model="fieldValues[field.name]"
							:options="field.options"
							optionLabel="label"
							optionValue="value"
							:disabled="field.disabled || isFormDisabled"
							:placeholder="field.placeholder"
							:invalid="!!getFieldError(field.name)"
							fluid
							appendTo="body"
							@update:model-value="handleFieldChange(field, $event)"
							@blur="handleFieldBlur(field, fieldValues[field.name])"
						/>
						<small v-if="field.helpText" class="field-help">{{
							field.helpText
						}}</small>
						<Message
							v-if="getFieldError(field.name)"
							severity="error"
							size="small"
							variant="simple"
						>
							{{ getFieldError(field.name) }}
						</Message>
					</div>

					<!-- AutoComplete Input (NEW!) -->
					<div v-else-if="field.type === 'autocomplete'" class="field-wrapper">
						<label v-if="field.label" :for="field.name" class="field-label">
							{{ field.label }}
							<span v-if="field.required" class="required">*</span>
						</label>
						<AutoComplete
							:id="field.name"
							v-model="fieldValues[field.name]"
							:suggestions="field.filteredOptions || field.options || []"
							:disabled="field.disabled || isFormDisabled"
							:placeholder="field.placeholder"
							:invalid="!!getFieldError(field.name)"
							fluid
							:dropdown="field.dropdown"
							:forceSelection="field.forceSelection"
							appendTo="body"
							@complete="handleAutocompleteSearch(field, $event)"
							@update:model-value="handleFieldChange(field, $event)"
							@blur="handleFieldBlur(field, fieldValues[field.name])"
						/>
						<small v-if="field.helpText" class="field-help">{{
							field.helpText
						}}</small>
						<Message
							v-if="getFieldError(field.name)"
							severity="error"
							size="small"
							variant="simple"
						>
							{{ getFieldError(field.name) }}
						</Message>
					</div>

					<!-- Checkbox -->
					<div v-else-if="field.type === 'checkbox'" class="field-wrapper">
						<div class="checkbox-container">
							<Checkbox
								:id="field.name"
								v-model="fieldValues[field.name]"
								:binary="true"
								:disabled="field.disabled || isFormDisabled"
								:invalid="!!getFieldError(field.name)"
								@update:model-value="handleFieldChange(field, $event)"
							/>
							<label v-if="field.label" :for="field.name" class="checkbox-label">
								{{ field.label }}
								<span v-if="field.required" class="required">*</span>
							</label>
						</div>
						<small v-if="field.helpText" class="field-help">{{
							field.helpText
						}}</small>
						<Message
							v-if="getFieldError(field.name)"
							severity="error"
							size="small"
							variant="simple"
						>
							{{ getFieldError(field.name) }}
						</Message>
					</div>

					<!-- Radio Group -->
					<div v-else-if="field.type === 'radio'" class="field-wrapper">
						<label v-if="field.label" class="field-label">
							{{ field.label }}
							<span v-if="field.required" class="required">*</span>
						</label>
						<div class="radio-group">
							<div
								v-for="option in field.options"
								:key="option.value"
								class="radio-option"
							>
								<RadioButton
									:id="`${field.name}_${option.value}`"
									v-model="fieldValues[field.name]"
									:name="field.name"
									:value="option.value"
									:disabled="field.disabled || isFormDisabled"
									:invalid="!!getFieldError(field.name)"
									@update:model-value="handleFieldChange(field, $event)"
								/>
								<label :for="`${field.name}_${option.value}`" class="radio-label">
									{{ option.label }}
								</label>
							</div>
						</div>
						<small v-if="field.helpText" class="field-help">{{
							field.helpText
						}}</small>
						<Message
							v-if="getFieldError(field.name)"
							severity="error"
							size="small"
							variant="simple"
						>
							{{ getFieldError(field.name) }}
						</Message>
					</div>

					<!-- Date Input -->
					<div v-else-if="field.type === 'date'" class="field-wrapper">
						<label v-if="field.label" :for="field.name" class="field-label">
							{{ field.label }}
							<span v-if="field.required" class="required">*</span>
						</label>
						<DatePicker
							:id="field.name"
							v-model="fieldValues[field.name]"
							:placeholder="field.placeholder || getDatePlaceholder(field)"
							:disabled="field.disabled || isFormDisabled"
							:readonly="field.readonly"
							:minDate="parseDateValue(field.minDate)"
							:maxDate="parseDateValue(field.maxDate)"
							:invalid="!!getFieldError(field.name)"
							fluid
							showIcon
							iconDisplay="input"
							:dateFormat="getDateFormat(field)"
							:showTime="field.showTime || false"
							:timeOnly="field.timeOnly || false"
							:hourFormat="field.hourFormat || '24'"
							:stepHour="field.stepHour || 1"
							:stepMinute="field.stepMinute || 1"
							:showSeconds="field.showSeconds || false"
							:stepSecond="field.stepSecond || 1"
							:showButtonBar="field.showButtonBar !== false"
							:todayButtonLabel="field.todayButtonLabel || 'Today'"
							:clearButtonLabel="field.clearButtonLabel || 'Clear'"
							:showWeek="field.showWeek || false"
							:manualInput="field.manualInput !== false"
							:yearNavigator="field.yearNavigator || false"
							:monthNavigator="field.monthNavigator || false"
							:yearRange="field.yearRange || '1900:2100'"
							:inline="field.inline || false"
							:view="field.view || 'date'"
							:touchUI="field.touchUI || false"
							@update:model-value="handleDateChange(field, $event)"
							@blur="handleFieldBlur(field, fieldValues[field.name])"
						/>
						<small v-if="field.helpText" class="field-help">{{
							field.helpText
						}}</small>
						<Message
							v-if="getFieldError(field.name)"
							severity="error"
							size="small"
							variant="simple"
						>
							{{ getFieldError(field.name) }}
						</Message>
					</div>

					<!-- DateTime Input (Legacy - use date with showTime: true) -->
					<div v-else-if="field.type === 'datetime'" class="field-wrapper">
						<label v-if="field.label" :for="field.name" class="field-label">
							{{ field.label }}
							<span v-if="field.required" class="required">*</span>
						</label>
						<DatePicker
							:id="field.name"
							v-model="fieldValues[field.name]"
							:placeholder="
								field.placeholder ||
								getDatePlaceholder({ ...field, showTime: true })
							"
							:disabled="field.disabled || isFormDisabled"
							:readonly="field.readonly"
							:minDate="parseDateValue(field.minDate)"
							:maxDate="parseDateValue(field.maxDate)"
							:invalid="!!getFieldError(field.name)"
							fluid
							showIcon
							iconDisplay="input"
							showTime
							:hourFormat="field.hourFormat || '24'"
							:dateFormat="getDateFormat({ ...field, showTime: true })"
							:stepHour="field.stepHour || 1"
							:stepMinute="field.stepMinute || 1"
							:showSeconds="field.showSeconds || false"
							:stepSecond="field.stepSecond || 1"
							:showButtonBar="field.showButtonBar !== false"
							:todayButtonLabel="field.todayButtonLabel || 'Today'"
							:clearButtonLabel="field.clearButtonLabel || 'Clear'"
							:manualInput="field.manualInput !== false"
							:yearNavigator="field.yearNavigator || false"
							:monthNavigator="field.monthNavigator || false"
							:yearRange="field.yearRange || '1900:2100'"
							:inline="field.inline || false"
							:touchUI="field.touchUI || false"
							@update:model-value="handleDateChange(field, $event)"
							@blur="handleFieldBlur(field, fieldValues[field.name])"
						/>
						<small v-if="field.helpText" class="field-help">{{
							field.helpText
						}}</small>
						<Message
							v-if="getFieldError(field.name)"
							severity="error"
							size="small"
							variant="simple"
						>
							{{ getFieldError(field.name) }}
						</Message>
					</div>

					<!-- File Input -->
					<div v-else-if="field.type === 'file'" class="field-wrapper">
						<label v-if="field.label" :for="field.name" class="field-label">
							{{ field.label }}
							<span v-if="field.required" class="required">*</span>
						</label>
						<FileUpload
							:id="field.name"
							v-model="fieldValues[field.name]"
							mode="basic"
							:disabled="field.disabled || isFormDisabled"
							:accept="field.accept"
							:multiple="field.multiple"
							:invalidFileTypeMessage="`Invalid file type. Accepted types: ${field.accept || 'any'}`"
							:maxFileSize="field.maxFileSize"
							:invalidFileSizeMessage="`File size exceeds the limit of ${field.maxFileSize} bytes`"
							:chooseLabel="field.chooseLabel || 'Choose File'"
							:showUploadButton="false"
							:showCancelButton="false"
							auto
							@upload="handleFieldChange(field, $event.files)"
							@select="handleFieldChange(field, $event.files)"
						/>
						<small v-if="field.helpText" class="field-help">{{
							field.helpText
						}}</small>
						<Message
							v-if="getFieldError(field.name)"
							severity="error"
							size="small"
							variant="simple"
						>
							{{ getFieldError(field.name) }}
						</Message>
					</div>
				</div>
			</div>

			<!-- Submit/Action Buttons -->
			<div v-if="showSubmitButton || showCancelButton" class="form-buttons">
				<Button
					v-if="showSubmitButton"
					type="button"
					:label="submitButtonText"
					:loading="isLoading"
					:disabled="isFormDisabled"
					severity="primary"
					@click="handleSubmit"
				/>
				<Button
					v-if="showCancelButton"
					type="button"
					:label="cancelButtonText"
					:disabled="isLoading"
					severity="secondary"
					variant="outlined"
					@click="handleCancel"
				/>
			</div>
		</div>
	</form>
</template>

<script setup>
import { ref, reactive, computed, watch, defineEmits, defineProps } from "vue";
// PrimeVue Components
import InputText from "primevue/inputtext";
import InputNumber from "primevue/inputnumber";
import Textarea from "primevue/textarea";
import Select from "primevue/select";
import AutoComplete from "primevue/autocomplete";
import Checkbox from "primevue/checkbox";
import RadioButton from "primevue/radiobutton";
import DatePicker from "primevue/datepicker";
import FileUpload from "primevue/fileupload";
import Button from "primevue/button";
import Message from "primevue/message";
import { useLoadingStore } from "../../stores/loading";

const loadingStore = useLoadingStore();

const props = defineProps({
	fields: {
		type: Array,
		required: true,
	},
	formData: {
		type: Object,
		required: false,
		default: null,
	},
	onChange: {
		type: Function,
		required: false,
		default: null,
	},
	onSubmit: {
		type: Function,
		required: false,
		default: null,
	},
	showSubmitButton: {
		type: Boolean,
		default: true,
	},
	showCancelButton: {
		type: Boolean,
		default: false,
	},
	submitButtonText: {
		type: String,
		default: "Submit",
	},
	cancelButtonText: {
		type: String,
		default: "Cancel",
	},
	validateOnChange: {
		type: Boolean,
		default: true,
	},
	validateOnBlur: {
		type: Boolean,
		default: true,
	},
	validateOnSubmit: {
		type: Boolean,
		default: true,
	},
	loading: {
		type: Boolean,
		default: false,
	},
	loadingMessage: {
		type: String,
		default: "Processing...",
	},
	disableOnLoading: {
		type: Boolean,
		default: true,
	},
	// Auto-connect to global loading store
	useGlobalLoading: {
		type: Boolean,
		default: true,
	},
	formName: {
		type: String,
		default: "form",
	},
});

const emit = defineEmits(["update:formData", "submit", "cancel", "change", "blur"]);

// Internal form state (used when no external formData is provided)
const internalFormData = reactive({});
const formErrors = reactive({});
const isSubmitting = ref(false);

// Computed loading and disabled states
const isLoading = computed(() => {
	if (props.useGlobalLoading) {
		return (
			props.loading ||
			loadingStore.getComponentLoading("form") ||
			loadingStore.getComponentLoading(props.formName) ||
			isSubmitting.value
		);
	}
	return props.loading || isSubmitting.value;
});

const isFormDisabled = computed(() => {
	return props.disableOnLoading && isLoading.value;
});

// Computed property for v-model binding
const fieldValues = computed({
	get() {
		return props.formData || internalFormData;
	},
	set(newValues) {
		if (props.formData) {
			Object.assign(props.formData, newValues);
			emit("update:formData", props.formData);
		} else {
			Object.assign(internalFormData, newValues);
		}
	},
});

// Initialize form data
const initializeFormData = () => {
	props.fields.forEach((field) => {
		if (props.formData) {
			// If external formData is provided, ensure all fields exist
			if (!(field.name in props.formData)) {
				props.formData[field.name] = getDefaultValue(field);
			}
		} else {
			// Use internal form data
			internalFormData[field.name] = getDefaultValue(field);
		}
	});
};

// Date utility functions
const getDateDefaultValue = (field) => {
	if (field.defaultValue !== undefined) {
		// Handle string date values
		if (typeof field.defaultValue === "string") {
			if (field.defaultValue === "today" || field.defaultValue === "now") {
				return new Date();
			}
			// Try to parse the string as a date
			const parsed = new Date(field.defaultValue);
			return !isNaN(parsed.getTime()) ? parsed : null;
		}
		// Handle Date objects or null/undefined
		return field.defaultValue;
	}

	// Set default based on field configuration
	if (field.defaultToToday || field.defaultToNow) {
		const now = new Date();
		if (field.type === "date" && !field.showTime) {
			// For date-only fields, set to start of day
			return new Date(now.getFullYear(), now.getMonth(), now.getDate());
		}
		return now;
	}

	// No default value
	return null;
};

const parseDateValue = (value) => {
	if (!value) return null;
	if (value instanceof Date) return value;
	if (typeof value === "string") {
		const parsed = new Date(value);
		return !isNaN(parsed.getTime()) ? parsed : null;
	}
	return null;
};

const getDateFormat = (field) => {
	// Return custom format if provided
	if (field.dateFormat) {
		return field.dateFormat;
	}

	// Handle predefined format strings
	if (field.format) {
		switch (field.format.toLowerCase()) {
			case "yyyy-mm-dd":
				return "yy-mm-dd";
			case "mm/dd/yyyy":
				return "mm/dd/yy";
			case "dd/mm/yyyy":
				return "dd/mm/yy";
			case "dd-mm-yyyy":
				return "dd-mm-yy";
			case "mm-dd-yyyy":
				return "mm-dd-yy";
			default:
				break;
		}
	}

	// Default formats based on field configuration
	if (field.showTime || field.type === "datetime") {
		return "dd/mm/yy"; // PrimeVue will append time format automatically
	}

	return "dd/mm/yy"; // Default date format
};

const getDatePlaceholder = (field) => {
	if (field.placeholder) return field.placeholder;

	const format = field.format || (field.showTime ? "dd/mm/yyyy hh:mm" : "dd/mm/yyyy");

	if (field.timeOnly) {
		return "Select time";
	} else if (field.showTime || field.type === "datetime") {
		return `Enter date and time (${format})`;
	} else {
		return `Enter date (${format})`;
	}
};

const handleDateChange = (field, value) => {
	// Convert Date object to appropriate format if needed
	let processedValue = value;

	// Apply custom formatting if specified
	if (field.onDateChange && typeof field.onDateChange === "function") {
		processedValue = field.onDateChange(value);
	}

	// Call the standard field change handler
	handleFieldChange(field, processedValue);
};

// Get default value for a field based on its type
const getDefaultValue = (field) => {
	switch (field.type) {
		case "checkbox":
			return field.defaultValue !== undefined ? field.defaultValue : false;
		case "number":
			return field.defaultValue !== undefined ? field.defaultValue : "";
		case "select":
		case "radio":
			return field.defaultValue !== undefined ? field.defaultValue : "";
		case "file":
			return null;
		case "date":
		case "datetime":
			return getDateDefaultValue(field);
		default:
			return field.defaultValue !== undefined ? field.defaultValue : "";
	}
};

// Get the current value for a field
const getFieldValue = (fieldName) => {
	return fieldValues.value[fieldName];
};

// Get error for a field
const getFieldError = (fieldName) => {
	return formErrors[fieldName];
};

// Validate a single field
const validateField = (field, value) => {
	const errors = [];

	// Required validation (only check if field is required and value is empty)
	if (field.required && (value === "" || value === null || value === undefined)) {
		errors.push(`${field.label} is required`);
		return errors[0]; // Return early if required field is empty
	}

	// Skip other validations if value is empty and field is not required
	if (!value && !field.required) {
		return null;
	}

	// Email validation (more comprehensive)
	if (field.format === "email" && value) {
		const emailRegex =
			/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
		if (!emailRegex.test(value)) {
			errors.push("Please enter a valid email address");
		}
	}

	// Phone validation (for tel format)
	if (field.format === "tel" && value) {
		// Allow various phone formats
		const phoneRegex =
			/^[\+]?[1-9][\d]{0,15}$|^\(?[0-9]{3}\)?[-.\s]?[0-9]{3}[-.\s]?[0-9]{4}$|^[0-9]{10}$/;
		if (!phoneRegex.test(value.replace(/[\s\-\(\)\.]/g, ""))) {
			// Use custom validation if provided, otherwise use default
			if (!field.validate) {
				errors.push("Please enter a valid phone number");
			}
		}
	}

	// URL validation
	if (field.format === "url" && value) {
		try {
			new URL(value);
		} catch {
			errors.push("Please enter a valid URL");
		}
	}

	// Min/Max length validation for text
	if ((field.type === "text" || field.type === "textarea") && value) {
		if (field.minLength && value.length < field.minLength) {
			errors.push(`${field.label} must be at least ${field.minLength} characters`);
		}
		if (field.maxLength && value.length > field.maxLength) {
			errors.push(`${field.label} must not exceed ${field.maxLength} characters`);
		}
	}

	// Min/Max for numbers
	if (field.type === "number" && value !== "" && value !== null && value !== undefined) {
		const numValue = parseFloat(value);
		if (!isNaN(numValue)) {
			if (field.min !== undefined && numValue < field.min) {
				errors.push(`Value must be at least ${field.min}`);
			}
			if (field.max !== undefined && numValue > field.max) {
				errors.push(`Value must not exceed ${field.max}`);
			}
		} else {
			errors.push("Please enter a valid number");
		}
	}

	// Date validation
	if ((field.type === "date" || field.type === "datetime") && value) {
		const dateValue = value instanceof Date ? value : parseDateValue(value);

		if (!dateValue || isNaN(dateValue.getTime())) {
			errors.push("Please enter a valid date");
		} else {
			// Min/Max date validation
			if (field.minDate) {
				const minDate = parseDateValue(field.minDate);
				if (minDate && dateValue < minDate) {
					errors.push(`Date must be on or after ${minDate.toLocaleDateString()}`);
				}
			}
			if (field.maxDate) {
				const maxDate = parseDateValue(field.maxDate);
				if (maxDate && dateValue > maxDate) {
					errors.push(`Date must be on or before ${maxDate.toLocaleDateString()}`);
				}
			}
		}
	}

	// Custom validation (always runs last)
	if (field.validate && typeof field.validate === "function") {
		const customError = field.validate(value);
		if (customError) {
			errors.push(customError);
		}
	}

	return errors.length > 0 ? errors[0] : null;
};

// Handle keydown events for input restrictions
const handleKeyDown = (field, event) => {
	// Check if field has numeric-only restriction
	if (field.inputMode === "numeric" || field.pattern === "[0-9]*") {
		const key = event.key;

		// Allow control keys (backspace, delete, tab, escape, enter, arrows, etc.)
		const allowedKeys = [
			"Backspace",
			"Delete",
			"Tab",
			"Escape",
			"Enter",
			"ArrowLeft",
			"ArrowRight",
			"ArrowUp",
			"ArrowDown",
			"Home",
			"End",
			"PageUp",
			"PageDown",
		];

		// Allow Ctrl+A, Ctrl+C, Ctrl+V, Ctrl+X, Ctrl+Z
		if (event.ctrlKey || event.metaKey) {
			return;
		}

		// Allow allowed control keys
		if (allowedKeys.includes(key)) {
			return;
		}

		// Only allow numeric keys (0-9)
		if (!/^[0-9]$/.test(key)) {
			event.preventDefault();
			return;
		}

		// Check max length if specified
		if (field.maxLength && event.target.value.length >= field.maxLength) {
			event.preventDefault();
			return;
		}
	}
};

// Handle text input with custom formatting
const handleTextInput = (field, event) => {
	let value = event.target ? event.target.value : event;

	// Apply custom input formatting if provided
	if (field.onInput && typeof field.onInput === "function") {
		value = field.onInput(value);

		// Update the input value immediately to reflect formatting
		if (event.target) {
			event.target.value = value;
		}
	}

	// Call the standard field change handler
	handleFieldChange(field, value);
};

// Handle field value changes
const handleFieldChange = (field, value) => {
	// Update form data
	if (props.formData) {
		props.formData[field.name] = value;
		emit("update:formData", props.formData);
	} else {
		internalFormData[field.name] = value;
	}

	// Clear previous error for this field
	delete formErrors[field.name];

	// Validate field if enabled
	if (props.validateOnChange) {
		const error = validateField(field, value);
		if (error) {
			formErrors[field.name] = error;
		}
	}

	// Call custom onChange if provided on the field
	if (field.onChangeOverride && typeof field.onChangeOverride === "function") {
		field.onChangeOverride(value, field.name, getCurrentFormData());
	}
	// Call global onChange if provided
	else if (props.onChange && typeof props.onChange === "function") {
		props.onChange(field.name, value, getCurrentFormData());
	}

	// Emit change event
	emit("change", {
		fieldName: field.name,
		value: value,
		formData: getCurrentFormData(),
	});
};

// Handle field blur events
const handleFieldBlur = (field, value) => {
	// Validate field on blur if enabled
	if (props.validateOnBlur) {
		const error = validateField(field, value);
		if (error) {
			formErrors[field.name] = error;
		} else {
			// Clear error if validation passes
			delete formErrors[field.name];
		}
	}

	// Emit blur event
	emit("blur", {
		fieldName: field.name,
		value: value,
		formData: getCurrentFormData(),
	});
};

// Get current form data (either external or internal)
const getCurrentFormData = () => {
	return props.formData || internalFormData;
};

// Handle autocomplete search
const handleAutocompleteSearch = (field, event) => {
	if (field.onSearch && typeof field.onSearch === "function") {
		// Custom search function provided
		field.onSearch(event.query, (results) => {
			field.filteredOptions = results;
		});
	} else if (field.options) {
		// Filter existing options
		const query = event.query.toLowerCase();
		field.filteredOptions = field.options.filter((option) => {
			const label =
				typeof option === "string" ? option : option[field.optionLabel || "label"];
			return label && label.toLowerCase().includes(query);
		});
	} else {
		field.filteredOptions = [];
	}
};

// Get field column classes for responsive layout
const getFieldColumnClasses = (field) => {
	const classes = [];

	// Base column size (mobile-first)
	const cols = field.cols || 12;
	classes.push(`col-${cols}`);

	// Small breakpoint (sm)
	if (field.sm && field.sm !== cols) {
		classes.push(`sm-${field.sm}`);
	}

	// Medium breakpoint (md)
	if (field.md && field.md !== cols) {
		classes.push(`md-${field.md}`);
	}

	// Large breakpoint (lg)
	if (field.lg && field.lg !== cols) {
		classes.push(`lg-${field.lg}`);
	}

	return classes.join(" ");
};

// Validate entire form
const validateForm = () => {
	const errors = {};
	let isValid = true;

	props.fields.forEach((field) => {
		const value = getFieldValue(field.name);
		const error = validateField(field, value);
		if (error) {
			errors[field.name] = error;
			isValid = false;
		}
	});

	Object.assign(formErrors, errors);
	return isValid;
};

// Handle form submission
const handleSubmit = async () => {
	// Prevent double submission
	if (isSubmitting.value) {
		console.warn("Form: submission already in progress, ignoring duplicate submission");
		return;
	}

	// Always validate on submit if enabled
	if (props.validateOnSubmit && !validateForm()) {
		console.warn("Form: validation failed on submit");
		return;
	}

	isSubmitting.value = true;

	try {
		const formData = getCurrentFormData();
		console.log("Form: emitting submit event with data:", formData);

		// Only emit the submit event - let parent handle the actual submission
		// This prevents the dual submission pathway issue
		emit("submit", formData);

		// Call onSubmit prop if provided (for backward compatibility)
		if (props.onSubmit && typeof props.onSubmit === "function") {
			await props.onSubmit(formData);
		}
	} catch (error) {
		console.error("Form: submission error:", error);
		// Reset isSubmitting on error so user can retry
		isSubmitting.value = false;
	}
	// Note: Don't reset isSubmitting.value here in finally - let parent control this
	// The parent should call the exposed stopLoading() method when done
};

// Handle cancel action
const handleCancel = () => {
	emit("cancel");
};

// Initialize form data when component mounts
initializeFormData();

// Watch for changes in fields to reinitialize
watch(
	() => props.fields,
	() => {
		initializeFormData();
	},
	{ deep: true },
);

// Clear all form errors
const clearAllErrors = () => {
	Object.keys(formErrors).forEach((key) => delete formErrors[key]);
};

// Expose methods for parent component
defineExpose({
	validateForm,
	getCurrentFormData,
	resetForm: () => {
		initializeFormData();
		clearAllErrors();
	},
	setFieldError: (fieldName, error) => {
		formErrors[fieldName] = error;
	},
	clearFieldError: (fieldName) => {
		delete formErrors[fieldName];
	},
	clearAllErrors,
	// Manual validation trigger
	validateField: (fieldName) => {
		const field = props.fields.find((f) => f.name === fieldName);
		if (field) {
			const value = getFieldValue(fieldName);
			const error = validateField(field, value);
			if (error) {
				formErrors[fieldName] = error;
			} else {
				delete formErrors[fieldName];
			}
			return !error;
		}
		return true;
	},
	// Loading control methods
	startLoading: (message) =>
		loadingStore.setComponentLoading(props.formName, true, message || props.loadingMessage),
	stopLoading: () => loadingStore.setComponentLoading(props.formName, false),
	isLoading: () => isLoading.value,
});
</script>

<style scoped>
.dynamic-form {
	max-width: 1200px;
	margin: 0 auto;
	padding: 1rem;
}

.form-container {
	width: 100%;
}

.form-row {
	display: grid;
	grid-template-columns: repeat(12, 1fr);
	gap: 1rem;
	margin-bottom: 1rem;
}

.form-field {
	display: flex;
	flex-direction: column;
}

/* Base column classes (mobile-first) */
.col-1 {
	grid-column: span 1;
}
.col-2 {
	grid-column: span 2;
}
.col-3 {
	grid-column: span 3;
}
.col-4 {
	grid-column: span 4;
}
.col-5 {
	grid-column: span 5;
}
.col-6 {
	grid-column: span 6;
}
.col-7 {
	grid-column: span 7;
}
.col-8 {
	grid-column: span 8;
}
.col-9 {
	grid-column: span 9;
}
.col-10 {
	grid-column: span 10;
}
.col-11 {
	grid-column: span 11;
}
.col-12 {
	grid-column: span 12;
}

/* Small breakpoint (576px and up) */
@media (min-width: 576px) {
	.sm-1 {
		grid-column: span 1;
	}
	.sm-2 {
		grid-column: span 2;
	}
	.sm-3 {
		grid-column: span 3;
	}
	.sm-4 {
		grid-column: span 4;
	}
	.sm-5 {
		grid-column: span 5;
	}
	.sm-6 {
		grid-column: span 6;
	}
	.sm-7 {
		grid-column: span 7;
	}
	.sm-8 {
		grid-column: span 8;
	}
	.sm-9 {
		grid-column: span 9;
	}
	.sm-10 {
		grid-column: span 10;
	}
	.sm-11 {
		grid-column: span 11;
	}
	.sm-12 {
		grid-column: span 12;
	}
}

/* Medium breakpoint (768px and up) */
@media (min-width: 768px) {
	.md-1 {
		grid-column: span 1;
	}
	.md-2 {
		grid-column: span 2;
	}
	.md-3 {
		grid-column: span 3;
	}
	.md-4 {
		grid-column: span 4;
	}
	.md-5 {
		grid-column: span 5;
	}
	.md-6 {
		grid-column: span 6;
	}
	.md-7 {
		grid-column: span 7;
	}
	.md-8 {
		grid-column: span 8;
	}
	.md-9 {
		grid-column: span 9;
	}
	.md-10 {
		grid-column: span 10;
	}
	.md-11 {
		grid-column: span 11;
	}
	.md-12 {
		grid-column: span 12;
	}
}

/* Large breakpoint (992px and up) */
@media (min-width: 992px) {
	.lg-1 {
		grid-column: span 1;
	}
	.lg-2 {
		grid-column: span 2;
	}
	.lg-3 {
		grid-column: span 3;
	}
	.lg-4 {
		grid-column: span 4;
	}
	.lg-5 {
		grid-column: span 5;
	}
	.lg-6 {
		grid-column: span 6;
	}
	.lg-7 {
		grid-column: span 7;
	}
	.lg-8 {
		grid-column: span 8;
	}
	.lg-9 {
		grid-column: span 9;
	}
	.lg-10 {
		grid-column: span 10;
	}
	.lg-11 {
		grid-column: span 11;
	}
	.lg-12 {
		grid-column: span 12;
	}
}

/* Mobile responsive - stack all fields on very small screens */
@media (max-width: 575px) {
	.form-field {
		grid-column: span 12 !important;
	}
}

.field-wrapper {
	display: flex;
	flex-direction: column;
	gap: 0.5rem;
	margin-bottom: 1rem;
}

.field-label {
	font-weight: 600;
	font-size: 0.875rem;
	color: var(--text-color, #374151);
	margin-bottom: 0.25rem;
}

.field-help {
	font-size: 0.75rem;
	color: var(--text-color-secondary, #6b7280);
	margin-top: 0.25rem;
}

.required {
	color: var(--red-500, #ef4444);
	margin-left: 0.125rem;
}

/* Checkbox specific styles */
.checkbox-container {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.checkbox-label {
	font-weight: 500;
	font-size: 0.875rem;
	color: var(--text-color, #374151);
	cursor: pointer;
}

/* Radio group styles */
.radio-group {
	display: flex;
	flex-direction: column;
	gap: 0.75rem;
}

.radio-option {
	display: flex;
	align-items: center;
	gap: 0.5rem;
}

.radio-label {
	font-weight: 500;
	font-size: 0.875rem;
	color: var(--text-color, #374151);
	cursor: pointer;
}

/* Form buttons */
.form-buttons {
	display: flex;
	gap: 0.75rem;
	margin-top: 2rem;
	justify-content: flex-start;
}

/* Tablet responsive - let the responsive classes handle the layout */
@media (max-width: 767px) {
	/* Fields without md specified should span full width on tablets */
	.form-field:not([class*="md-"]) {
		grid-column: span 12;
	}
}

/* Large mobile responsive */
@media (max-width: 640px) {
	.form-buttons {
		flex-direction: column;
	}

	.form-buttons :deep(.p-button) {
		width: 100%;
	}
}
</style>
