import { useForm } from "@tanstack/react-form";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { toast } from "sonner";
import { type ReactNode } from "react";

interface FormBuilderProps<T extends Record<string, any>> {
  defaultValues: T;
  onSubmit: (values: T) => Promise<void> | void;
  submitLabel?: string;
  cancelLabel?: string;
  onCancel?: () => void;
  showCancel?: boolean;
  children: (form: any) => ReactNode;
}

export function FormBuilder<T extends Record<string, any>>({
  defaultValues,
  onSubmit,
  submitLabel = "Submit",
  cancelLabel = "Hủy",
  onCancel,
  showCancel = false,
  children,
}: FormBuilderProps<T>) {
  const form = useForm({
    defaultValues,
    onSubmit: async ({ value }) => {
      try {
        await onSubmit(value as T);
      } catch (error) {
        console.error("Submit error:", error);
        toast.error("Có lỗi xảy ra!");
      }
    },
  });

  return (
    <form
      className="space-y-4"
      onSubmit={(e) => {
        e.preventDefault();
        form.handleSubmit();
      }}
    >
      {children(form)}

      <div className="flex justify-end gap-2">
        {showCancel && onCancel && (
          <Button type="button" variant="outline" onClick={onCancel}>
            {cancelLabel}
          </Button>
        )}
        <Button type="submit">{submitLabel}</Button>
      </div>
    </form>
  );
}

interface FormFieldProps<T, K extends keyof T> {
  form: any;
  name: K;
  label: string;
  type?: string;
  placeholder?: string;
  required?: boolean;
}

export function FormField<T extends Record<string, any>, K extends keyof T>({
  form,
  name,
  label,
  type = "text",
  placeholder,
  required,
}: FormFieldProps<T, K>) {
  return (
    <form.Field name={name as string}>
      {(field: any) => (
        <div>
          <Label>
            {label}
            {required && <span className="text-red-500 ml-1">*</span>}
          </Label>
          <Input
            type={type}
            value={field.state.value}
            onChange={(e) => field.handleChange(e.target.value)}
            placeholder={placeholder}
          />
        </div>
      )}
    </form.Field>
  );
}

export function FormTextarea<T extends Record<string, any>, K extends keyof T>({
  form,
  name,
  label,
  placeholder,
  required,
}: Omit<FormFieldProps<T, K>, "type">) {
  return (
    <form.Field name={name as string}>
      {(field: any) => (
        <div>
          <Label>
            {label}
            {required && <span className="text-red-500 ml-1">*</span>}
          </Label>
          <textarea
            className="flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
            value={field.state.value}
            onChange={(e) => field.handleChange(e.target.value)}
            placeholder={placeholder}
          />
        </div>
      )}
    </form.Field>
  );
}

export function FormSelect<T extends Record<string, any>, K extends keyof T>({
  form,
  name,
  label,
  options,
  required,
}: {
  form: any;
  name: K;
  label: string;
  options: { value: string; label: string }[];
  required?: boolean;
}) {
  return (
    <form.Field name={name as string}>
      {(field: any) => (
        <div>
          <Label>
            {label}
            {required && <span className="text-red-500 ml-1">*</span>}
          </Label>
          <select
            className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2"
            value={field.state.value}
            onChange={(e) => field.handleChange(e.target.value)}
          >
            {options.map((opt) => (
              <option key={opt.value} value={opt.value}>
                {opt.label}
              </option>
            ))}
          </select>
        </div>
      )}
    </form.Field>
  );
}