import '@testing-library/jest-dom';

import userEvent from '@testing-library/user-event';

import { render, screen } from 'src/test-utils';

import useRolesPermissions from '../hooks/useRolesPermissions';
import { type RoleListItem, RoleState, RoleType } from '../types';

import RolesAndPermissionsRow from './RolesAndPermissionsRow';

jest.mock('../hooks/useRolesPermissions');
jest.mock('@material-hu/components/composed-components/MenuList', () => ({
  __esModule: true,
  default: ({
    options,
  }: {
    options: { title: string; onClick: () => void }[];
  }) => (
    <ul data-testid="menu-options">
      {options.map(option => (
        <li key={option.title}>
          <button
            type="button"
            onClick={option.onClick}
          >
            {option.title}
          </button>
        </li>
      ))}
    </ul>
  ),
}));

const mockNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useNavigate: () => mockNavigate,
}));

const mockedUseRolesPermissions = useRolesPermissions as jest.MockedFunction<
  typeof useRolesPermissions
>;

const ACTIVE_CUSTOM_ROLE: RoleListItem = {
  id: '42',
  name: 'Editor',
  description: 'Edits content',
  state: RoleState.ACTIVE,
  type: RoleType.CUSTOM,
  userCount: 3,
  updatedAt: '2026-01-01T00:00:00Z',
};

const renderRow = (role: RoleListItem = ACTIVE_CUSTOM_ROLE) =>
  render(
    <table>
      <tbody>
        <RolesAndPermissionsRow
          role={role}
          onDelete={jest.fn()}
          onViewDetail={jest.fn()}
        />
      </tbody>
    </table>,
  );

const setPermissions = (
  perms: Partial<ReturnType<typeof useRolesPermissions>>,
) => {
  mockedUseRolesPermissions.mockReturnValue({
    canManageRoles: false,
    canDefineRoles: false,
    canUpdateRolesAssignment: false,
    canManageOrDefineRoles: false,
    onlyCanAssignUsersActiveRole: false,
    ...perms,
  });
};

describe('RolesAndPermissionsRow — menu permutations', () => {
  beforeEach(() => {
    mockNavigate.mockReset();
  });

  it('shows Ver detalle + Editar + Eliminar for MANAGE_ROLES on a CUSTOM active role', () => {
    setPermissions({
      canManageRoles: true,
      canManageOrDefineRoles: true,
    });
    renderRow();
    const items = screen.getAllByRole('listitem').map(li => li.textContent);
    expect(items).toEqual([
      'role_details.view',
      'GENERAL:EDIT',
      'GENERAL:DELETE',
    ]);
  });

  it('shows Ver detalle + Editar + Eliminar for DEFINE_ROLES only on a CUSTOM active role', () => {
    setPermissions({
      canDefineRoles: true,
      canManageOrDefineRoles: true,
    });
    renderRow();
    const items = screen.getAllByRole('listitem').map(li => li.textContent);
    expect(items).toEqual([
      'role_details.view',
      'GENERAL:EDIT',
      'GENERAL:DELETE',
    ]);
  });

  it('renames Editar → Asignar miembros for UPDATE_ROLES_ASSIGNMENT only', () => {
    setPermissions({
      canUpdateRolesAssignment: true,
      onlyCanAssignUsersActiveRole: true,
    });
    renderRow();
    const items = screen.getAllByRole('listitem').map(li => li.textContent);
    expect(items).toEqual([
      'role_details.view',
      'table.actions.assign_members',
    ]);
    expect(items).not.toContain('GENERAL:EDIT');
    expect(items).not.toContain('GENERAL:DELETE');
  });

  it('navigates to ?step=assignment when "Asignar miembros" is clicked', async () => {
    setPermissions({
      canUpdateRolesAssignment: true,
      onlyCanAssignUsersActiveRole: true,
    });
    renderRow();
    await userEvent.click(
      screen.getByRole('button', { name: 'table.actions.assign_members' }),
    );
    expect(mockNavigate).toHaveBeenCalledTimes(1);
    expect(mockNavigate).toHaveBeenCalledWith(
      expect.stringContaining('step=assignment'),
    );
  });

  it('hides "Asignar miembros" on draft rows for UPDATE_ROLES_ASSIGNMENT only', () => {
    setPermissions({
      canUpdateRolesAssignment: true,
      onlyCanAssignUsersActiveRole: true,
    });
    renderRow({ ...ACTIVE_CUSTOM_ROLE, state: RoleState.DRAFT });
    const items = screen.getAllByRole('listitem').map(li => li.textContent);
    expect(items).not.toContain('table.actions.assign_members');
    expect(items).not.toContain('role_details.view');
    expect(items).not.toContain('GENERAL:DELETE');
  });

  it('navigates without step=assignment when standard Editar is clicked', async () => {
    setPermissions({
      canManageRoles: true,
      canManageOrDefineRoles: true,
    });
    renderRow();
    await userEvent.click(screen.getByRole('button', { name: 'GENERAL:EDIT' }));
    expect(mockNavigate).toHaveBeenCalledTimes(1);
    expect(mockNavigate).toHaveBeenCalledWith(
      expect.not.stringContaining('step='),
    );
  });

  it('hides Eliminar for predefined (non-CUSTOM) roles even with MANAGE_ROLES', () => {
    setPermissions({
      canManageRoles: true,
      canManageOrDefineRoles: true,
    });
    renderRow({ ...ACTIVE_CUSTOM_ROLE, type: RoleType.ADMIN });
    const items = screen.getAllByRole('listitem').map(li => li.textContent);
    expect(items).not.toContain('GENERAL:DELETE');
  });

  it('hides Ver detalle for non-active roles', () => {
    setPermissions({
      canManageRoles: true,
      canManageOrDefineRoles: true,
    });
    renderRow({ ...ACTIVE_CUSTOM_ROLE, state: RoleState.DRAFT });
    const items = screen.getAllByRole('listitem').map(li => li.textContent);
    expect(items).not.toContain('role_details.view');
  });
});
