/**
 * 通用用户选择器组件
 * 用于审批流程中选择审批人、抄送人，以及转交审批等场景
 * 
 * 功能：
 * - 无限滚动加载
 * - 后端全量搜索
 * - 单选/多选模式
 */

'use client';

import React, { useState, useEffect, useRef, useCallback } from 'react';
import {
  X,
  Search,
  Users,
  User as UserIcon,
  Check,
  Building,
  Mail,
  Loader2,
} from 'lucide-react';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from '@/components/ui/dialog';
import { toast } from '@/lib/toast';
import { getUsers, type User } from '@/services/api/users';
import { ApiClientError } from '@/lib/api-client';

// 用户信息类型
export interface UserInfo {
  id: string;
  displayName: string;
  username?: string;
  email?: string;
  avatar?: string;
  department?: string;
}

// 将 User 转换为 UserInfo
function userToUserInfo(user: User): UserInfo {
  return {
    id: user.id,
    displayName: user.displayName,
    username: user.username,
    email: user.email,
    avatar: undefined, // 暂无头像字段
    department: user.department?.name,
  };
}

interface UserSelectorProps {
  open: boolean;
  onClose: () => void;
  onConfirm: (selectedUsers: UserInfo[]) => void;
  selectedUserIds?: string[];
  multiple?: boolean;
  title?: string;
  description?: string;
}

