// components/FormDynamicInputs.tsx
import { useFieldArray, useFormContext } from "react-hook-form";
import { AnimatePresence, motion } from "framer-motion";
import React, { useState } from "react";
import { CheckIcon, XMarkIcon, PlusIcon } from "@heroicons/react/24/outline";
import FormError from "./FormError";
import { TrashIcon } from "@heroicons/react/24/solid";

export interface DynamicFormInputProps
	extends Omit<
		React.InputHTMLAttributes<HTMLInputElement | HTMLTextAreaElement>,
		"type"
	> {
	name: string;
	addTitle?: string;
	subTitle?: string;
	label: string;
	type?:
		| "text"
		| "textarea"
		| "password"
		| "email"
		| "number"
		| "tel"
		| "url"
		| "search"
		| "date"
		| "time"
		| "datetime-local";
	rows?: number;
}

export function FormDynamicInputs({
	name,
	addTitle,
	label,
	subTitle,
	type = "text",
	rows = 4,
	className,
	...restProps
}: DynamicFormInputProps) {
	const [focusedIndexes, setFocusedIndexes] = useState<number[]>([]);
	const {
		register,
		formState: { errors },
		watch,
		setValue,
		trigger,
		control,
	} = useFormContext();

	const { fields, append, remove } = useFieldArray({
		control,
		name,
	});
	// 添加 onChange 处理函数
	const handleInputChange = (index: number, value: string) => {
		setValue(`${name}.${index}`, value, {
			shouldValidate: true,
			shouldDirty: true,
			shouldTouch: true,
		});
	};
	const handleBlur = async (index: number) => {
		setFocusedIndexes(focusedIndexes.filter((i) => i !== index));
		await trigger(`${name}.${index}`);
	};

	const values = watch(name) || [];
	const fieldErrors = errors[name] as any;

	const inputClasses = `
    w-full rounded-md border bg-white p-2 pr-8 outline-none shadow-sm
    transition-all duration-300 ease-out placeholder:text-gray-400
    border-gray-300 focus:border-blue-500 focus:ring-blue-200
  `;

	const InputElement = type === "textarea" ? "textarea" : "input";
	return (
		<div className="space-y-4">
			<label className="block text-sm font-medium text-gray-700">
				{label}
			</label>
			{subTitle && (
				<label className="block text-sm font-normal text-gray-500">
					{subTitle}
				</label>
			)}

			<AnimatePresence mode="popLayout">
				{fields.map((field, index) => (
					<motion.div
						key={field.id}
						initial={{ opacity: 0, y: -20 }}
						animate={{ opacity: 1, y: 0 }}
						exit={{ opacity: 0, y: 20 }}
						transition={{ duration: 0.2 }}
						className="group relative">
						<div className="relative">
							<InputElement
								{...register(`${name}.${index}`, {
									onChange: (e) =>
										handleInputChange(
											index,
											e.target.value
										),
								})}
								type={type !== "textarea" ? type : undefined}
								rows={type === "textarea" ? rows : undefined}
								{...restProps}
								onFocus={() =>
									setFocusedIndexes([
										...focusedIndexes,
										index,
									])
								}
								onBlur={() => handleBlur(index)}
								className={inputClasses}
							/>

							{/* 修改这部分，将删除按钮放在 input 内部右侧 */}
							<div className="absolute right-2 top-1/2 -translate-y-1/2 flex items-center space-x-2">
								{values[index] && !fieldErrors?.[index] && (
									<CheckIcon className="text-green-500 w-4 h-4" />
								)}
								{fields.length > 1 && (
									<button
										type="button"
										onClick={() => remove(index)}
										className="p-1 text-red-500 hover:text-red-600 opacity-0 group-hover:opacity-100 transition-opacity duration-200">
										<TrashIcon className="w-4 h-4" />
									</button>
								)}
							</div>
						</div>
						{fieldErrors?.[index]?.message && (
							<FormError error={fieldErrors[index].message} />
						)}
					</motion.div>
				))}
			</AnimatePresence>

			<motion.button
				type="button"
				whileHover={{ scale: 1.02 }}
				whileTap={{ scale: 0.98 }}
				onClick={() => append("")}
				className="flex items-center gap-1 text-blue-500 hover:text-blue-600 
                 transition-colors px-4 py-2 rounded-lg hover:bg-blue-50">
				<PlusIcon className="w-5 h-5" />
				添加新{addTitle || label}
			</motion.button>
		</div>
	);
}
