// Feature: divisi-metrics, Property 5: Authentication guard redirects unauthenticated access
// **Validates: Requirements 2.4**

import { describe, it, expect, vi, beforeEach } from 'vitest';
import * as fc from 'fast-check';
import { render } from '@testing-library/react';
import React from 'react';
import { useAuthStore } from '@/lib/stores/auth-store';

// ── Mock next/navigation ────────────────────────────────────────────────────

const mockReplace = vi.fn();
const mockPush = vi.fn();

vi.mock('next/navigation', () => ({
  useRouter: () => ({
    replace: mockReplace,
    push: mockPush,
    back: vi.fn(),
    forward: vi.fn(),
    refresh: vi.fn(),
    prefetch: vi.fn(),
  }),
  usePathname: () => '/overview',
}));

// ── Import AuthGuard after mocks are set up ─────────────────────────────────

import AuthGuard from '@/components/auth/AuthGuard';

// ── Dashboard routes ────────────────────────────────────────────────────────

const DASHBOARD_ROUTES = [
  '/overview',
  '/works',
  '/composers',
  '/payees',
  '/contracts',
  '/income',
  '/transactions',
  '/costs',
  '/statements',
  '/suspense',
  '/audit',
] as const;

describe('Property 5: Authentication guard redirects unauthenticated access', () => {
  beforeEach(() => {
    // Reset auth store to unauthenticated state
    useAuthStore.setState({
      user: null,
      role: null,
      isAuthenticated: false,
    });
    mockReplace.mockClear();
    mockPush.mockClear();
  });

  it('unauthenticated access to any dashboard route triggers redirect to /login', () => {
    fc.assert(
      fc.property(
        fc.constantFrom(...DASHBOARD_ROUTES),
        (route) => {
          mockReplace.mockClear();

          // Ensure store is unauthenticated
          useAuthStore.setState({
            user: null,
            role: null,
            isAuthenticated: false,
          });

          const { unmount } = render(
            React.createElement(AuthGuard, null,
              React.createElement('div', { 'data-testid': 'protected' }, `Content for ${route}`)
            )
          );

          // AuthGuard should call router.replace('/login')
          expect(mockReplace).toHaveBeenCalledWith('/login');

          unmount();
        },
      ),
      { numRuns: 100 },
    );
  });

  it('invalid or corrupted role values trigger redirect to /login', () => {
    const invalidRoles = [
      '',
      'admin',
      'SUPER_ADMIN',
      'viewer',
      'publisher_admin',
      'unknown_role',
      'null',
      'undefined',
      '123',
      'Super Admin',
    ];

    fc.assert(
      fc.property(
        fc.constantFrom(...invalidRoles),
        (invalidRole) => {
          mockReplace.mockClear();

          // Set an invalid role in the store
          useAuthStore.setState({
            user: null,
            role: invalidRole as unknown as null,
            isAuthenticated: true,
          });

          const { unmount } = render(
            React.createElement(AuthGuard, null,
              React.createElement('div', { 'data-testid': 'protected' }, 'Protected content')
            )
          );

          // AuthGuard should detect invalid role and redirect
          expect(mockReplace).toHaveBeenCalledWith('/login');

          unmount();
        },
      ),
      { numRuns: 100 },
    );
  });

  it('unauthenticated AuthGuard does not render children', () => {
    fc.assert(
      fc.property(
        fc.constantFrom(...DASHBOARD_ROUTES),
        (route) => {
          // Ensure store is unauthenticated
          useAuthStore.setState({
            user: null,
            role: null,
            isAuthenticated: false,
          });

          const { queryByTestId, unmount } = render(
            React.createElement(AuthGuard, null,
              React.createElement('div', { 'data-testid': 'protected' }, `Content for ${route}`)
            )
          );

          // Children should NOT be rendered
          expect(queryByTestId('protected')).toBeNull();

          unmount();
        },
      ),
      { numRuns: 100 },
    );
  });
});
