import { useState, useCallback, useEffect, useRef } from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import {
  Plus,
  Search,
  Users,
  Shield,
  Loader2,
  CheckCircle,
  AlertCircle,
  Crown,
  User as UserIcon,
} from 'lucide-react';
import { userApi } from '@/services/userApi';
import { toast } from 'sonner';
import { UserTable } from './UserTable';
import { UserStatsCards } from './UserStatsCards';

// Simple debounce function
function debounce<T extends (...args: any[]) => any>(
  func: T,
  wait: number
): (...args: Parameters<T>) => void {
  let timeout: NodeJS.Timeout | null = null;
  return function executedFunction(...args: Parameters<T>) {
    const later = () => {
      timeout = null;
      func(...args);
    };
    if (timeout) clearTimeout(timeout);
    timeout = setTimeout(later, wait);
  };
}

interface OktaUser {
  userId: string;
  email: string;
  firstName?: string;
  lastName?: string;
  displayName?: string;
  department?: string;
  designation?: string;
}

export interface User {
  userId: string;
  email: string;
  displayName: string;
  role: 'USER' | 'MANAGEMENT' | 'ADMIN';
  department?: string;
  designation?: string;
  isActive?: boolean;
}

export function UserManagement() {
  const [searchQuery, setSearchQuery] = useState('');
  const [searchResults, setSearchResults] = useState<OktaUser[]>([]);
  const [searching, setSearching] = useState(false);
  const [selectedUser, setSelectedUser] = useState<OktaUser | null>(null);
  const [selectedRole, setSelectedRole] = useState<'USER' | 'MANAGEMENT' | 'ADMIN'>('USER');
  const [updating, setUpdating] = useState(false);
  const [fetchingRole, setFetchingRole] = useState(false);
  const [message, setMessage] = useState<{ type: 'success' | 'error'; text: string } | null>(null);

  // Users list with filtering and pagination
  const [users, setUsers] = useState<User[]>([]);
  const [loadingUsers, setLoadingUsers] = useState(false);
  const [roleStats, setRoleStats] = useState({ admins: 0, management: 0, users: 0, total: 0, active: 0, inactive: 0 });

  // Pagination and filtering
  const [roleFilter, setRoleFilter] = useState<'ELEVATED' | 'ALL' | 'ADMIN' | 'MANAGEMENT' | 'USER'>('ELEVATED');
  const [currentPage, setCurrentPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [totalUsers, setTotalUsers] = useState(0);
  const limit = 10;

  // Refs for search container
  const searchContainerRef = useRef<HTMLDivElement>(null);

  // Search users from Okta
  const searchUsers = useCallback(
    debounce(async (query: string) => {
      // Only trigger search when using @ sign
      if (!query || !query.startsWith('@') || query.length < 2) {
        setSearchResults([]);
        setSearching(false);
        return;
      }

      setSearching(true);
      try {
        const term = query.slice(1); // Remove @ prefix
        const response = await userApi.searchUsers(term, 20);
        const users = response.data?.data || [];
        setSearchResults(users);
      } catch (error: any) {
        console.error('Search failed:', error);
        setMessage({
          type: 'error',
          text: error.response?.data?.message || 'Failed to search users'
        });
      } finally {
        setSearching(false);
      }
    }, 300),
    []
  );

  // Handle search input
  const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const query = e.target.value;
    setSearchQuery(query);
    searchUsers(query);
  };

  // Fetch user's current role
  const fetchUserRole = async (email: string): Promise<'USER' | 'MANAGEMENT' | 'ADMIN' | null> => {
    try {
      // First check if user exists in current users list
      const existingUser = users.find(u => u.email.toLowerCase() === email.toLowerCase());
      if (existingUser) {
        return existingUser.role;
      }

      // If not found, try to fetch from backend by checking all users
      // We'll search with a broader filter to find the user
      const response = await userApi.getUsersByRole('ALL', 1, 1000);
      const allUsers = response.data?.data?.users || [];
      const foundUser = allUsers.find((u: any) =>
        u.email?.toLowerCase() === email.toLowerCase()
      );

      if (foundUser && foundUser.role) {
        return foundUser.role as 'USER' | 'MANAGEMENT' | 'ADMIN';
      }

      return null; // User not found in system, no role assigned
    } catch (error) {
      console.error('Failed to fetch user role:', error);
      return null;
    }
  };

  // Select user from search results
  const handleSelectUser = async (user: OktaUser) => {
    setSelectedUser(user);
    setSearchQuery(user.email);
    setSearchResults([]);
    setFetchingRole(true);

    try {
      // Fetch and set the user's current role if they have one
      const currentRole = await fetchUserRole(user.email);
      if (currentRole) {
        setSelectedRole(currentRole);
      } else {
        // Default to USER if no role found
        setSelectedRole('USER');
      }
    } catch (error) {
      console.error('Failed to fetch user role:', error);
      setSelectedRole('USER'); // Default on error
    } finally {
      setFetchingRole(false);
    }
  };

  // Assign role to user
  const handleAssignRole = async () => {
    if (!selectedUser || !selectedRole) {
      setMessage({ type: 'error', text: 'Please select a user and role' });
      return;
    }

    setUpdating(true);
    setMessage(null);

    try {
      await userApi.assignRole(selectedUser.email, selectedRole);

      setMessage({
        type: 'success',
        text: `Successfully assigned ${selectedRole} role to ${selectedUser.displayName || selectedUser.email}`
      });

      // Reset form
      setSelectedUser(null);
      setSearchQuery('');
      setSelectedRole('USER');

      // Refresh the users list
      await fetchUsers();
      await fetchRoleStatistics();

      toast.success(`Role assigned successfully`);
    } catch (error: any) {
      console.error('Role assignment failed:', error);
      const errorMsg = error.response?.data?.error || 'Failed to assign role';
      setMessage({
        type: 'error',
        text: errorMsg
      });
      toast.error(errorMsg);
    } finally {
      setUpdating(false);
    }
  };

  // Fetch users with filtering and pagination
  const fetchUsers = async (page: number = currentPage) => {
    setLoadingUsers(true);
    try {
      const response = await userApi.getUsersByRole(roleFilter, page, limit);

      const usersData = response.data?.data?.users || [];
      const paginationData = response.data?.data?.pagination;
      const summaryData = response.data?.data?.summary;

      setUsers(usersData.map((u: any) => ({
        userId: u.userId,
        email: u.email,
        displayName: u.displayName || u.email,
        role: u.role || 'USER',
        department: u.department,
        designation: u.designation,
        isActive: u.isActive !== false // Default to true if not specified
      })));

      if (paginationData) {
        setCurrentPage(paginationData.currentPage);
        setTotalPages(paginationData.totalPages);
        setTotalUsers(paginationData.totalUsers);
      }

      // Update summary stats if available
      if (summaryData) {
        setRoleStats(prev => ({
          ...prev,
          admins: summaryData.ADMIN || 0,
          management: summaryData.MANAGEMENT || 0,
          users: summaryData.USER || 0,
          total: (summaryData.ADMIN || 0) + (summaryData.MANAGEMENT || 0) + (summaryData.USER || 0)
        }));
      }
    } catch (error) {
      console.error('Failed to fetch users:', error);
      toast.error('Failed to load users');
    } finally {
      setLoadingUsers(false);
    }
  };

  // Fetch role statistics
  const fetchRoleStatistics = async () => {
    try {
      const response = await userApi.getRoleStatistics();
      const statsData = response.data?.data?.statistics || response.data?.statistics || [];

      const stats = {
        admins: parseInt(statsData.find((s: any) => s.role === 'ADMIN')?.count || '0'),
        management: parseInt(statsData.find((s: any) => s.role === 'MANAGEMENT')?.count || '0'),
        users: parseInt(statsData.find((s: any) => s.role === 'USER')?.count || '0')
      };

      setRoleStats(prev => ({
        ...prev,
        ...stats,
        total: stats.admins + stats.management + stats.users,
        active: prev.active || stats.admins + stats.management + stats.users,
        inactive: prev.inactive || 0
      }));
    } catch (error) {
      console.error('Failed to fetch statistics:', error);
    }
  };

  // Load data on mount and when filter changes
  useEffect(() => {
    fetchUsers(1); // Reset to page 1 when filter changes
    fetchRoleStatistics();
  }, [roleFilter]);

  // Handle filter change
  const handleFilterChange = (value: string) => {
    setRoleFilter(value as any);
    setCurrentPage(1);
  };

  // Handle page change
  const handlePageChange = (page: number) => {
    fetchUsers(page);
  };

  // Handle edit user role
  const handleEditUser = async (userId: string, newRole: 'USER' | 'MANAGEMENT' | 'ADMIN') => {
    try {
      await userApi.updateUserRole(userId, newRole);
      toast.success('User role updated successfully');
      await fetchUsers();
      await fetchRoleStatistics();
    } catch (error: any) {
      console.error('Failed to update user role:', error);
      toast.error(error.response?.data?.error || 'Failed to update user role');
    }
  };

  // Handle toggle user status (placeholder - needs backend support)
  const handleToggleUserStatus = async (userId: string) => {
    const user = users.find(u => u.userId === userId);
    if (!user) return;


    toast.info('User status toggle functionality coming soon');
  };

  // Handle delete user (placeholder - needs backend support)
  const handleDeleteUser = async (userId: string) => {
    const user = users.find(u => u.userId === userId);
    if (!user) return;

    if (user.role === 'ADMIN') {
      toast.error('Cannot delete admin user');
      return;
    }

    toast.info('User deletion functionality coming soon');
  };

  // Handle click outside to close search results
  useEffect(() => {
    const handleClickOutside = (event: MouseEvent) => {
      if (searchContainerRef.current && !searchContainerRef.current.contains(event.target as Node)) {
        setSearchResults([]);
      }
    };

    if (searchResults.length > 0) {
      document.addEventListener('mousedown', handleClickOutside);
    }

    return () => {
      document.removeEventListener('mousedown', handleClickOutside);
    };
  }, [searchResults]);


  // Calculate stats for UserStatsCards
  const stats = {
    total: roleStats.total,
    active: roleStats.active,
    inactive: roleStats.inactive,
    admins: roleStats.admins
  };

  return (
    <div className="space-y-6">
      {/* Statistics Cards */}
      <UserStatsCards stats={stats} />

      {/* Assign Role Section */}
      <Card>
        <CardHeader>
          <div className="flex items-center justify-between">
            <div>
              <CardTitle>Assign User Role</CardTitle>
              <CardDescription>
                Search for a user in Okta and assign them a role
              </CardDescription>
            </div>
            <Button onClick={handleAssignRole} disabled={!selectedUser || updating} className="bg-re-green hover:bg-re-green/90">
              {updating ? (
                <>
                  <Loader2 className="w-4 h-4 mr-2 animate-spin" />
                  Assigning...
                </>
              ) : (
                <>
                  <Plus className="w-4 h-4 mr-2" />
                  Assign Role
                </>
              )}
            </Button>
          </div>
        </CardHeader>
        <CardContent className="space-y-6">
          {/* Search Input */}
          <div className="space-y-2" ref={searchContainerRef}>
            <div className="flex items-center gap-2">
              <div className="relative flex-1">
                <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-muted-foreground" />
                <Input
                  type="text"
                  placeholder="Type @ to search users..."
                  value={searchQuery}
                  onChange={handleSearchChange}
                  className="pl-10 border-gray-200 focus:border-re-green focus:ring-2 focus:ring-re-green/20"
                />
                {searching && (
                  <Loader2 className="absolute right-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-re-green animate-spin" />
                )}
              </div>
            </div>
            <p className="text-xs text-muted-foreground">Start with @ to search users (e.g., @john)</p>

            {/* Search Results Dropdown */}
            {searchResults.length > 0 && (
              <div className="border rounded-lg shadow-lg bg-white max-h-60 overflow-y-auto">
                <div className="sticky top-0 bg-muted px-4 py-2 border-b">
                  <p className="text-xs font-semibold text-muted-foreground">
                    {searchResults.length} user{searchResults.length > 1 ? 's' : ''} found
                  </p>
                </div>
                <div className="p-3">
                  {searchResults.map((user) => (
                    <button
                      key={user.userId}
                      onClick={() => handleSelectUser(user)}
                      className="w-full text-left p-3 hover:bg-muted rounded-lg transition-colors mb-1 last:mb-0"
                    >
                      <p className="font-medium text-gray-900">{user.displayName || user.email}</p>
                      <p className="text-sm text-muted-foreground">{user.email}</p>
                      {user.department && (
                        <p className="text-xs text-muted-foreground mt-1">
                          {user.department}{user.designation ? ` • ${user.designation}` : ''}
                        </p>
                      )}
                    </button>
                  ))}
                </div>
              </div>
            )}
          </div>

          {/* Selected User */}
          {selectedUser && (
            <div className="border-2 border-re-green/20 bg-re-green/5 rounded-lg p-4">
              <div className="flex items-center justify-between">
                <div className="flex items-center gap-3">
                  <div className="w-10 h-10 rounded-lg bg-re-green flex items-center justify-center text-white font-bold shadow-md">
                    {(selectedUser.displayName || selectedUser.email).charAt(0).toUpperCase()}
                  </div>
                  <div>
                    <p className="font-semibold text-gray-900">
                      {selectedUser.displayName || selectedUser.email}
                    </p>
                    <p className="text-sm text-muted-foreground">{selectedUser.email}</p>
                    {selectedUser.department && (
                      <p className="text-xs text-muted-foreground mt-1">
                        {selectedUser.department}{selectedUser.designation ? ` • ${selectedUser.designation}` : ''}
                      </p>
                    )}
                    {fetchingRole && (
                      <p className="text-xs text-re-green mt-1 flex items-center gap-1">
                        <Loader2 className="w-3 h-3 animate-spin" />
                        Checking current role...
                      </p>
                    )}
                  </div>
                </div>
                <Button
                  variant="ghost"
                  size="sm"
                  onClick={() => {
                    setSelectedUser(null);
                    setSearchQuery('');
                    setSelectedRole('USER');
                    setFetchingRole(false);
                  }}
                >
                  Clear
                </Button>
              </div>
            </div>
          )}

          {/* Role Selection */}
          <div className="space-y-2">
            <label className="text-sm font-medium">Select Role</label>
            <Select value={selectedRole} onValueChange={(value: any) => setSelectedRole(value)} disabled={fetchingRole}>
              <SelectTrigger className="border-gray-200 focus:border-re-green focus:ring-2 focus:ring-re-green/20">
                <SelectValue placeholder={fetchingRole ? "Loading current role..." : "Select role"} />
              </SelectTrigger>
              <SelectContent className="rounded-lg">
                <SelectItem value="USER" className="p-3 rounded-lg my-1">
                  <div className="flex items-center gap-2">
                    <UserIcon className="w-4 h-4 text-gray-600" />
                    <span>User - Regular access</span>
                  </div>
                </SelectItem>
                <SelectItem value="MANAGEMENT" className="p-3 rounded-lg my-1">
                  <div className="flex items-center gap-2">
                    <Users className="w-4 h-4 text-blue-600" />
                    <span>Management - Read all data</span>
                  </div>
                </SelectItem>
                <SelectItem value="ADMIN" className="p-3 rounded-lg my-1">
                  <div className="flex items-center gap-2">
                    <Crown className="w-4 h-4 text-yellow-600" />
                    <span>Administrator - Full access</span>
                  </div>
                </SelectItem>
              </SelectContent>
            </Select>
          </div>

          {/* Message */}
          {message && (
            <div className={`border-2 rounded-lg p-4 ${message.type === 'success'
              ? 'border-green-200 bg-green-50'
              : 'border-red-200 bg-red-50'
              }`}>
              <div className="flex items-start gap-3">
                {message.type === 'success' ? (
                  <CheckCircle className="w-5 h-5 text-green-600 shrink-0 mt-0.5" />
                ) : (
                  <AlertCircle className="w-5 h-5 text-red-600 shrink-0 mt-0.5" />
                )}
                <p className={`text-sm ${message.type === 'success' ? 'text-green-800' : 'text-red-800'}`}>
                  {message.text}
                </p>
              </div>
            </div>
          )}
        </CardContent>
      </Card>

      {/* Users List with Filter and Pagination */}
      <Card>
        <CardHeader>
          <div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
            <div>
              <CardTitle className="flex items-center gap-2">
                <Users className="w-5 h-5 text-re-green" />
                User Management
              </CardTitle>
              <CardDescription>
                View and manage user accounts and roles ({totalUsers} {roleFilter !== 'ALL' && roleFilter !== 'ELEVATED' ? roleFilter.toLowerCase() : ''} users)
              </CardDescription>
            </div>
            <div className="flex items-center gap-3">
              <Select value={roleFilter} onValueChange={handleFilterChange}>
                <SelectTrigger className="w-[200px] border-gray-200 focus:border-re-green focus:ring-2 focus:ring-re-green/20">
                  <SelectValue placeholder="Filter by role" />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="ELEVATED">
                    <div className="flex items-center gap-2">
                      <Shield className="w-4 h-4 text-purple-600" />
                      <span>Elevated ({roleStats.admins + roleStats.management})</span>
                    </div>
                  </SelectItem>
                  <SelectItem value="ADMIN">
                    <div className="flex items-center gap-2">
                      <Crown className="w-4 h-4 text-yellow-600" />
                      <span>Admins ({roleStats.admins})</span>
                    </div>
                  </SelectItem>
                  <SelectItem value="MANAGEMENT">
                    <div className="flex items-center gap-2">
                      <Users className="w-4 h-4 text-blue-600" />
                      <span>Management ({roleStats.management})</span>
                    </div>
                  </SelectItem>
                  <SelectItem value="USER">
                    <div className="flex items-center gap-2">
                      <UserIcon className="w-4 h-4 text-gray-600" />
                      <span>Users ({roleStats.users})</span>
                    </div>
                  </SelectItem>
                  <SelectItem value="ALL">
                    <div className="flex items-center gap-2">
                      <Users className="w-4 h-4 text-gray-600" />
                      <span>All Users ({roleStats.admins + roleStats.management + roleStats.users})</span>
                    </div>
                  </SelectItem>
                </SelectContent>
              </Select>
            </div>
          </div>
        </CardHeader>
        <CardContent className="pt-6">
          {loadingUsers ? (
            <div className="flex flex-col items-center justify-center py-8">
              <Loader2 className="w-6 h-6 animate-spin text-re-green mb-2" />
              <p className="text-sm text-muted-foreground">Loading users...</p>
            </div>
          ) : users.length === 0 ? (
            <div className="text-center py-8">
              <div className="w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center mx-auto mb-3">
                <Users className="w-6 h-6 text-gray-400" />
              </div>
              <p className="font-medium text-gray-700">No users found</p>
              <p className="text-sm text-gray-500 mt-1">
                {roleFilter === 'ELEVATED'
                  ? 'Assign ADMIN or MANAGEMENT roles to see users here'
                  : 'No users match the selected filter'
                }
              </p>
            </div>
          ) : (
            <>
              <UserTable
                users={users.map(u => ({
                  id: u.userId,
                  name: u.displayName,
                  email: u.email,
                  role: u.role, // Keep as ADMIN, MANAGEMENT, or USER
                  department: u.department || 'N/A',
                  status: u.isActive ? 'active' : 'inactive'
                }))}
                onEdit={(userId) => {
                  const user = users.find(u => u.userId === userId);
                  if (user) {
                    // Open role selection dialog
                    const newRole = user.role === 'USER' ? 'MANAGEMENT' : user.role === 'MANAGEMENT' ? 'ADMIN' : 'USER';
                    handleEditUser(userId, newRole);
                  }
                }}
                onToggleStatus={handleToggleUserStatus}
                onDelete={handleDeleteUser}
              />

              {/* Pagination Controls */}
              {totalPages > 1 && (
                <div className="flex items-center justify-between pt-4 border-t mt-4">
                  <div className="text-sm text-gray-600">
                    Showing {((currentPage - 1) * limit) + 1} to {Math.min(currentPage * limit, totalUsers)} of {totalUsers} users
                  </div>
                  <div className="flex items-center gap-2">
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => handlePageChange(currentPage - 1)}
                      disabled={currentPage === 1}
                    >
                      Previous
                    </Button>
                    <div className="flex items-center gap-1">
                      {Array.from({ length: Math.min(5, totalPages) }, (_, i) => {
                        let pageNum;
                        if (totalPages <= 5) {
                          pageNum = i + 1;
                        } else if (currentPage <= 3) {
                          pageNum = i + 1;
                        } else if (currentPage >= totalPages - 2) {
                          pageNum = totalPages - 4 + i;
                        } else {
                          pageNum = currentPage - 2 + i;
                        }
                        return (
                          <Button
                            key={pageNum}
                            variant={currentPage === pageNum ? "default" : "outline"}
                            size="sm"
                            onClick={() => handlePageChange(pageNum)}
                            className={`w-9 h-9 p-0 ${currentPage === pageNum
                              ? 'bg-re-green hover:bg-re-green/90'
                              : ''
                              }`}
                          >
                            {pageNum}
                          </Button>
                        );
                      })}
                    </div>
                    <Button
                      variant="outline"
                      size="sm"
                      onClick={() => handlePageChange(currentPage + 1)}
                      disabled={currentPage === totalPages}
                    >
                      Next
                    </Button>
                  </div>
                </div>
              )}
            </>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
