import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import React from "react";
import { FormGroup } from "../../../components/molecules/FormGroup";
import { Button } from "../../../components/atoms/Button";
import { Alert } from "../../../components/molecules/Alert";
import { validateForm } from "../../../utils/validation";
import { cn } from "../../../utils/cn";
export const Form = ({ fields, onSubmit, submitLabel = "Submit", cancelLabel = "Cancel", onCancel, loading = false, error, success, className, validation, }) => {
    const [errors, setErrors] = React.useState({});
    const [touched, setTouched] = React.useState({});
    const handleSubmit = async (e) => {
        e.preventDefault();
        const formData = {};
        fields.forEach((field) => {
            formData[field.name] = field.value;
        });
        // Run validation if provided
        if (validation) {
            let validationErrors = {};
            if (typeof validation === "function") {
                // Custom validation function
                validationErrors = validation(formData);
            }
            else {
                // Validation schema
                const result = validateForm(formData, validation);
                if (!result.isValid) {
                    validationErrors = result.errors;
                }
            }
            if (Object.keys(validationErrors).length > 0) {
                setErrors(validationErrors);
                // Mark all fields as touched
                const touchedFields = {};
                fields.forEach((field) => {
                    touchedFields[field.name] = true;
                });
                setTouched(touchedFields);
                return;
            }
        }
        setErrors({});
        await onSubmit(formData);
    };
    const handleFieldChange = (name, value) => {
        const field = fields.find((f) => f.name === name);
        if (field) {
            field.onChange(value);
            setTouched({ ...touched, [name]: true });
            // Clear error when user starts typing
            if (errors[name]) {
                setErrors({ ...errors, [name]: "" });
            }
        }
    };
    return (_jsxs("form", { onSubmit: handleSubmit, className: cn("w-full", className), children: [error && _jsx(Alert, { variant: "error", message: error, className: "mb-4" }), success && (_jsx(Alert, { variant: "success", message: success, className: "mb-4" })), _jsx(FormGroup, { spacing: "md", children: fields.map((field) => {
                    const fieldError = errors[field.name] || field.error;
                    const isTouched = touched[field.name];
                    // This is a simplified version - in practice, you'd use the actual form field components
                    return (_jsxs("div", { children: [_jsxs("label", { htmlFor: field.name, className: "block text-sm font-medium text-neutral-700 dark:text-neutral-300 mb-2", children: [field.label, field.required && (_jsx("span", { className: "text-error-500 ml-1", children: "*" }))] }), field.type === "textarea" ? (_jsx("textarea", { id: field.name, name: field.name, value: field.value || "", onChange: (e) => handleFieldChange(field.name, e.target.value), required: field.required, placeholder: field.placeholder, "aria-invalid": !!fieldError, "aria-describedby": fieldError && isTouched ? `${field.name}-error` : undefined, className: cn("w-full px-4 py-2 border-2 rounded-lg", "bg-white dark:bg-neutral-700", "text-neutral-900 dark:text-white", "focus:ring-2 focus:ring-primary-500 focus:border-transparent", fieldError && "border-error-500") })) : field.type === "select" ? (_jsx("select", { id: field.name, name: field.name, value: field.value || "", onChange: (e) => handleFieldChange(field.name, e.target.value), required: field.required, "aria-invalid": !!fieldError, "aria-describedby": fieldError && isTouched ? `${field.name}-error` : undefined, className: cn("w-full px-4 py-2 border-2 rounded-lg", "bg-white dark:bg-neutral-700", "text-neutral-900 dark:text-white", "focus:ring-2 focus:ring-primary-500 focus:border-transparent", fieldError && "border-error-500"), children: field.options?.map((option) => (_jsx("option", { value: option.value, children: option.label }, option.value))) })) : (_jsx("input", { type: field.type || "text", id: field.name, name: field.name, value: field.value || "", onChange: (e) => handleFieldChange(field.name, e.target.value), required: field.required, placeholder: field.placeholder, "aria-invalid": !!fieldError, "aria-describedby": fieldError && isTouched ? `${field.name}-error` : undefined, className: cn("w-full px-4 py-2 border-2 rounded-lg", "bg-white dark:bg-neutral-700", "text-neutral-900 dark:text-white", "focus:ring-2 focus:ring-primary-500 focus:border-transparent", fieldError && "border-error-500") })), fieldError && isTouched && (_jsx("p", { id: `${field.name}-error`, className: "mt-1 text-sm text-error-600 dark:text-error-400", role: "alert", children: fieldError }))] }, field.name));
                }) }), _jsxs("div", { className: "flex gap-2 mt-6", children: [_jsx(Button, { type: "submit", disabled: loading, children: loading ? "Loading..." : submitLabel }), onCancel && (_jsx(Button, { type: "button", variant: "outline", onClick: onCancel, children: cancelLabel }))] })] }));
};
export default Form;
