import { useFormContext } from "react-hook-form";
import React, { useRef, useState, KeyboardEvent } from "react";
import {
	CheckIcon,
	PencilIcon,
	XMarkIcon,
	PlusCircleIcon,
} from "@heroicons/react/24/outline";
import FormError from "./FormError";
import { Button } from "../element/Button";

export interface FormTagsProps
	extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "type"> {
	name: string;
	label?: string;
	viewMode?: boolean;
	maxTags?: number;
}

export function FormTags({
	name,
	label,
	className,
	viewMode = false,
	maxTags = 10,
	...restProps
}: FormTagsProps) {
	const [isFocused, setIsFocused] = useState(false);
	const [isEditing, setIsEditing] = useState(!viewMode);
	const [inputValue, setInputValue] = useState("");
	const inputWrapper = useRef<HTMLDivElement>(null);

	const {
		register,
		formState: { errors },
		watch,
		setValue,
		trigger,
	} = useFormContext();

	const tags = watch(name) || [];
	const error = errors[name]?.message as string;
	const isValid = tags.length > 0 && !error;

	const handleAddTag = () => {
		if (inputValue.trim() && tags.length < maxTags) {
			const newTags = [...tags, inputValue.trim()];
			setValue(name, newTags);
			setInputValue("");
			trigger(name);
		}
	};

	const handleKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
		if (e.key === "Enter") {
			e.preventDefault();
			handleAddTag();
		}
	};

	const handleRemoveTag = (indexToRemove: number) => {
		const newTags = tags.filter((_, index) => index !== indexToRemove);
		setValue(name, newTags);
		trigger(name);
	};

	const inputClasses = `
    w-full rounded-lg border bg-white px-4 py-2 outline-none
    transition-all duration-200 ease-out placeholder:text-tertiary-300
    ${error
			? "border-red-500 focus:border-red-500 focus:ring-2 focus:ring-red-200"
			: "border-gray-200 hover:border-gray-300 focus:border-blue-500 focus:ring-2 focus:ring-blue-100"
		}
    ${isFocused ? "ring-2 ring-opacity-50" : ""}
    ${className || ""}
  `;

	const viewModeClasses = `
    w-full text-gray-700 hover:text-primary-600 min-h-[48px] 
    flex items-center gap-2 relative cursor-pointer group
    transition-all duration-200 ease-out select-none
  `;

	const renderTags = () => (
		<div className="flex flex-wrap gap-2 mb-2">
			{tags.map((tag: string, index: number) => (
				<span
					key={index}
					className="
            inline-flex items-center gap-1 px-3 py-1 
            bg-blue-50 text-blue-700 rounded-full
            text-sm font-medium
          ">
					{tag}
					{!viewMode && (
						<XMarkIcon
							className="w-4 h-4 cursor-pointer hover:text-blue-900"
							onClick={() => handleRemoveTag(index)}
						/>
					)}
				</span>
			))}
		</div>
	);

	const renderViewMode = () => (
		<div className={viewModeClasses} onClick={() => setIsEditing(true)}>
			{tags.length > 0 ? (
				renderTags()
			) : (
				<span className="text-tertiary-300">点击编辑标签</span>
			)}
			<Button
				onClick={(e) => {
					e.stopPropagation();
					setIsEditing(true);
				}}
				size="xs"
				variant="ghost"
				leftIcon={<PencilIcon />}
				className="absolute -right-10 opacity-0 group-hover:opacity-100"
			/>
		</div>
	);

	const renderEditMode = () => (
		<div className="space-y-2">
			{renderTags()}
			<div className="relative">
				<input
					{...register(name)}
					value={inputValue}
					onChange={(e) => setInputValue(e.target.value)}
					onKeyDown={handleKeyDown}
					onFocus={() => setIsFocused(true)}
					onBlur={() => {
						setIsFocused(false);
						if (viewMode) setIsEditing(false);
					}}
					className={inputClasses}
					placeholder="输入标签后按回车添加"
					aria-label={label}
					{...restProps}
				/>
				<div
					className="
            absolute right-3 top-1/2 -translate-y-1/2
            flex items-center space-x-2
          ">
					{inputValue && (
						<button
							type="button"
							className="
                p-1.5 rounded-full text-tertiary-300 
                hover:text-gray-600 hover:bg-gray-100
                transition-all duration-200 ease-out
              "
							onClick={() => setInputValue("")}
							aria-label="清除输入"
							tabIndex={-1}>
							<XMarkIcon className="w-4 h-4" />
						</button>
					)}
					{isValid && (
						<CheckIcon className="text-green-500 w-4 h-4 animate-fade-in duration-200" />
					)}
					{error && <FormError error={error} />}
				</div>
			</div>
			<div className="text-sm text-tertiary-300">
				{tags.length}/{maxTags} 个标签
			</div>
		</div>
	);

	return (
		<div ref={inputWrapper} className="flex flex-col gap-2">
			{label && (
				<label className="text-sm font-medium text-gray-700 px-0.5">
					{label}
				</label>
			)}
			{viewMode && !isEditing ? renderViewMode() : renderEditMode()}
		</div>
	);
}