export function UserSelector({
  open,
  onClose,
  onConfirm,
  selectedUserIds = [],
  multiple = true,
  title = '选择用户',
  description,
}: UserSelectorProps) {
  const [allUsers, setAllUsers] = useState<UserInfo[]>([]); // 所有已加载的用户
  const [searchTerm, setSearchTerm] = useState('');
  const [selectedIds, setSelectedIds] = useState<Set<string>>(new Set(selectedUserIds));
  const [loading, setLoading] = useState(false);
  
  // 分页状态
  const [page, setPage] = useState(1);
  const [total, setTotal] = useState(0);
  const [hasMore, setHasMore] = useState(true);
  const pageSize = 20;

  // 无限滚动相关
  const scrollContainerRef = useRef<HTMLDivElement>(null);
  const observerRef = useRef<IntersectionObserver | null>(null);
  const loadMoreTriggerRef = useRef<HTMLDivElement>(null);

  // 搜索防抖
  const searchTimeoutRef = useRef<NodeJS.Timeout | null>(null);
  
  // 用于区分是初始化还是搜索变化（避免重复加载）
  const isInitializingRef = useRef(false);

  // 用 ref 保存最新状态，供 IntersectionObserver 使用（避免闭包问题）
  const stateRef = useRef({ page, hasMore, loading, searchTerm });
  // ⚠️ 不用 useEffect，每次渲染时立即更新（避免延迟）
  stateRef.current = { page, hasMore, loading, searchTerm };

  // 初始化 - 只在对话框打开时执行一次
  useEffect(() => {
    if (open) {
      isInitializingRef.current = true;
      setPage(1);
      setAllUsers([]);
      setSearchTerm('');
      setSelectedIds(new Set(selectedUserIds));
      setHasMore(true);
      loadUsers(1, '');
      // 延迟重置标志，确保搜索防抖 useEffect 能检测到
      setTimeout(() => {
        isInitializingRef.current = false;
      }, 50);
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open]);

  // 搜索处理（防抖 + 后端搜索）
  useEffect(() => {
    if (!open) return;
    
    // ⚠️ 如果是初始化阶段，跳过（避免重复加载）
    if (isInitializingRef.current) {
      return;
    }

    // 清除之前的定时器
    if (searchTimeoutRef.current) {
      clearTimeout(searchTimeoutRef.current);
    }

    // 设置新的定时器（300ms 防抖）
    searchTimeoutRef.current = setTimeout(() => {
      console.log('[UserSelector] Search triggered, term:', searchTerm);
      // ⚠️ 搜索时不清空列表（避免抖动），而是用 loading 状态覆盖
      setPage(1);
      setHasMore(true);
      loadUsers(1, searchTerm);
    }, 300);

    return () => {
      if (searchTimeoutRef.current) {
        clearTimeout(searchTimeoutRef.current);
      }
    };
  }, [searchTerm, open]);

  // 无限滚动监听（最简方案：打开时创建，关闭时销毁）
  useEffect(() => {
    if (!open) {
      // 关闭时清理
      if (observerRef.current) {
        observerRef.current.disconnect();
        observerRef.current = null;
        console.log('[UserSelector] Observer disconnected (dialog closed)');
      }
      return;
    }

    // 打开时，延迟创建（等待数据和 DOM）
    let rafId: number;
    let checkInterval: NodeJS.Timeout;

    const trySetupObserver = () => {
      // 如果已经有 Observer，跳过
      if (observerRef.current) {
        console.log('[UserSelector] Observer already exists');
        return true;
      }

      // 如果触发元素还不存在，返回 false
      if (!loadMoreTriggerRef.current) {
        return false;
      }

      // 创建 Observer
      observerRef.current = new IntersectionObserver(
        (entries) => {
          const [entry] = entries;
          const { page, hasMore, loading, searchTerm } = stateRef.current;
          
          console.log('[UserSelector] Observer triggered:', {
            isIntersecting: entry.isIntersecting,
            hasMore,
            loading,
            page,
            searchTerm,
            timestamp: Date.now()
          });
          
          if (entry.isIntersecting && hasMore && !loading) {
            console.log('[UserSelector] ✅ Conditions met, loading page', page + 1);
            loadUsers(page + 1, searchTerm);
          } else {
            console.log('[UserSelector] ❌ Conditions not met:', {
              isIntersecting: entry.isIntersecting,
              hasMore,
              loading,
              willLoad: entry.isIntersecting && hasMore && !loading
            });
          }
        },
        {
          root: scrollContainerRef.current,
          rootMargin: '100px',
          threshold: 0.1,
        }
      );

      observerRef.current.observe(loadMoreTriggerRef.current);
      console.log('[UserSelector] Observer created and connected');
      return true;
    };

    // 尝试立即创建
    rafId = requestAnimationFrame(() => {
      if (!trySetupObserver()) {
        console.log('[UserSelector] Waiting for trigger element...');
        // 如果失败，每100ms重试一次
        checkInterval = setInterval(() => {
          if (trySetupObserver()) {
            clearInterval(checkInterval);
          }
        }, 100);
      }
    });

    // Cleanup：只清理定时器和 RAF，不清理 Observer
    return () => {
      cancelAnimationFrame(rafId);
      if (checkInterval) {
        clearInterval(checkInterval);
      }
    };
  }, [open]); // ⚠️ 只依赖 open，打开后不再重建

  const loadUsers = async (pageNum: number, search: string) => {
    console.log('[UserSelector] loadUsers called:', { pageNum, search, currentLoading: loading, currentPage: page });
    
    // ⚠️ 立即更新 loading 和 page，防止重复触发
    setLoading(true);
    setPage(pageNum);
    
    try {
      // 调用真实的用户列表 API（支持搜索）
      const response = await getUsers({
        page: pageNum,
        pageSize,
        status: 'ACTIVE', // 只获取激活的用户
        search: search || undefined, // 后端搜索
      });
      
      // 转换为 UserInfo 格式
      const userInfos = response.items.map(userToUserInfo);
      
      // 追加到已有用户列表（支持加载更多）
      setAllUsers(prev => pageNum === 1 ? userInfos : [...prev, ...userInfos]);
      
      // 更新分页信息
      setTotal(response.total);
      setHasMore(response.hasNext);
      
      console.log('[UserSelector] loadUsers completed:', { pageNum, itemsCount: userInfos.length, hasNext: response.hasNext });
      
      // ⚠️ 搜索完成后（第1页），手动触发 Observer 检查一次（确保 trigger 元素在视口内时能立即加载下一页）
      if (pageNum === 1 && response.hasNext && observerRef.current && loadMoreTriggerRef.current) {
        console.log('[UserSelector] Manually re-observing trigger after search');
        // 先断开再重新观察，触发一次检查
        observerRef.current.unobserve(loadMoreTriggerRef.current);
        observerRef.current.observe(loadMoreTriggerRef.current);
      }
      
    } catch (error) {
      console.error('加载用户列表失败:', error);
      if (error instanceof ApiClientError) {
        toast.error(`加载用户列表失败: ${error.message}`);
      } else {
        toast.error('加载用户列表失败');
      }
      // ⚠️ 出错时恢复 page
      setPage(pageNum - 1);
    } finally {
      setLoading(false);
    }
  };

  const toggleUser = (userId: string) => {
    const newSelected = new Set(selectedIds);
    if (newSelected.has(userId)) {
      newSelected.delete(userId);
    } else {
      if (!multiple) {
        newSelected.clear();
      }
      newSelected.add(userId);
    }
    setSelectedIds(newSelected);
  };

  const handleConfirm = () => {
    const selected = allUsers.filter((user) => selectedIds.has(user.id));
    onConfirm(selected);
    onClose();
  };

  const handleClose = () => {
    setSearchTerm('');
    onClose();
  };

  return (
    <Dialog open={open} onOpenChange={handleClose}>
      <DialogContent className="max-w-2xl max-h-[80vh] p-0 gap-0">
        <DialogHeader className="px-6 py-4 border-b">
          <DialogTitle className="flex items-center gap-2">
            <Users className="w-5 h-5 text-blue-600" />
            {title}
            {selectedIds.size > 0 && (
              <span className="ml-2 px-2 py-0.5 bg-blue-50 text-blue-600 text-xs rounded-full">
                已选 {selectedIds.size} 人
              </span>
            )}
          </DialogTitle>
          <DialogDescription className="sr-only">
            {description || title}
          </DialogDescription>
        </DialogHeader>

        {/* 搜索栏 */}
        <div className="px-6 py-3 border-b bg-gray-50">
          <div className="relative">
            <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-gray-400" />
            <Input
              placeholder="搜索姓名、用户名、邮箱或部门..."
              value={searchTerm}
              onChange={(e) => setSearchTerm(e.target.value)}
              className="pl-10 bg-white"
            />
          </div>
          {searchTerm && (
            <div className="mt-2 text-xs text-gray-500">
              {loading && page === 1 ? '搜索中...' : `找到 ${total} 个结果`}
            </div>
          )}
        </div>

        {/* 用户列表 */}
        <div 
          ref={scrollContainerRef}
          className="flex-1 overflow-y-auto px-6 py-4 min-h-[300px] max-h-[400px] relative"
        >
          {/* 搜索时的 loading overlay（避免抖动） */}
          {loading && page === 1 && searchTerm && allUsers.length > 0 && (
            <div className="absolute inset-0 bg-white/80 backdrop-blur-sm flex items-center justify-center z-10">
              <div className="flex flex-col items-center">
                <Loader2 className="w-8 h-8 text-blue-500 animate-spin" />
                <p className="mt-2 text-sm text-gray-500">搜索中...</p>
              </div>
            </div>
          )}

          {loading && page === 1 && (!searchTerm || allUsers.length === 0) ? (
            <div className="flex flex-col items-center justify-center py-12">
              <Loader2 className="w-8 h-8 text-blue-500 animate-spin" />
              <p className="mt-2 text-sm text-gray-500">加载中...</p>
            </div>
          ) : allUsers.length === 0 ? (
            <div className="flex flex-col items-center justify-center py-12">
              <Users className="w-12 h-12 text-gray-300" />
              <p className="mt-2 text-sm text-gray-500">
                {searchTerm ? '未找到匹配的用户' : '暂无用户'}
              </p>
            </div>
          ) : (
            <>
              <div className="space-y-1">
                {allUsers.map((user) => {
                const isSelected = selectedIds.has(user.id);
                return (
                  <div
                    key={user.id}
                    onClick={() => toggleUser(user.id)}
                    className={`
                      flex items-center gap-3 p-3 rounded-lg cursor-pointer transition-all
                      ${
                        isSelected
                          ? 'bg-blue-50 border-2 border-blue-500'
                          : 'border-2 border-transparent hover:bg-gray-50 hover:border-gray-200'
                      }
                    `}
                  >
                    {/* 头像 */}
                    <div
                      className={`
                        w-10 h-10 rounded-full flex items-center justify-center flex-shrink-0
                        ${isSelected ? 'bg-blue-500' : 'bg-gray-200'}
                      `}
                    >
                      {user.avatar ? (
                        <img
                          src={user.avatar}
                          alt={user.displayName}
                          className="w-full h-full rounded-full object-cover"
                        />
                      ) : (
                        <UserIcon
                          className={`w-5 h-5 ${
                            isSelected ? 'text-white' : 'text-gray-500'
                          }`}
                        />
                      )}
                    </div>

                    {/* 用户信息 */}
                    <div className="flex-1 min-w-0">
                      <div className="flex items-center gap-2">
                        <span
                          className={`font-medium ${
                            isSelected ? 'text-blue-900' : 'text-gray-900'
                          }`}
                        >
                          {user.displayName}
                        </span>
                        {user.username && (
                          <span className="text-xs text-gray-400">
                            @{user.username}
                          </span>
                        )}
                      </div>
                      <div className="flex items-center gap-3 mt-0.5 text-xs text-gray-500">
                        {user.department && (
                          <span className="flex items-center gap-1">
                            <Building className="w-3 h-3" />
                            {user.department}
                          </span>
                        )}
                        {user.email && (
                          <span className="flex items-center gap-1 truncate">
                            <Mail className="w-3 h-3" />
                            {user.email}
                          </span>
                        )}
                      </div>
                    </div>

                    {/* 选中状态 */}
                    {isSelected && (
                      <div className="w-6 h-6 rounded-full bg-blue-500 flex items-center justify-center flex-shrink-0">
                        <Check className="w-4 h-4 text-white" />
                      </div>
                    )}
                  </div>
                );
              })}
              </div>

              {/* 无限滚动触发器 + 加载状态 */}
              {hasMore && (
                <div 
                  ref={loadMoreTriggerRef}
                  className="mt-4 flex justify-center py-4"
                >
                  {loading ? (
                    <div className="flex items-center gap-2 text-sm text-gray-500">
                      <Loader2 className="w-4 h-4 animate-spin" />
                      <span>加载中...</span>
                    </div>
                  ) : (
                    <div className="text-xs text-gray-400">
                      滚动加载更多 ({allUsers.length}/{total})
                    </div>
                  )}
                </div>
              )}

              {/* 已加载全部 */}
              {!hasMore && allUsers.length > 0 && (
                <div className="mt-4 py-4 text-center text-xs text-gray-400">
                  已加载全部 {total} 人
                </div>
              )}
            </>
          )}
        </div>

        {/* 底部按钮 */}
        <DialogFooter className="px-6 py-4 border-t bg-gray-50">
          <div className="flex items-center justify-between w-full">
            <div className="text-sm text-gray-600">
              {multiple ? (
                <>
                  {selectedIds.size > 0 ? (
                    <span>
                      已选择 <span className="font-medium text-blue-600">{selectedIds.size}</span> 人
                    </span>
                  ) : (
                    <span>请选择用户</span>
                  )}
                  {total > 0 && (
                    <span className="ml-2 text-gray-400">
                      / 共 {total} 人
                    </span>
                  )}
                </>
              ) : (
                <span>单选模式</span>
              )}
            </div>
            <div className="flex gap-2">
              <Button variant="outline" onClick={handleClose}>
                取消
              </Button>
              <Button
                onClick={handleConfirm}
                disabled={selectedIds.size === 0}
                className="bg-blue-500 hover:bg-blue-600"
              >
                确定 {selectedIds.size > 0 && `(${selectedIds.size})`}
              </Button>
            </div>
          </div>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}
