import React from 'react';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { jest } from '@jest/globals';
import ActionForPermission from './ActionForPermission';
import '@testing-library/jest-dom';

describe('ActionForPermission Component', () => {
  
  const mockHandleModifyPermissions = jest.fn();

  const mockUserData = {
    id: 1,
    name: 'John Doe',
    role: 'Admin',
    email: 'john@example.com'
  };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  // Test 1: Component renders without crashing
  test('renders action button', () => {
    render(
      <ActionForPermission
        handleModifyPermissions={mockHandleModifyPermissions}
        userData={mockUserData}
      />
    );
    const button = screen.getByRole('button');
    expect(button).toBeInTheDocument();
  });

  // Test 2: Popover opens on button click
  test('opens popover on button click', async () => {
    render(
      <ActionForPermission
        handleModifyPermissions={mockHandleModifyPermissions}
        userData={mockUserData}
      />
    );
    const button = screen.getByRole('button');
    fireEvent.click(button);
    
    await waitFor(() => {
      expect(screen.getByText('Edit')).toBeInTheDocument();
    });
  });

  // Test 3: Edit option is available
  test('displays Edit option in menu', async () => {
    render(
      <ActionForPermission
        handleModifyPermissions={mockHandleModifyPermissions}
        userData={mockUserData}
      />
    );
    const button = screen.getByRole('button');
    fireEvent.click(button);
    
    await waitFor(() => {
      expect(screen.getByText('Edit')).toBeInTheDocument();
    });
  });

  // Test 4: Delete option is available
  test('displays Delete option in menu', async () => {
    render(
      <ActionForPermission
        handleModifyPermissions={mockHandleModifyPermissions}
        userData={mockUserData}
      />
    );
    const button = screen.getByRole('button');
    fireEvent.click(button);
    
    await waitFor(() => {
      expect(screen.getByText('Delete')).toBeInTheDocument();
    });
  });

  // Test 5: Edit callback is called
  test('calls handleModifyPermissions on Edit click', async () => {
    render(
      <ActionForPermission
        handleModifyPermissions={mockHandleModifyPermissions}
        userData={mockUserData}
      />
    );
    const button = screen.getByRole('button');
    fireEvent.click(button);
    
    await waitFor(() => {
      const editButton = screen.getByText('Edit');
      fireEvent.click(editButton);
    });
    
    expect(mockHandleModifyPermissions).toHaveBeenCalled();
  });

  // Test 6: Delete callback is called
  test('calls handleModifyPermissions on Delete click', async () => {
    render(
      <ActionForPermission
        handleModifyPermissions={mockHandleModifyPermissions}
        userData={mockUserData}
      />
    );
    const button = screen.getByRole('button');
    fireEvent.click(button);
    
    await waitFor(() => {
      const deleteButton = screen.getByText('Delete');
      fireEvent.click(deleteButton);
    });
    
    expect(mockHandleModifyPermissions).toHaveBeenCalled();
  });

  // Test 7: Popover closes after selecting option
  test('closes popover after Edit selection', async () => {
    render(
      <ActionForPermission
        handleModifyPermissions={mockHandleModifyPermissions}
        userData={mockUserData}
      />
    );
    const button = screen.getByRole('button');
    fireEvent.click(button);
    
    await waitFor(() => {
      const editButton = screen.getByText('Edit');
      fireEvent.click(editButton);
    });
  });

  // Test 8: Handles different user data
  test('works with different userData', async () => {
    const differentUser = {
      id: 2,
      name: 'Jane Smith',
      role: 'User',
      email: 'jane@example.com'
    };
    
    render(
      <ActionForPermission
        handleModifyPermissions={mockHandleModifyPermissions}
        userData={differentUser}
      />
    );
    
    const button = screen.getByRole('button');
    expect(button).toBeInTheDocument();
  });

  // Test 9: handleModifyPermissions not called on initial render
  test('does not call handleModifyPermissions on render', () => {
    render(
      <ActionForPermission
        handleModifyPermissions={mockHandleModifyPermissions}
        userData={mockUserData}
      />
    );
    
    expect(mockHandleModifyPermissions).not.toHaveBeenCalled();
  });

  // Test 10: Multiple opens and closes work
  test('can open and close popover multiple times', async () => {
    render(
      <ActionForPermission
        handleModifyPermissions={mockHandleModifyPermissions}
        userData={mockUserData}
      />
    );
    
    const button = screen.getByRole('button');
    
    // First open
    fireEvent.click(button);
    await waitFor(() => {
      expect(screen.getByText('Edit')).toBeInTheDocument();
    });
    
    // Close by clicking backdrop or clicking outside (using Escape key or outside click)
    fireEvent.keyDown(document, { key: 'Escape' });
    
    // Second open
    fireEvent.click(button);
    await waitFor(() => {
      expect(screen.getByText('Edit')).toBeInTheDocument();
    });
  });
});
