'use client';

import * as React from 'react';
import { useState } from 'react';
import { Button } from '@nice/ui/components/button';
import { Popover, PopoverContent, PopoverTrigger } from '@nice/ui/components/popover';
import {
	Command,
	CommandEmpty,
	CommandGroup,
	CommandInput,
	CommandItem,
	CommandList,
} from '@nice/ui/components/command';
import { IconChevronDown, IconChevronRight, IconCheck, IconBuilding, IconX } from '@tabler/icons-react';
import { cn } from '@nice/ui/lib/utils';
import { useTRPC } from '@fenghuo/client';
import { useQuery } from '@tanstack/react-query';
import type { OrganizationTreeNode } from '@fenghuo/common';
import { Organization } from '@fenghuo/db';
import { Badge } from '@nice/ui/components/badge';

// 树形选择器属性
interface OrganizationTreeSelectorProps {
	value?: string | string[]; // 支持单选和多选
	onValueChange?: (value: string | string[]) => void;
	placeholder?: string;
	className?: string;
	disabled?: boolean;
	allowClear?: boolean;
	multiple?: boolean; // 是否支持多选
	excludeIds?: string[]; // 排除的部门ID列表，用于编辑时排除自身及子部门
	modal?: boolean; // 是否为模态模式，用于在 Dialog 中解决滚轮问题
}

// 树形节点组件
interface TreeNodeProps {
	node: OrganizationTreeNode;
	level: number;
	selectedValue?: string | string[];
	multiple?: boolean;
	expandedIds: Set<string>;
	onSelect: (value: string, name: string) => void;
	onToggleExpand: (id: string) => void;
}

function TreeNode({ node, level, selectedValue, multiple, expandedIds, onSelect, onToggleExpand }: TreeNodeProps) {
	const hasChildren = node.children && node.children.length > 0;
	const isExpanded = expandedIds.has(node.id);

	// 判断是否选中 - 兼容单选和多选
	const isSelected = React.useMemo(() => {
		if (!selectedValue) return false;
		return Array.isArray(selectedValue) ? selectedValue.includes(node.id) : selectedValue === node.id;
	}, [selectedValue, node.id]);

	const handleSelect = () => {
		onSelect(node.id, node.name);
	};

	const handleToggleExpand = (e: React.MouseEvent) => {
		e.stopPropagation();
		if (hasChildren) {
			onToggleExpand(node.id);
		}
	};

	return (
		<>
			<CommandItem
				value={`${node.id}-${node.name}`}
				onSelect={handleSelect}
				className={cn(
					'flex items-center justify-between cursor-pointer',
					'hover:bg-accent hover:text-accent-foreground',
					isSelected && 'bg-accent text-accent-foreground',
				)}
				style={{ paddingLeft: `${level * 16 + 8}px` }}
			>
				<div className="flex items-center gap-2 flex-1">
					{/* 展开/折叠图标 */}
					<div className="w-4 h-4 flex items-center justify-center">
						{hasChildren ? (
							<button onClick={handleToggleExpand} className="hover:bg-muted/50 rounded-sm p-0.5">
								{isExpanded ? <IconChevronDown className="h-3 w-3" /> : <IconChevronRight className="h-3 w-3" />}
							</button>
						) : (
							<div className="w-3 h-3" />
						)}
					</div>

					{/* 部门图标 */}
					<IconBuilding className="h-4 w-4 text-muted-foreground" />

					{/* 部门名称 */}
					<span className="flex-1 truncate">{node.name}</span>
				</div>

				{/* 选中状态指示 */}
				{isSelected && <IconCheck className="h-4 w-4 text-primary" />}
			</CommandItem>

			{/* 子节点 */}
			{hasChildren && isExpanded && (
				<>
					{node.children!.map((child) => (
						<TreeNode
							key={child.id}
							node={child}
							level={level + 1}
							selectedValue={selectedValue}
							multiple={multiple}
							expandedIds={expandedIds}
							onSelect={onSelect}
							onToggleExpand={onToggleExpand}
						/>
					))}
				</>
			)}
		</>
	);
}

