'use client';

import * as React from 'react';
import { useState } from 'react';
import { Button } from '@nice/ui/components/button';
import { Badge } from '@nice/ui/components/badge';
import {
	DndContext,
	DragEndEvent,
	DragOverlay,
	DragStartEvent,
	PointerSensor,
	useSensor,
	useSensors,
	closestCenter,
	DragOverEvent,
} from '@dnd-kit/core';
import {
	SortableContext,
	verticalListSortingStrategy,
	useSortable,
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';

import {
	IconChevronRight,
	IconChevronDown,
	IconDots,
	IconEdit,
	IconTrash,
	IconPlus,
	IconGripVertical,
} from '@tabler/icons-react';
import {
	DropdownMenu,
	DropdownMenuContent,
	DropdownMenuItem,
	DropdownMenuSeparator,
	DropdownMenuTrigger,
} from '@nice/ui/components/dropdown-menu';
import { TaxonomySlug, type TermWithTaxonomy } from '@fenghuo/common';

// 通用树节点接口
export interface TreeNode {
	id: string;
	name: string;
	slug?: string | null;
	description?: string | null;
	parentId?: string | null;
	level?: number;
	order?: number; // 添加排序字段
	children?: TreeNode[];
	terms?: TermWithTaxonomy[]; // 添加 terms 字段支持
	[key: string]: any; // 允许额外的属性
}

// 图标配置
export interface TreeIconConfig {
	// 根节点图标
	rootIcon?: React.ComponentType<{ className?: string }>;
	// 父节点图标（有子节点）
	parentIcon?: React.ComponentType<{ className?: string }>;
	// 父节点展开时图标
	parentExpandedIcon?: React.ComponentType<{ className?: string }>;
	// 叶子节点图标
	leafIcon?: React.ComponentType<{ className?: string }>;
	// 根据节点动态决定图标的函数
	getIcon?: (node: TreeNode, hasChildren: boolean, isExpanded: boolean) => React.ComponentType<{ className?: string }>;
}

// 操作配置
export interface TreeActionConfig<T extends TreeNode> {
	// 编辑操作
	onEdit?: (node: T) => void;
	editLabel?: string;
	// 删除操作
	onDelete?: (node: T) => void;
	deleteLabel?: string;
	// 添加子节点操作
	onAddChild?: (parentId: string) => void;
	addChildLabel?: string;
	// 自定义操作
	customActions?: Array<{
		label: string;
		icon?: React.ComponentType<{ className?: string }>;
		onClick: (node: T) => void;
		className?: string;
	}>;
}

// 显示配置
export interface TreeDisplayConfig<T extends TreeNode> {
	// 是否显示描述
	showDescription?: boolean;
	// 是否显示 slug
	showSlug?: boolean;
	// 自定义渲染节点内容
	renderContent?: (node: T) => React.ReactNode;
	// 自定义渲染额外信息（如徽章）
	renderExtra?: (node: T) => React.ReactNode;
	// 节点选择样式配置
	selectedClassName?: string;
	hoverClassName?: string;
}

// 拖拽配置
export interface TreeDragConfig<T extends TreeNode> {
	// 是否启用拖拽
	enabled?: boolean;
	// 拖拽开始回调
	onDragStart?: (event: DragStartEvent) => void;
	// 拖拽结束回调 - 返回更新后的数据
	onDragEnd?: (oldData: T[], newData: T[]) => void;
	// 拖拽过程中回调
	onDragOver?: (event: DragOverEvent) => void;
	// 是否显示拖拽手柄
	showHandle?: boolean;
}

// 可拖拽的树节点组件属性
interface DraggableTreeNodeProps<T extends TreeNode> {
	node: T;
	level: number;
	expandedIds: Set<string>;
	selectedNode?: T | null;
	onToggleExpand: (id: string) => void;
	onSelect?: (node: T) => void;
	iconConfig: TreeIconConfig;
	actionConfig: TreeActionConfig<T>;
	displayConfig: TreeDisplayConfig<T>;
	dragConfig: TreeDragConfig<T>;
	indentSize?: number;
	isDragging?: boolean;
	siblings: T[];
}

// 可拖拽的树节点组件
function DraggableTreeNode<T extends TreeNode>({
	node,
	level,
	expandedIds,
	selectedNode,
	onToggleExpand,
	onSelect,
	iconConfig,
	actionConfig,
	displayConfig,
	dragConfig,
	indentSize = 20,
	isDragging = false,
	siblings,
}: DraggableTreeNodeProps<T>) {
	// 只有在启用拖拽时才使用 useSortable
	const sortableProps = dragConfig.enabled ? useSortable({ id: node.id }) : null;

	const {
		attributes = {},
		listeners = {},
		setNodeRef = () => { },
		transform = null,
		transition = '',
		isDragging: isSortableDragging = false,
	} = sortableProps || {};

	const style = dragConfig.enabled ? {
		transform: CSS.Transform.toString(transform),
		transition,
	} : {};

	const hasChildren = node.children && node.children.length > 0;
	const isExpanded = expandedIds.has(node.id);
	const isSelected = selectedNode?.id === node.id;

	// 获取图标
	const getNodeIcon = () => {
		if (iconConfig.getIcon) {
			return iconConfig.getIcon(node, !!hasChildren, isExpanded);
		}

		if (level === 0 && iconConfig.rootIcon) {
			return iconConfig.rootIcon;
		}

		if (hasChildren) {
			if (isExpanded && iconConfig.parentExpandedIcon) {
				return iconConfig.parentExpandedIcon;
			}
			return iconConfig.parentIcon;
		}

		return iconConfig.leafIcon;
	};

	const NodeIcon = getNodeIcon();

	// 默认选中样式
	const defaultSelectedClassName = 'bg-primary/10 border border-primary/20';
	const defaultHoverClassName = 'hover:bg-muted/50 border border-transparent';

	const selectedClassName = displayConfig.selectedClassName || defaultSelectedClassName;
	const hoverClassName = displayConfig.hoverClassName || defaultHoverClassName;

	return (
		<div className="select-none" style={style} ref={setNodeRef}>
			<div
				className={`flex items-center justify-between p-2 rounded-md group cursor-pointer transition-colors ${isSelected ? selectedClassName : hoverClassName
					} ${isSortableDragging ? 'opacity-50' : ''} ${isDragging ? 'z-50' : ''}`}
				onClick={() => onSelect?.(node)}
				style={{ paddingLeft: `${level * indentSize + 8}px` }}
			>
				<div className="flex items-center gap-2 flex-1 min-w-0">
					{/* 拖拽手柄 */}
					{dragConfig.enabled && dragConfig.showHandle && (
						<div
							className="w-4 h-4 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity cursor-grab active:cursor-grabbing"
							{...attributes}
							{...listeners}
						>
							<IconGripVertical className="h-3 w-3 text-muted-foreground" />
						</div>
					)}

					{/* 展开/折叠按钮 */}
					<div className="w-5 h-5 flex items-center justify-center">
						{hasChildren ? (
							<Button
								variant="ghost"
								size="sm"
								className="h-4 w-4 p-0 hover:bg-background"
								onClick={(e) => {
									e.stopPropagation();
									onToggleExpand(node.id);
								}}
							>
								{isExpanded ? (
									<IconChevronDown className="h-3 w-3" />
								) : (
									<IconChevronRight className="h-3 w-3" />
								)}
							</Button>
						) : (
							<div className="w-3 h-3" />
						)}
					</div>

					{/* 图标 */}
					{NodeIcon && (
						<div className="w-5 h-5 flex items-center justify-center flex-shrink-0">
							<NodeIcon className="h-4 w-4" />
						</div>
					)}

					{/* 节点内容 */}
					<div className="flex-1 min-w-0">
						{displayConfig.renderContent ? (
							displayConfig.renderContent(node)
						) : (
							<>
								<div className="flex items-center gap-2 flex-wrap">
									<span className="font-medium text-sm truncate">{node.name}</span>
									{/* 显示 organization_type 类型的 term 作为标签 */}
									{node.terms?.filter(term => term.taxonomy.slug === TaxonomySlug.ORGANIZATION_TYPE).map(term => (
										<Badge key={term.id} variant="secondary" className="text-xs shrink-0">
											{term.name}
										</Badge>
									))}
									{displayConfig.renderExtra && displayConfig.renderExtra(node)}
								</div>
								{displayConfig.showDescription && node.description && (
									<div className="text-xs text-muted-foreground mt-1 truncate">
										{node.description}
									</div>
								)}
								{/* 显示 profession 类型的 term 作为文本 */}
								{(() => {
									const professionTerms = node.terms?.filter(term => term.taxonomy.slug === TaxonomySlug.PROFESSION) || [];
									return professionTerms.length > 0 && (
										<div className="mt-1 flex flex-wrap gap-1">
											{professionTerms.map((term, index) => (
												<span key={term.id} className="text-xs text-muted-foreground">
													{index > 0 && '• '}{term.name}
												</span>
											))}
										</div>
									);
								})()}
								{displayConfig.showSlug && node.slug && (
									<div className="text-xs text-gray-400 dark:text-gray-500 mt-1">/{node.slug}</div>
								)}
							</>
						)}
					</div>
				</div>

				{/* 操作菜单 */}
				{(actionConfig.onEdit || actionConfig.onDelete || actionConfig.onAddChild || actionConfig.customActions) && (
					<div className="opacity-0 group-hover:opacity-100 transition-opacity">
						<DropdownMenu>
							<DropdownMenuTrigger asChild>
								<Button
									variant="ghost"
									size="sm"
									className="h-6 w-6 p-0"
									onClick={(e) => e.stopPropagation()}
								>
									<IconDots className="h-4 w-4" />
								</Button>
							</DropdownMenuTrigger>
							<DropdownMenuContent align="end">
								{actionConfig.onEdit && (
									<DropdownMenuItem
										onClick={(e) => {
											e.stopPropagation();
											actionConfig.onEdit!(node);
										}}
										className="cursor-pointer"
									>
										<IconEdit className="mr-2 h-4 w-4" />
										{actionConfig.editLabel || '编辑'}
									</DropdownMenuItem>
								)}
								{actionConfig.onAddChild && (
									<DropdownMenuItem
										onClick={(e) => {
											e.stopPropagation();
											actionConfig.onAddChild!(node.id);
										}}
										className="cursor-pointer"
									>
										<IconPlus className="mr-2 h-4 w-4" />
										{actionConfig.addChildLabel || '添加子项'}
									</DropdownMenuItem>
								)}
								{actionConfig.customActions?.map((action, index) => (
									<DropdownMenuItem
										key={index}
										onClick={(e) => {
											e.stopPropagation();
											action.onClick(node);
										}}
										className={`cursor-pointer ${action.className || ''}`}
									>
										{action.icon && <action.icon className="mr-2 h-4 w-4" />}
										{action.label}
									</DropdownMenuItem>
								))}
								{(actionConfig.onEdit || actionConfig.onAddChild || actionConfig.customActions) && actionConfig.onDelete && (
									<DropdownMenuSeparator />
								)}
								{actionConfig.onDelete && (
									<DropdownMenuItem
										onClick={(e) => {
											e.stopPropagation();
											actionConfig.onDelete!(node);
										}}
										className="text-destructive focus:text-destructive cursor-pointer"
									>
										<IconTrash className="mr-2 h-4 w-4" />
										{actionConfig.deleteLabel || '删除'}
									</DropdownMenuItem>
								)}
							</DropdownMenuContent>
						</DropdownMenu>
					</div>
				)}
			</div>

			{/* 子节点 */}
			{hasChildren && isExpanded && (
				<div className="ml-1">
					<DraggableTreeLevel
						nodes={node.children! as T[]}
						level={level + 1}
						expandedIds={expandedIds}
						selectedNode={selectedNode}
						onToggleExpand={onToggleExpand}
						onSelect={onSelect}
						iconConfig={iconConfig}
						actionConfig={actionConfig}
						displayConfig={displayConfig}
						dragConfig={dragConfig}
						indentSize={indentSize}
					/>
				</div>
			)}
		</div>
	);
}

// 可拖拽的树级别组件
function DraggableTreeLevel<T extends TreeNode>({
	nodes,
	level,
	expandedIds,
	selectedNode,
	onToggleExpand,
	onSelect,
	iconConfig,
	actionConfig,
	displayConfig,
	dragConfig,
	indentSize,
}: {
	nodes: T[];
	level: number;
	expandedIds: Set<string>;
	selectedNode?: T | null;
	onToggleExpand: (id: string) => void;
	onSelect?: (node: T) => void;
	iconConfig: TreeIconConfig;
	actionConfig: TreeActionConfig<T>;
	displayConfig: TreeDisplayConfig<T>;
	dragConfig: TreeDragConfig<T>;
	indentSize?: number;
}) {
	// 按order排序
	const sortedNodes = [...nodes].sort((a, b) => (a.order || 0) - (b.order || 0));

	if (!dragConfig.enabled) {
		// 如果不启用拖拽，直接使用拖拽组件但不包装在SortableContext中
		return (
			<div className="space-y-1">
				{sortedNodes.map((node) => (
					<DraggableTreeNode
						key={node.id}
						node={node}
						level={level}
						expandedIds={expandedIds}
						selectedNode={selectedNode}
						onToggleExpand={onToggleExpand}
						onSelect={onSelect}
						iconConfig={iconConfig}
						actionConfig={actionConfig}
						displayConfig={displayConfig}
						dragConfig={dragConfig}
						indentSize={indentSize}
						siblings={sortedNodes}
					/>
				))}
			</div>
		);
	}

	return (
		<SortableContext items={sortedNodes.map(node => node.id)} strategy={verticalListSortingStrategy}>
			<div className="space-y-1">
				{sortedNodes.map((node) => (
					<DraggableTreeNode
						key={node.id}
						node={node}
						level={level}
						expandedIds={expandedIds}
						selectedNode={selectedNode}
						onToggleExpand={onToggleExpand}
						onSelect={onSelect}
						iconConfig={iconConfig}
						actionConfig={actionConfig}
						displayConfig={displayConfig}
						dragConfig={dragConfig}
						indentSize={indentSize}
						siblings={sortedNodes}
					/>
				))}
			</div>
		</SortableContext>
	);
}



// 树选择器组件属性
export interface TreeSelectorProps<T extends TreeNode> {
	// 数据
	data: T[];
	// 选中的节点
	selectedNode?: T | null;
	// 选择回调
	onSelect?: (node: T) => void;
	// 图标配置
	iconConfig?: TreeIconConfig;
	// 操作配置
	actionConfig?: TreeActionConfig<T>;
	// 显示配置
	displayConfig?: TreeDisplayConfig<T>;
	// 拖拽配置
	dragConfig?: TreeDragConfig<T>;
	// 缩进大小
	indentSize?: number;
	// 容器样式
	className?: string;
	// 是否显示在容器中
	containerized?: boolean;
	// 最大高度
	maxHeight?: string;
}

// 工具函数：查找节点的同级节点ID
function findSiblingNodes<T extends TreeNode>(nodes: T[], targetId: string): string[] {
	const siblings: string[] = [];

	function searchInLevel(levelNodes: T[]): boolean {
		// 检查当前层级是否包含目标节点
		const hasTarget = levelNodes.some(node => node.id === targetId);

		if (hasTarget) {
			// 如果当前层级包含目标节点，返回所有同级节点的ID
			siblings.push(...levelNodes.map(node => node.id));
			return true;
		}

		// 递归搜索子节点
		for (const node of levelNodes) {
			if (node.children && searchInLevel(node.children as T[])) {
				return true;
			}
		}

		return false;
	}

	searchInLevel(nodes);
	return siblings;
}

// 支持 BigInt 的深拷贝函数
function deepClone<T>(obj: T): T {
	if (obj === null || typeof obj !== 'object') {
		return obj;
	}

	if (obj instanceof Date) {
		return new Date(obj.getTime()) as T;
	}

	if (obj instanceof Array) {
		return obj.map(item => deepClone(item)) as T;
	}

	if (typeof obj === 'object') {
		const cloned = {} as T;
		for (const key in obj) {
			if (obj.hasOwnProperty(key)) {
				cloned[key] = deepClone(obj[key]);
			}
		}
		return cloned;
	}

	return obj;
}

// 工具函数：更新节点的order值
function updateNodeOrder<T extends TreeNode>(nodes: T[], draggedId: string, targetId: string): T[] {
	const clonedNodes = deepClone(nodes);

	// 递归查找并更新节点
	function updateInLevel(levelNodes: T[]): T[] {
		// 找到拖拽的节点和目标节点
		const draggedIndex = levelNodes.findIndex(node => node.id === draggedId);
		const targetIndex = levelNodes.findIndex(node => node.id === targetId);

		if (draggedIndex !== -1 && targetIndex !== -1) {
			// 在同一层级内重新排列
			const draggedNodes = levelNodes.splice(draggedIndex, 1);
			const draggedNode = draggedNodes[0];
			if (draggedNode) {
				levelNodes.splice(targetIndex, 0, draggedNode);

				// 重新计算order值
				levelNodes.forEach((node, index) => {
					node.order = index;
				});
			}

			return levelNodes;
		}

		// 递归处理子节点
		return levelNodes.map(node => ({
			...node,
			children: node.children ? updateInLevel(node.children as T[]) : node.children
		}));
	}

	return updateInLevel(clonedNodes);
}

// 主要的树选择器组件
export function TreeSelector<T extends TreeNode>({
	data,
	selectedNode,
	onSelect,
	iconConfig = {},
	actionConfig = {},
	displayConfig = {},
	dragConfig = {},
	indentSize = 20,
	className = '',
	containerized = true,
	maxHeight = 'calc(100vh - 300px)',
}: TreeSelectorProps<T>) {
	const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set());
	const [activeId, setActiveId] = useState<string | null>(null);
	// 设置传感器
	const sensors = useSensors(
		useSensor(PointerSensor, {
			activationConstraint: {
				distance: 8,
			},
		})
	);

	const toggleExpand = (id: string) => {
		const newExpanded = new Set(expandedIds);
		if (newExpanded.has(id)) {
			newExpanded.delete(id);
		} else {
			newExpanded.add(id);
		}
		setExpandedIds(newExpanded);
	};

	const handleDragStart = (event: DragStartEvent) => {
		const { active } = event;
		setActiveId(active.id as string);

		// 找到同级节点并收起它们
		const siblingIds = findSiblingNodes(data, active.id as string);
		const newExpandedIds = new Set(expandedIds);

		// 移除同级节点（包括拖拽节点本身）
		siblingIds.forEach(id => {
			newExpandedIds.delete(id);
		});

		setExpandedIds(newExpandedIds);

		if (dragConfig.onDragStart) {
			dragConfig.onDragStart(event);
		}
	};

	const handleDragEnd = (event: DragEndEvent) => {
		const { active, over } = event;

		setActiveId(null);

		if (!over || active.id === over.id) {
			return;
		}

		// 更新数据
		const newData = updateNodeOrder(data, active.id as string, over.id as string);

		// 调用回调
		if (dragConfig.onDragEnd) {
			dragConfig.onDragEnd(data, newData);
		}
	};

	const handleDragOver = (event: DragOverEvent) => {
		if (dragConfig.onDragOver) {
			dragConfig.onDragOver(event);
		}
	};

	const content = (
		<div className="space-y-1">
			<DraggableTreeLevel
				nodes={data}
				level={0}
				expandedIds={expandedIds}
				selectedNode={selectedNode}
				onToggleExpand={toggleExpand}
				onSelect={onSelect}
				iconConfig={iconConfig}
				actionConfig={actionConfig}
				displayConfig={displayConfig}
				dragConfig={dragConfig}
				indentSize={indentSize}
			/>
		</div>
	);

	// 如果启用拖拽，使用DndContext包装
	const wrappedContent = dragConfig.enabled ? (
		<DndContext
			sensors={sensors}
			collisionDetection={closestCenter}
			onDragStart={handleDragStart}
			onDragEnd={handleDragEnd}
			onDragOver={handleDragOver}
		>
			{content}
			<DragOverlay>
				{activeId ? (
					<div className="opacity-0">
						{/* 空的覆盖层，让拖拽时只显示原节点的虚化效果 */}
					</div>
				) : null}
			</DragOverlay>
		</DndContext>
	) : content;

	if (containerized) {
		return (
			<div className={`p-4 ${className}`}>
				<div className={`overflow-y-auto`} style={{ maxHeight }}>
					{wrappedContent}
				</div>
			</div>
		);
	}

	return <div className={className}>{wrappedContent}</div>;
}

// 导出默认组件
export default TreeSelector;
