/**
 * ADMFE-R15-01 — Render-contract guard: AuditLogs Index
 *
 * Renders with controller-shaped props (snake_case keys, exactly as the PHP
 * controller emits them) and asserts the filter UI elements appear without
 * throwing a TypeError.
 *
 * Historically this crashed because the component destructured the camelCase
 * names `eventTypes` / `adminUsers` while the controller sent `event_types` /
 * `admin_users`.  The test intentionally uses the controller-shaped keys so it
 * stays red until the component is fixed (snake_case destructure).
 */
import { render, screen } from '@testing-library/react';
import { describe, it, expect, vi, beforeEach } from 'vitest';

import type { AdminAuditLogsIndexProps } from '@/types/admin';

// Minimal Inertia mock — provides Link + usePage without a router
vi.mock('@/Components/theme/use-theme', () => ({
  useTheme: vi.fn(() => ({ theme: 'system', setTheme: vi.fn(), resolvedTheme: 'light' })),
}));

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/audit-logs',
      props: {
        auth: { user: { name: 'Admin', email: 'admin@test.com' } },
        features: {
          billing: false,
          socialAuth: false,
          emailVerification: true,
          apiTokens: true,
          userSettings: true,
          notifications: false,
        },
      },
    })),
    Link: ({
      children,
      href,
      ...rest
    }: {
      children: React.ReactNode;
      href: string;
      className?: string;
    }) => (
      <a href={href} {...rest}>
        {children}
      </a>
    ),
  };
});

// Import the component AFTER mocks are established
import AdminAuditLogsIndex from './Index';

// Controller-shaped paginated stub (exactly what PHP serializes)
const paginatedLogs = {
  data: [
    {
      id: 1,
      action: 'admin.login',
      event: undefined,
      user_name: 'Alice',
      user_email: 'alice@test.com',
      user_id: 1,
      ip: '1.2.3.4',
      user_agent: 'Mozilla',
      metadata: null,
      created_at: '2026-01-01T00:00:00.000Z',
    },
  ],
  current_page: 1,
  last_page: 1,
  per_page: 50,
  total: 1,
  from: 1,
  to: 1,
  next_page_url: null,
  prev_page_url: null,
  links: [],
};

// Controller sends snake_case prop names
const defaultProps: AdminAuditLogsIndexProps = {
  logs: paginatedLogs as AdminAuditLogsIndexProps['logs'],
  event_types: ['admin.login', 'user.created'],
  admin_users: [{ id: 1, name: 'Op' }],
  filters: {},
  impersonation_count: 0,
};

describe('AdminAuditLogsIndex — ADMFE-R15-01 render-contract guard', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });

  it('renders without crashing when given controller-shaped (snake_case) props', () => {
    // Before the fix, this throws: "TypeError: eventTypes.map is not a function"
    expect(() => render(<AdminAuditLogsIndex {...defaultProps} />)).not.toThrow();
  });

  it('renders event type filter options from event_types prop', () => {
    render(<AdminAuditLogsIndex {...defaultProps} />);
    // The event_types array must drive the filter dropdown
    // Both event type options should be present in the DOM (in the select content)
    // We look for the visible "All Events" option which always renders
    expect(screen.getByText('All Events')).toBeInTheDocument();
  });

  it('renders admin user filter select from admin_users prop', () => {
    render(<AdminAuditLogsIndex {...defaultProps} />);
    // The "All admins" trigger label appears when admin_users is non-empty.
    // Radix Select renders option content in a portal — check the trigger label only.
    expect(screen.getByText('All admins')).toBeInTheDocument();
  });

  it('renders empty admin user filter select gracefully when admin_users is empty', () => {
    render(<AdminAuditLogsIndex {...defaultProps} admin_users={[]} />);
    // When no admin users, the select should not render (guarded by adminUsers.length > 0)
    expect(screen.queryByText('All admins')).not.toBeInTheDocument();
  });

  it('renders impersonation count when non-zero', () => {
    render(<AdminAuditLogsIndex {...defaultProps} impersonation_count={3} />);
    expect(screen.getByText(/3 impersonation/)).toBeInTheDocument();
  });

  it('does not render impersonation count banner when count is zero', () => {
    render(<AdminAuditLogsIndex {...defaultProps} impersonation_count={0} />);
    // The banner text starts with "{count} impersonation session(s)" — check for
    // the specific count pattern, NOT /impersonation/i which matches the subtitle.
    expect(screen.queryByText(/\d+ impersonation session/i)).not.toBeInTheDocument();
  });
});
