import { useFormContext } from "react-hook-form";
import { PlusIcon, XMarkIcon } from "@heroicons/react/24/outline";
import { Reorder } from "framer-motion";
import React, { useEffect, useState } from "react";
import FormError from "./FormError";
import { UUIDGenerator } from "@nice/common";
interface ArrayFieldProps {
	name: string;
	label: string;
	placeholder?: string;
	addButtonText?: string;
	inputProps?: React.InputHTMLAttributes<HTMLInputElement>;
}
type ItemType = { id: string; value: string };
const inputStyles =
	"w-full rounded-md border border-gray-300 bg-white p-2 outline-none transition-all duration-300 ease-out focus:border-blue-500 focus:ring-2 focus:ring-blue-200 focus:ring-opacity-50 placeholder:text-gray-400 shadow-sm";
const buttonStyles =
	"rounded-md inline-flex items-center gap-1 px-4 py-2 text-sm font-medium transition-colors ";
export function FormArrayField({
	name,
	label,
	placeholder,
	addButtonText = "添加项目",
	inputProps = {},
}: ArrayFieldProps) {
	const {
		register,
		watch,
		setValue,
		formState: { errors },
		trigger,
	} = useFormContext();

	// 添加 watch 监听
	const watchedValues = watch(name);
	const [items, setItems] = useState<ItemType[]>(
		() =>
			(watchedValues as string[])?.map((value) => ({
				id: UUIDGenerator.generate(),
				value,
			})) || []
	);
	// 使用 useEffect 监听表单值变化
	useEffect(() => {
		if (watchedValues) {
			const newItems = watchedValues.map(
				(value: string, index: number) => {
					// 尽量保持现有的 id
					return {
						id: items[index]?.id || UUIDGenerator.generate(),
						value,
					};
				}
			);
			setItems(newItems);
		}
	}, [watchedValues]);
	const error = errors[name]?.message as string;
	const updateItems = (newItems: ItemType[]) => {
		setItems(newItems);
		setValue(
			name,
			newItems.map((item) => item.value),
			{ shouldDirty: true }
		);
	};
	return (
		<div className="space-y-2">
			<label className="block text-sm font-medium text-gray-700">
				{label}
			</label>
			<div className="space-y-3">
				<Reorder.Group
					axis="y"
					values={items}
					onReorder={updateItems}
					className="space-y-3">
					{items.map((item, index) => (
						<Reorder.Item
							key={item.id}
							value={item}
							initial={{ opacity: 0, y: -20 }}
							animate={{ opacity: 1, y: 0 }}
							exit={{ opacity: 0, y: -20 }}
							className="group">
							<div className="relative flex items-center">
								<div className="flex-1 relative">
									<input
										{...register(`${name}.${index}`)}
										{...inputProps}
										value={item.value}
										onChange={(e) => {
											const newItems = items.map((i) =>
												i.id === item.id
													? {
															...i,
															value: e.target
																.value,
														}
													: i
											);
											updateItems(newItems);
										}}
										onBlur={() => {
											trigger(name);
										}}
										placeholder={placeholder}
										className={inputStyles}
									/>
									{inputProps.maxLength && (
										<span className="absolute right-2 top-1/2 -translate-y-1/2 text-sm text-gray-400">
											{inputProps.maxLength -
												(item.value?.length || 0)}
										</span>
									)}
								</div>
								<button
									type="button"
									onClick={() =>
										updateItems(
											items.filter(
												(i) => i.id !== item.id
											)
										)
									}
									className="absolute -right-10 p-2 text-gray-400 hover:text-red-500 transition-colors rounded-md hover:bg-red-50 focus:ring-red-200 opacity-0 group-hover:opacity-100">
									<XMarkIcon className="w-5 h-5" />
								</button>
							</div>
						</Reorder.Item>
					))}
				</Reorder.Group>

				<button
					type="button"
					onClick={() =>
						updateItems([
							...items,
							{ id: UUIDGenerator.generate(), value: "" },
						])
					}
					className={`${buttonStyles} text-blue-600 bg-blue-50 hover:bg-blue-100 focus:ring-blue-500`}>
					<PlusIcon className="w-4 h-4" />
					{addButtonText}
				</button>
			</div>
			<FormError error={error}></FormError>
		</div>
	);
}
