import { render, screen, fireEvent } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';

vi.mock('@inertiajs/react', async () => {
  const actual = await vi.importActual('@inertiajs/react');
  return {
    ...actual,
    Head: ({ title }: { title: string }) => <title>{title}</title>,
    usePage: vi.fn(() => ({
      url: '/admin/users',
      props: {
        auth: { user: { id: 1, name: 'Admin', email: 'admin@test.com', is_admin: true, admin_role: 'admin' } },
        features: {
          billing: false,
          socialAuth: false,
          emailVerification: true,
          apiTokens: true,
          userSettings: true,
          notifications: false,
          onboarding: false,
          apiDocs: false,
          twoFactor: false,
          webhooks: false,
          admin: true,
        },
      },
    })),
    Link: ({
      children,
      href,
      ...rest
    }: {
      children: React.ReactNode;
      href: string;
      className?: string;
    }) => (
      <a href={href} {...rest}>
        {children}
      </a>
    ),
    router: {
      patch: vi.fn(),
      delete: vi.fn(),
      post: vi.fn(),
      get: vi.fn(),
      on: vi.fn(() => vi.fn()),
    },
  };
});

vi.mock('@/Components/theme/use-theme', () => ({
  useTheme: vi.fn(() => ({ theme: 'system', setTheme: vi.fn(), resolvedTheme: 'light' })),
}));

vi.mock('sonner', () => ({
  toast: { success: vi.fn(), error: vi.fn() },
}));

import { usePage } from '@inertiajs/react';

import AdminUsersIndex from './Index';

const makePagination = <T,>(data: T[]) => ({
  data,
  current_page: 1,
  per_page: 15,
  total: data.length,
  last_page: 1,
  from: data.length > 0 ? 1 : 0,
  to: data.length,
  links: [],
});

const makeUser = (overrides = {}) => ({
  id: 2,
  name: 'Alice Example',
  email: 'alice@example.com',
  is_admin: false,
  email_verified_at: '2026-01-01T00:00:00Z',
  last_login_at: '2026-03-01T10:00:00Z',
  created_at: '2026-01-01T00:00:00Z',
  deleted_at: null,
  tokens_count: 0,
  lead_score: null,
  lead_score_tier: null,
  pql_qualified_at: null,
  ...overrides,
});