// 主组件
export function DeptSelect({
	value,
	onValueChange,
	placeholder = '选择部门',
	className,
	disabled = false,
	allowClear = true,
	multiple = false,
	excludeIds = [],
	modal = false,
}: OrganizationTreeSelectorProps) {
	const [open, setOpen] = useState(false);
	const [expandedIds, setExpandedIds] = useState<Set<string>>(new Set());
	const [searchValue, setSearchValue] = useState('');

	const trpc = useTRPC();

	// 使用 tRPC 获取组织树数据
	const {
		data: rawOrganizationTree = [],
		isLoading,
		error,
	} = useQuery({
		...trpc.organization.getTree.queryOptions({
			includeInactive: false,
		}),
	});

	// 过滤排除的部门
	const organizationTree = React.useMemo(() => {
		const filterExcluded = (nodes: OrganizationTreeNode[]): OrganizationTreeNode[] => {
			return nodes
				.filter((node) => !excludeIds.includes(node.id))
				.map((node) => ({
					...node,
					children: node.children ? filterExcluded(node.children) : [],
				}));
		};
		return filterExcluded(rawOrganizationTree);
	}, [rawOrganizationTree, excludeIds]);

	// 构建部门树 - 由于后端已经返回树形结构并排序，客户端只需处理过滤后的树
	const buildOrganizationTree = React.useMemo(() => {
		if (!organizationTree || organizationTree.length === 0) {
			return [];
		}
		return organizationTree;
	}, [organizationTree]);

	// 扁平化所有部门，用于查找和路径计算
	const flatOrganizations = React.useMemo(() => {
		const flatten = (nodes: OrganizationTreeNode[]): Organization[] => {
			return nodes.reduce<Organization[]>((acc, node) => {
				acc.push(node);
				if (node.children) {
					acc.push(...flatten(node.children));
				}
				return acc;
			}, []);
		};
		return flatten(organizationTree);
	}, [organizationTree]);

	// 获取选中的部门列表
	const selectedOrganizations = React.useMemo(() => {
		if (!value) return [];

		const selectedIds = Array.isArray(value) ? value : [value];
		return flatOrganizations.filter((org) => selectedIds.includes(org.id));
	}, [flatOrganizations, value]);

	// 获取部门的完整路径
	const getOrganizationPath = React.useCallback(
		(deptId: string): string => {
			const dept = flatOrganizations.find((d) => d.id === deptId);
			if (!dept) return '';

			const path: string[] = [];
			let current: Organization | undefined = dept;

			while (current) {
				path.unshift(current.name);
				current = flatOrganizations.find((d) => d.id === current?.parentId);
			}

			return path.join(' / ');
		},
		[flatOrganizations],
	);

	// 切换展开状态
	const toggleExpand = (id: string) => {
		setExpandedIds((prev) => {
			const newSet = new Set(prev);
			if (newSet.has(id)) {
				newSet.delete(id);
			} else {
				newSet.add(id);
			}
			return newSet;
		});
	};

	// 处理选择逻辑
	const handleSelect = (selectedValue: string, selectedName: string) => {
		if (!onValueChange) return;

		if (multiple) {
			const currentValues = Array.isArray(value) ? value : value ? [value] : [];

			if (currentValues.includes(selectedValue)) {
				// 取消选择
				const newValues = currentValues.filter((id) => id !== selectedValue);
				onValueChange(newValues);
			} else {
				// 添加选择
				onValueChange([...currentValues, selectedValue]);
			}
		} else {
			// 单选模式
			onValueChange(selectedValue);
			setOpen(false);
		}
	};

	// 处理清除
	const handleClear = (e: React.MouseEvent) => {
		e.preventDefault();
		e.stopPropagation();
		onValueChange?.(multiple ? [] : '');
	};

	// 处理单个部门移除（仅多选模式）
	const handleRemoveOrganization = (orgId: string, e: React.MouseEvent) => {
		e.preventDefault();
		e.stopPropagation();
		if (multiple) {
			const currentValues = Array.isArray(value) ? value : value ? [value] : [];
			const newValues = currentValues.filter((id) => id !== orgId);
			onValueChange?.(newValues);
		}
	};

	// 过滤部门（支持搜索）
	const filterOrganizations = React.useCallback(
		(nodes: OrganizationTreeNode[], search: string): OrganizationTreeNode[] => {
			if (!search) return nodes;

			const filtered: OrganizationTreeNode[] = [];

			for (const node of nodes) {
				const matches = node.name.toLowerCase().includes(search.toLowerCase());
				const filteredChildren = node.children ? filterOrganizations(node.children, search) : [];

				if (matches || filteredChildren.length > 0) {
					filtered.push({
						...node,
						children: filteredChildren.length > 0 ? filteredChildren : node.children,
					});
				}
			}

			return filtered;
		},
		[],
	);

	const filteredTree = React.useMemo(() => {
		return filterOrganizations(buildOrganizationTree, searchValue);
	}, [buildOrganizationTree, searchValue, filterOrganizations]);

	// 处理搜索时的自动展开逻辑
	React.useEffect(() => {
		if (searchValue) {
			// 在useEffect内部计算过滤结果，避免依赖filteredTree
			const filtered = filterOrganizations(buildOrganizationTree, searchValue);

			if (filtered.length > 0) {
				const idsToExpand = new Set<string>();

				const collectExpandIds = (nodes: OrganizationTreeNode[]) => {
					nodes.forEach(node => {
						// 如果节点名称匹配搜索条件，展开该节点
						if (node.name.toLowerCase().includes(searchValue.toLowerCase())) {
							idsToExpand.add(node.id);
						}

						// 如果有子节点，展开该节点并递归处理子节点
						if (node.children && node.children.length > 0) {
							idsToExpand.add(node.id);
							collectExpandIds(node.children);
						}
					});
				};

				collectExpandIds(filtered);

				// 批量更新展开状态
				setExpandedIds(prev => new Set([...prev, ...idsToExpand]));
			}
		}
	}, [searchValue, buildOrganizationTree, filterOrganizations]);

	// 渲染触发器内容
	const renderTriggerContent = () => {
		if (selectedOrganizations.length === 0) {
			return placeholder;
		}

		if (multiple) {
			if (selectedOrganizations.length === 1) {
				return getOrganizationPath(selectedOrganizations[0]!.id);
			} else {
				return (
					<div className="flex flex-wrap gap-1 justify-start">
						{selectedOrganizations.slice(0, 2).map((org) => (
							<Badge key={org.id} variant="secondary" className="text-xs px-1.5 py-0.5 h-5 max-w-[120px]">
								<span className="truncate">{org.name}</span>
								<span
									onClick={(e) => handleRemoveOrganization(org.id, e)}
									className="ml-1 hover:bg-muted-foreground/20 rounded-sm p-0.5 cursor-pointer inline-flex items-center justify-center"
									role="button"
									tabIndex={0}
									aria-label={`移除部门 ${org.name}`}
									onKeyDown={(e) => {
										if (e.key === 'Enter' || e.key === ' ') {
											e.preventDefault();
											handleRemoveOrganization(org.id, e as any);
										}
									}}
								>
									<IconX className="h-2.5 w-2.5" />
								</span>
							</Badge>
						))}
						{selectedOrganizations.length > 2 && (
							<Badge variant="secondary" className="text-xs px-1.5 py-0.5 h-5">
								+{selectedOrganizations.length - 2}
							</Badge>
						)}
					</div>
				);
			}
		}

		return getOrganizationPath(selectedOrganizations[0]!.id);
	};

	// 检查是否选中
	const isSelected = (orgId: string) => {
		if (!value) return false;
		return Array.isArray(value) ? value.includes(orgId) : value === orgId;
	};

	// 加载状态
	if (isLoading) {
		return (
			<Button
				variant="outline"
				className={cn('w-[150px] h-8 justify-between text-sm font-normal text-muted-foreground', className)}
				disabled
			>
				<div className="flex items-center gap-2">
					<IconBuilding className="h-4 w-4 text-muted-foreground" />
					<span>加载中...</span>
				</div>
				<IconChevronDown className="h-4 w-4 shrink-0 opacity-50" />
			</Button>
		);
	}

	// 错误状态
	if (error) {
		return (
			<Button
				variant="outline"
				className={cn('w-[150px] h-8 justify-between text-sm font-normal text-muted-foreground', className)}
				disabled
			>
				<div className="flex items-center gap-2">
					<IconBuilding className="h-4 w-4 text-muted-foreground" />
					<span>加载失败</span>
				</div>
				<IconChevronDown className="h-4 w-4 shrink-0 opacity-50" />
			</Button>
		);
	}

	return (
		<Popover open={open} onOpenChange={setOpen} modal={modal}>
			<PopoverTrigger asChild>
				<Button
					variant="outline"
					role="combobox"
					aria-expanded={open}
					className={cn(
						'w-full justify-start text-left font-normal',
						!selectedOrganizations.length && 'text-muted-foreground',
						className,
					)}
					disabled={disabled}
				>
					<div className="flex items-center gap-2 flex-1 min-w-0">
						<IconBuilding className="h-4 w-4 text-muted-foreground shrink-0" />
						<div className="flex-1 min-w-0 text-left">{renderTriggerContent()}</div>
					</div>
					<div className="flex items-center gap-1 shrink-0 ml-auto">
						{allowClear && selectedOrganizations.length > 0 && (
							<span
								onClick={handleClear}
								className="flex items-center justify-center w-4 h-4 rounded-sm hover:bg-muted/50 text-muted-foreground hover:text-foreground transition-colors cursor-pointer"
								role="button"
								tabIndex={0}
								aria-label="清除选择"
								onKeyDown={(e) => {
									if (e.key === 'Enter' || e.key === ' ') {
										e.preventDefault();
										handleClear(e as any);
									}
								}}
							>
								<IconX className="h-3 w-3" />
							</span>
						)}
						<IconChevronDown className="h-4 w-4 shrink-0 opacity-50" />
					</div>
				</Button>
			</PopoverTrigger>
			<PopoverContent className="p-0 w-full" style={{ width: 'var(--radix-popover-trigger-width)' }} align="start">
				<Command shouldFilter={false}>
					<CommandInput placeholder="搜索部门..." value={searchValue} onValueChange={setSearchValue} className="h-9" />
					<CommandList className="max-h-[300px]">
						<CommandEmpty>未找到部门</CommandEmpty>
						<CommandGroup>
							{/* 多选模式下显示已选择数量 */}
							{multiple && selectedOrganizations.length > 0 && (
								<div className="px-2 py-1.5 text-xs text-muted-foreground border-b">
									已选择 {selectedOrganizations.length} 个部门
								</div>
							)}
							{/* 树形部门列表 */}
							{filteredTree.map((node) => (
								<TreeNode
									key={node.id}
									node={node}
									level={0}
									selectedValue={value}
									multiple={multiple}
									expandedIds={expandedIds}
									onSelect={handleSelect}
									onToggleExpand={toggleExpand}
								/>
							))}
						</CommandGroup>
					</CommandList>
				</Command>
			</PopoverContent>
		</Popover>
	);
}

// 导出便捷的单选和多选组件
export function SingleDeptSelector(
	props: Omit<OrganizationTreeSelectorProps, 'multiple' | 'onValueChange'> & {
		onValueChange?: (value: string) => void;
	},
) {
	const handleValueChange = (value: string | string[]) => {
		if (props.onValueChange && typeof value === 'string') {
			props.onValueChange(value);
		}
	};

	return <DeptSelect {...props} multiple={false} onValueChange={handleValueChange} />;
}

export function MultipleDeptSelector(
	props: Omit<OrganizationTreeSelectorProps, 'multiple' | 'onValueChange'> & {
		onValueChange?: (value: string[]) => void;
	},
) {
	const handleValueChange = (value: string | string[]) => {
		if (props.onValueChange && Array.isArray(value)) {
			props.onValueChange(value);
		}
	};

	return <DeptSelect {...props} multiple={true} onValueChange={handleValueChange} />;
}
