import React, { useState, useEffect, useMemo } from 'react';
import { User, UserRole } from '../../types';
import { AccountStatus } from '../../services/auth/auth.constants';
import { databaseService } from '../../services/database';
import { useUser } from '../../contexts/UserContext';

interface AdminInterfaceProps {
  onClose: () => void;
}

const AdminInterface: React.FC<AdminInterfaceProps> = ({ onClose }) => {
  const { user: currentUser } = useUser();
  const [users, setUsers] = useState<User[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState('');
  const [selectedUser, setSelectedUser] = useState<User | null>(null);
  const [newPassword, setNewPassword] = useState('');
  const [userPendingDeletion, setUserPendingDeletion] = useState<User | null>(
    null
  );
  const [isDeletingUser, setIsDeletingUser] = useState(false);
  const [toasts, setToasts] = useState<
    Array<{ id: string; message: string; tone: 'success' | 'error' | 'info' }>
  >([]);
  const [searchTerm, setSearchTerm] = useState('');
  const [sortField, setSortField] = useState<
    'createdAt' | 'status' | 'role' | 'username'
  >('createdAt');
  const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc');

  const createToastId = () =>
    typeof crypto !== 'undefined' && crypto.randomUUID
      ? crypto.randomUUID()
      : `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;

  const removeToast = (id: string) => {
    setToasts(prev => prev.filter(toast => toast.id !== id));
  };

  const pushToast = (
    message: string,
    tone: 'success' | 'error' | 'info' = 'info'
  ) => {
    const id = createToastId();
    setToasts(prev => [...prev, { id, message, tone }]);
    window.setTimeout(() => removeToast(id), 4000);
  };

  const toastStyles: Record<'success' | 'error' | 'info', string> = {
    success: 'bg-green-50 border border-green-200 text-green-800',
    error: 'bg-red-50 border border-red-200 text-red-800',
    info: 'bg-blue-50 border border-blue-200 text-blue-800',
  };

  useEffect(() => {
    loadUsers();
  }, []);

  const loadUsers = async () => {
    setLoading(true);
    setError('');
    try {
      const users = await databaseService.getAllUsers();
      setUsers(users);
    } catch (error) {
      setError('Failed to load users');
      console.error('Error loading users:', error);
      pushToast('Failed to load users', 'error');
    } finally {
      setLoading(false);
    }
  };

  const handleSuspendUser = async (user: User) => {
    try {
      await databaseService.suspendUser(user._id);
      pushToast(`${user.username} suspended`, 'info');
      await loadUsers();
    } catch (error) {
      setError('Failed to suspend user');
      console.error('Error suspending user:', error);
      pushToast('Failed to suspend user', 'error');
    }
  };

  const handleActivateUser = async (user: User) => {
    try {
      await databaseService.activateUser(user._id);
      pushToast(`${user.username} reactivated`, 'success');
      await loadUsers();
    } catch (error) {
      setError('Failed to activate user');
      console.error('Error activating user:', error);
      pushToast('Failed to activate user', 'error');
    }
  };

  const confirmDeleteUser = (user: User) => {
    setUserPendingDeletion(user);
    setError('');
  };

  const executeDeleteUser = async () => {
    if (!userPendingDeletion) return;

    setIsDeletingUser(true);
    try {
      await databaseService.deleteUser(userPendingDeletion._id);
      pushToast(`${userPendingDeletion.username} deleted`, 'info');
      await loadUsers();
    } catch (error) {
      setError('Failed to delete user');
      console.error('Error deleting user:', error);
      pushToast('Failed to delete user', 'error');
    } finally {
      setIsDeletingUser(false);
      setUserPendingDeletion(null);
    }
  };

  const closeDeleteDialog = () => {
    if (isDeletingUser) return;
    setUserPendingDeletion(null);
  };

  const handleChangePassword = async (userId: string) => {
    if (!newPassword || newPassword.length < 6) {
      setError('Password must be at least 6 characters long');
      return;
    }

    try {
      await databaseService.changeUserPassword(userId, newPassword);
      setNewPassword('');
      setSelectedUser(null);
      setError('');
      pushToast('Password changed successfully', 'success');
    } catch (error) {
      setError('Failed to change password');
      console.error('Error changing password:', error);
      pushToast('Failed to change password', 'error');
    }
  };

  const getStatusColor = (status?: AccountStatus) => {
    switch (status) {
      case AccountStatus.ACTIVE:
        return 'text-green-600 bg-green-100';
      case AccountStatus.SUSPENDED:
        return 'text-red-600 bg-red-100';
      case AccountStatus.PENDING:
        return 'text-yellow-600 bg-yellow-100';
      default:
        return 'text-gray-600 bg-gray-100';
    }
  };

  const getRoleColor = (role?: UserRole) => {
    return role === UserRole.ADMIN
      ? 'text-purple-600 bg-purple-100'
      : 'text-blue-600 bg-blue-100';
  };

  const statusPriority: Record<AccountStatus, number> = {
    [AccountStatus.ACTIVE]: 0,
    [AccountStatus.PENDING]: 1,
    [AccountStatus.SUSPENDED]: 2,
  };

  const rolePriority: Record<UserRole, number> = {
    [UserRole.ADMIN]: 0,
    [UserRole.USER]: 1,
  };

  const getStatusPriority = (status?: AccountStatus) =>
    statusPriority[status as AccountStatus] ?? Number.MAX_SAFE_INTEGER;

  const getRolePriority = (role?: UserRole) =>
    rolePriority[role as UserRole] ?? Number.MAX_SAFE_INTEGER;

  const sortedUsers = useMemo(() => {
    const copy = [...users];
    copy.sort((a, b) => {
      let result = 0;

      switch (sortField) {
        case 'status':
          result = getStatusPriority(a.status) - getStatusPriority(b.status);
          break;
        case 'role':
          result = getRolePriority(a.role) - getRolePriority(b.role);
          break;
        case 'username':
          result = (a.username || '').localeCompare(
            b.username || '',
            undefined,
            {
              sensitivity: 'base',
            }
          );
          break;
        case 'createdAt':
        default: {
          const timeA = a.createdAt ? new Date(a.createdAt).getTime() : 0;
          const timeB = b.createdAt ? new Date(b.createdAt).getTime() : 0;
          result = timeA - timeB;
          break;
        }
      }

      if (result === 0) {
        result = (a.username || '').localeCompare(b.username || '', undefined, {
          sensitivity: 'base',
        });
      }

      if (result === 0) {
        result = (a.email || '').localeCompare(b.email || '', undefined, {
          sensitivity: 'base',
        });
      }

      return sortDirection === 'asc' ? result : -result;
    });

    return copy;
  }, [users, sortField, sortDirection]);

  const filteredUsers = useMemo(() => {
    if (!searchTerm.trim()) {
      return sortedUsers;
    }

    const query = searchTerm.trim().toLowerCase();
    return sortedUsers.filter(user => {
      const username = user.username?.toLowerCase() ?? '';
      const email = user.email?.toLowerCase() ?? '';
      return username.includes(query) || email.includes(query);
    });
  }, [sortedUsers, searchTerm]);

  const visibleUsersLabel = searchTerm.trim()
    ? `${filteredUsers.length} of ${users.length} users`
    : `${filteredUsers.length} users`;

  if (currentUser?.role !== UserRole.ADMIN) {
    return (
      <div className='fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50'>
        <div className='bg-white dark:bg-slate-800 rounded-lg p-6 max-w-md'>
          <h2 className='text-xl font-bold text-red-600 mb-4'>Access Denied</h2>
          <p className='text-slate-600 dark:text-slate-300 mb-4'>
            You don't have permission to access the admin interface.
          </p>
          <button
            onClick={onClose}
            className='w-full bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-2 px-4 rounded-md'
          >
            Close
          </button>
        </div>
      </div>
    );
  }

  return (
    <>
      <div className='fixed top-4 right-4 z-[70] space-y-2'>
        {toasts.map(toast => (
          <div
            key={toast.id}
            className={`px-4 py-3 rounded-lg shadow-lg flex items-start justify-between gap-3 ${toastStyles[toast.tone]}`}
            role='status'
            aria-live='polite'
          >
            <span className='text-sm font-medium'>{toast.message}</span>
            <button
              onClick={() => removeToast(toast.id)}
              className='text-sm font-semibold text-slate-600 hover:text-slate-800 dark:text-slate-200 dark:hover:text-slate-50'
              aria-label='Dismiss notification'
            >
              ×
            </button>
          </div>
        ))}
      </div>
      <div className='fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4'>
        <div className='bg-white dark:bg-slate-800 rounded-lg w-full max-w-6xl max-h-[90vh] overflow-hidden'>
          <div className='p-6 border-b border-slate-200 dark:border-slate-600'>
            <div className='flex justify-between items-center'>
              <h2 className='text-2xl font-bold text-slate-800 dark:text-slate-100'>
                Admin Interface
              </h2>
              <button
                onClick={onClose}
                className='text-slate-500 hover:text-slate-700 dark:text-slate-400 dark:hover:text-slate-200'
              >
                <svg
                  className='w-6 h-6'
                  fill='none'
                  stroke='currentColor'
                  viewBox='0 0 24 24'
                >
                  <path
                    strokeLinecap='round'
                    strokeLinejoin='round'
                    strokeWidth={2}
                    d='M6 18L18 6M6 6l12 12'
                  />
                </svg>
              </button>
            </div>
          </div>

          <div className='p-6 overflow-y-auto max-h-[calc(90vh-120px)]'>
            {error && (
              <div className='bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4'>
                {error}
              </div>
            )}

            {loading ? (
              <div className='text-center py-8'>
                <div className='animate-spin rounded-full h-8 w-8 border-b-2 border-indigo-600 mx-auto'></div>
                <p className='mt-2 text-slate-600 dark:text-slate-300'>
                  Loading users...
                </p>
              </div>
            ) : (
              <div className='space-y-4'>
                <div className='flex justify-between items-center'>
                  <h3 className='text-lg font-semibold text-slate-800 dark:text-slate-100'>
                    User Management ({visibleUsersLabel})
                  </h3>
                  <button
                    onClick={loadUsers}
                    className='bg-indigo-600 hover:bg-indigo-700 text-white px-4 py-2 rounded-md text-sm'
                  >
                    Refresh
                  </button>
                </div>

                <div className='overflow-x-auto'>
                  <div className='flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between mb-4'>
                    <div className='w-full sm:w-72'>
                      <label htmlFor='admin-search' className='sr-only'>
                        Search users
                      </label>
                      <input
                        id='admin-search'
                        type='search'
                        value={searchTerm}
                        onChange={e => setSearchTerm(e.target.value)}
                        placeholder='Search by username or email'
                        className='w-full px-3 py-2 border border-slate-300 rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 text-sm bg-white dark:bg-slate-700 dark:border-slate-600 dark:text-slate-100'
                      />
                    </div>
                    <div className='flex items-center gap-2'>
                      <label
                        htmlFor='admin-sort'
                        className='text-sm text-slate-600 dark:text-slate-300'
                      >
                        Sort by
                      </label>
                      <select
                        id='admin-sort'
                        value={sortField}
                        onChange={e =>
                          setSortField(
                            e.target.value as
                              | 'createdAt'
                              | 'status'
                              | 'role'
                              | 'username'
                          )
                        }
                        className='px-3 py-2 border border-slate-300 rounded-md text-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 bg-white dark:bg-slate-700 dark:border-slate-600 dark:text-slate-100'
                      >
                        <option value='createdAt'>Created Date</option>
                        <option value='status'>Status</option>
                        <option value='role'>Role</option>
                        <option value='username'>Name</option>
                      </select>
                      <button
                        type='button'
                        onClick={() =>
                          setSortDirection(prev =>
                            prev === 'asc' ? 'desc' : 'asc'
                          )
                        }
                        className='px-3 py-2 text-sm border border-slate-300 rounded-md bg-white hover:bg-slate-100 dark:bg-slate-700 dark:border-slate-600 dark:text-slate-100 dark:hover:bg-slate-600'
                        aria-label={`Toggle sort direction. Currently ${
                          sortDirection === 'asc' ? 'ascending' : 'descending'
                        }`}
                      >
                        {sortDirection === 'asc' ? 'Asc ↑' : 'Desc ↓'}
                      </button>
                    </div>
                  </div>
                  {filteredUsers.length === 0 ? (
                    <p className='text-center text-sm text-slate-600 dark:text-slate-300 py-6'>
                      No users match the current filters.
                    </p>
                  ) : (
                    <table className='min-w-full bg-white dark:bg-slate-700 rounded-lg overflow-hidden'>
                      <thead className='bg-slate-50 dark:bg-slate-600'>
                        <tr>
                          <th className='px-4 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-300 uppercase tracking-wider'>
                            User
                          </th>
                          <th className='px-4 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-300 uppercase tracking-wider'>
                            Email
                          </th>
                          <th className='px-4 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-300 uppercase tracking-wider'>
                            Status
                          </th>
                          <th className='px-4 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-300 uppercase tracking-wider'>
                            Role
                          </th>
                          <th className='px-4 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-300 uppercase tracking-wider'>
                            Created
                          </th>
                          <th className='px-4 py-3 text-left text-xs font-medium text-slate-500 dark:text-slate-300 uppercase tracking-wider'>
                            Actions
                          </th>
                        </tr>
                      </thead>
                      <tbody className='divide-y divide-slate-200 dark:divide-slate-600'>
                        {filteredUsers.map(user => (
                          <tr
                            key={user._id}
                            className='hover:bg-slate-50 dark:hover:bg-slate-600'
                          >
                            <td className='px-4 py-4'>
                              <div className='flex items-center'>
                                {user.avatar ? (
                                  <img
                                    src={user.avatar}
                                    alt={user.username}
                                    className='w-8 h-8 rounded-full mr-3'
                                  />
                                ) : (
                                  <div className='w-8 h-8 bg-indigo-600 rounded-full flex items-center justify-center mr-3'>
                                    <span className='text-white text-sm font-medium'>
                                      {user.username.charAt(0).toUpperCase()}
                                    </span>
                                  </div>
                                )}
                                <div>
                                  <div className='text-sm font-medium text-slate-900 dark:text-slate-100'>
                                    {user.username}
                                  </div>
                                  <div className='text-sm text-slate-500 dark:text-slate-400'>
                                    ID: {user._id.slice(-8)}
                                  </div>
                                </div>
                              </div>
                            </td>
                            <td className='px-4 py-4 text-sm text-slate-900 dark:text-slate-100'>
                              {user.email}
                              {user.emailVerified && (
                                <span className='ml-2 text-green-600'>✓</span>
                              )}
                            </td>
                            <td className='px-4 py-4'>
                              <span
                                className={`inline-flex px-2 py-1 text-xs font-semibold rounded-full ${getStatusColor(user.status)}`}
                              >
                                {user.status || 'Unknown'}
                              </span>
                            </td>
                            <td className='px-4 py-4'>
                              <span
                                className={`inline-flex px-2 py-1 text-xs font-semibold rounded-full ${getRoleColor(user.role)}`}
                              >
                                {user.role || 'USER'}
                              </span>
                            </td>
                            <td className='px-4 py-4 text-sm text-slate-500 dark:text-slate-400'>
                              {user.createdAt
                                ? new Date(user.createdAt).toLocaleDateString()
                                : 'Unknown'}
                            </td>
                            <td className='px-4 py-4'>
                              <div className='flex space-x-2'>
                                {user.status === AccountStatus.ACTIVE ? (
                                  <button
                                    onClick={() => handleSuspendUser(user)}
                                    className='text-red-600 hover:text-red-800 text-xs'
                                    disabled={user._id === currentUser?._id}
                                  >
                                    Suspend
                                  </button>
                                ) : (
                                  <button
                                    onClick={() => handleActivateUser(user)}
                                    className='text-green-600 hover:text-green-800 text-xs'
                                  >
                                    Activate
                                  </button>
                                )}

                                {user.password && (
                                  <button
                                    onClick={() => setSelectedUser(user)}
                                    className='text-blue-600 hover:text-blue-800 text-xs'
                                  >
                                    Change Password
                                  </button>
                                )}

                                <button
                                  onClick={() => confirmDeleteUser(user)}
                                  className='text-red-600 hover:text-red-800 text-xs'
                                  disabled={
                                    user._id === currentUser?._id ||
                                    user.role === UserRole.ADMIN
                                  }
                                >
                                  Delete
                                </button>
                              </div>
                            </td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  )}
                </div>
              </div>
            )}
          </div>

          {/* Password Change Modal */}
          {selectedUser && (
            <div className='fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-60'>
              <div className='bg-white dark:bg-slate-800 rounded-lg p-6 max-w-md w-full mx-4'>
                <h3 className='text-lg font-semibold text-slate-800 dark:text-slate-100 mb-4'>
                  Change Password for {selectedUser.username}
                </h3>
                <div className='space-y-4'>
                  <div>
                    <label className='block text-sm font-medium text-slate-700 dark:text-slate-300 mb-2'>
                      New Password
                    </label>
                    <input
                      type='password'
                      value={newPassword}
                      onChange={e => setNewPassword(e.target.value)}
                      className='w-full px-3 py-2 border border-slate-300 rounded-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 dark:bg-slate-700 dark:border-slate-600 dark:text-white'
                      placeholder='Enter new password (min 6 characters)'
                    />
                  </div>
                  <div className='flex space-x-3'>
                    <button
                      onClick={() => handleChangePassword(selectedUser._id)}
                      className='flex-1 bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-2 px-4 rounded-md'
                    >
                      Change Password
                    </button>
                    <button
                      onClick={() => {
                        setSelectedUser(null);
                        setNewPassword('');
                      }}
                      className='flex-1 bg-slate-300 hover:bg-slate-400 text-slate-700 font-medium py-2 px-4 rounded-md'
                    >
                      Cancel
                    </button>
                  </div>
                </div>
              </div>
            </div>
          )}
          {userPendingDeletion && (
            <div className='fixed inset-0 bg-black bg-opacity-40 flex items-center justify-center z-[65] p-4'>
              <div className='bg-white dark:bg-slate-800 rounded-lg p-6 max-w-md w-full'>
                <h3 className='text-lg font-semibold text-slate-800 dark:text-slate-100 mb-2'>
                  Delete {userPendingDeletion.username}?
                </h3>
                <p className='text-sm text-slate-600 dark:text-slate-300 mb-4'>
                  This action cannot be undone. The user's data will be
                  permanently removed.
                </p>
                <div className='flex space-x-3'>
                  <button
                    onClick={executeDeleteUser}
                    disabled={isDeletingUser}
                    className='flex-1 bg-red-600 hover:bg-red-700 text-white font-medium py-2 px-4 rounded-md disabled:opacity-50'
                  >
                    {isDeletingUser ? 'Deleting...' : 'Delete'}
                  </button>
                  <button
                    onClick={closeDeleteDialog}
                    disabled={isDeletingUser}
                    className='flex-1 bg-slate-200 hover:bg-slate-300 text-slate-700 font-medium py-2 px-4 rounded-md dark:bg-slate-700 dark:text-slate-200 dark:hover:bg-slate-600 disabled:opacity-50'
                  >
                    Cancel
                  </button>
                </div>
              </div>
            </div>
          )}
        </div>
      </div>
    </>
  );
};

export default AdminInterface;