describe('AdminUsersIndex', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('renders the Users heading', () => {
    render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
    expect(screen.getByRole('heading', { name: 'Users', level: 1 })).toBeInTheDocument();
  });

  it('renders a user row with name and email', () => {
    render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
    expect(screen.getByText('Alice Example')).toBeInTheDocument();
    expect(screen.getByText('alice@example.com')).toBeInTheDocument();
  });

  it('shows Admin badge for admin users', () => {
    render(<AdminUsersIndex users={makePagination([makeUser({ is_admin: true })])} filters={{}} />);
    // Multiple "Admin" occurrences expected: layout badge + table badge
    const adminBadges = screen.getAllByText('Admin');
    expect(adminBadges.length).toBeGreaterThanOrEqual(1);
  });

  it('shows User badge for non-admin users', () => {
    render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
    expect(screen.getByText('User')).toBeInTheDocument();
  });

  it('shows Active badge for active users', () => {
    render(
      <AdminUsersIndex users={makePagination([makeUser({ deleted_at: null })])} filters={{}} />,
    );
    expect(screen.getByText('Active')).toBeInTheDocument();
  });

  it('shows Deactivated badge for deleted users', () => {
    render(
      <AdminUsersIndex
        users={makePagination([makeUser({ deleted_at: '2026-02-01T00:00:00Z', id: 99 })])}
        filters={{}}
      />,
    );
    expect(screen.getByText('Deactivated')).toBeInTheDocument();
  });

  it('shows Verified badge for verified users', () => {
    render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
    // "Verified" appears as both a table header and a badge; use getAllByText
    const verifiedElements = screen.getAllByText('Verified');
    expect(verifiedElements.length).toBeGreaterThanOrEqual(1);
  });

  it('shows empty state when no users exist', () => {
    render(<AdminUsersIndex users={makePagination([])} filters={{}} />);
    expect(screen.getByText('No users found')).toBeInTheDocument();
    expect(
      screen.getByText('User accounts will appear here once people register.'),
    ).toBeInTheDocument();
  });

  it('shows filtered empty state message when search is active', () => {
    render(
      <AdminUsersIndex users={makePagination([])} filters={{ search: 'notfound@example.com' }} />,
    );
    expect(screen.getByText(/No users match your current filters/)).toBeInTheDocument();
  });

  it('renders multiple users', () => {
    const users = [
      makeUser({ id: 2, name: 'Alice', email: 'alice@example.com' }),
      makeUser({ id: 3, name: 'Bob', email: 'bob@example.com' }),
    ];
    render(<AdminUsersIndex users={makePagination(users)} filters={{}} />);
    expect(screen.getByText('Alice')).toBeInTheDocument();
    expect(screen.getByText('Bob')).toBeInTheDocument();
  });

  it('shows Unverified badge for users without email_verified_at', () => {
    render(
      <AdminUsersIndex
        users={makePagination([makeUser({ email_verified_at: null })])}
        filters={{}}
      />,
    );
    expect(screen.getByText('Unverified')).toBeInTheDocument();
  });

  it('renders search input with correct placeholder', () => {
    render(<AdminUsersIndex users={makePagination([])} filters={{}} />);
    expect(
      screen.getByRole('textbox', { name: /Search users by name or email/ }),
    ).toBeInTheDocument();
  });

  it('renders Export button', () => {
    render(<AdminUsersIndex users={makePagination([])} filters={{}} />);
    expect(screen.getByRole('link', { name: /Export/ })).toBeInTheDocument();
  });

  it('shows selection toolbar with user count when a row is selected', () => {
    render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
    const checkbox = screen.getByRole('checkbox', { name: /Select Alice Example/ });
    fireEvent.click(checkbox);
    expect(screen.getByText('1 user selected')).toBeInTheDocument();
  });

  it('shows "Deactivate Selected" button in toolbar when users are selected', () => {
    render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
    fireEvent.click(screen.getByRole('checkbox', { name: /Select Alice Example/ }));
    expect(screen.getByRole('button', { name: /Deactivate Selected/ })).toBeInTheDocument();
  });

  it('clears selection when Clear button is clicked', () => {
    render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
    fireEvent.click(screen.getByRole('checkbox', { name: /Select Alice Example/ }));
    expect(screen.getByText('1 user selected')).toBeInTheDocument();
    fireEvent.click(screen.getByRole('button', { name: /Clear selection/ }));
    expect(screen.queryByText('1 user selected')).not.toBeInTheDocument();
  });

  it('opens bulk deactivate confirm dialog when Deactivate Selected is clicked', () => {
    render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
    fireEvent.click(screen.getByRole('checkbox', { name: /Select Alice Example/ }));
    fireEvent.click(screen.getByRole('button', { name: /Deactivate Selected/ }));
    expect(screen.getByText('Bulk Deactivate Users')).toBeInTheDocument();
  });

  it('admin user has a disabled checkbox (cannot be bulk-selected)', () => {
    render(
      <AdminUsersIndex
        users={makePagination([makeUser({ id: 10, name: 'Super Admin', is_admin: true })])}
        filters={{}}
      />,
    );
    const disabledCheckbox = screen.getByRole('checkbox', {
      name: /Cannot select Super Admin/,
    });
    expect(disabledCheckbox).toBeDisabled();
  });

  it('shows action menu button for each user row', () => {
    render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
    expect(screen.getByRole('button', { name: /User actions/ })).toBeInTheDocument();
  });

  it('shows correct count in bulk deactivate confirmation', () => {
    const users = [
      makeUser({ id: 2, name: 'User A', email: 'a@example.com' }),
      makeUser({ id: 3, name: 'User B', email: 'b@example.com' }),
    ];
    render(<AdminUsersIndex users={makePagination(users)} filters={{}} />);
    fireEvent.click(screen.getByRole('checkbox', { name: /Select User A/ }));
    fireEvent.click(screen.getByRole('checkbox', { name: /Select User B/ }));
    expect(screen.getByText('2 users selected')).toBeInTheDocument();
    fireEvent.click(screen.getByRole('button', { name: /Deactivate Selected/ }));
    expect(screen.getByText(/deactivate 2 user\(s\)/i)).toBeInTheDocument();
  });

  describe('viewer role', () => {
    beforeEach(() => {
      vi.mocked(usePage).mockReturnValue({
        url: '/admin/users',
        props: {
          auth: { user: { id: 1, name: 'Viewer', email: 'viewer@test.com', is_admin: true, admin_role: 'viewer' } },
          features: {
            billing: false,
            socialAuth: false,
            emailVerification: true,
            apiTokens: true,
            userSettings: true,
            notifications: false,
            onboarding: false,
            apiDocs: false,
            twoFactor: false,
            webhooks: false,
            admin: true,
          },
        },
      } as unknown as ReturnType<typeof usePage>);
    });

    it('does not show row checkboxes for viewer role', () => {
      render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
      expect(screen.queryByRole('checkbox', { name: /Select Alice Example/ })).not.toBeInTheDocument();
    });

    it('does not show select-all checkbox for viewer role', () => {
      render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
      expect(screen.queryByRole('checkbox', { name: /Select all users/ })).not.toBeInTheDocument();
    });

    it('does not show bulk action bar for viewer role even when selection attempted', () => {
      render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
      expect(screen.queryByText('Deactivate Selected')).not.toBeInTheDocument();
    });

    it('still shows the action menu trigger button for viewer role', () => {
      render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
      // Viewer can still access the dropdown to reach View Details
      expect(screen.getByRole('button', { name: /User actions/ })).toBeInTheDocument();
    });

    it('does not render mutation dropdown items in DOM for viewer role', () => {
      render(<AdminUsersIndex users={makePagination([makeUser()])} filters={{}} />);
      // Open the dropdown — Radix DropdownMenuContent renders into a portal only when open,
      // so asserting item absence while closed is vacuous and would pass even without canMutate guards.
      fireEvent.click(screen.getByRole('button', { name: /User actions/ }));
      // With canMutate=false, mutation items must not appear even with the dropdown open.
      expect(screen.queryByText('Make Admin')).not.toBeInTheDocument();
      expect(screen.queryByText('Remove Admin')).not.toBeInTheDocument();
      expect(screen.queryByText('Deactivate User')).not.toBeInTheDocument();
      expect(screen.queryByText('Impersonate')).not.toBeInTheDocument();
    });
  });
});
