// Feature: client-portal, Property 2: Role-route isolation
// **Validates: Requirements 2.2, 2.3**

import { describe, it, expect } from 'vitest';
import * as fc from 'fast-check';
import { PORTAL_ROUTES, DASHBOARD_ROUTES } from '@/lib/constants/portal-navigation';
import type { UserRole } from '@/lib/constants/navigation';

/**
 * Determines whether a given role is allowed to access a given route.
 *
 * Rules:
 * - Client_Portal users can ONLY access PORTAL_ROUTES
 * - Non-Client_Portal users (Super_Admin, Publisher_Admin, Viewer) can ONLY access DASHBOARD_ROUTES
 */
function isRouteAllowed(role: UserRole, route: string): boolean {
  if (role === 'Client_Portal') {
    return PORTAL_ROUTES.includes(route);
  }
  return DASHBOARD_ROUTES.includes(route);
}

/** All known roles */
const ALL_ROLES: UserRole[] = ['Super_Admin', 'Publisher_Admin', 'Viewer', 'Client_Portal'];

/** Non-Client_Portal roles (dashboard roles) */
const DASHBOARD_ROLES: UserRole[] = ['Super_Admin', 'Publisher_Admin', 'Viewer'];

/** All known routes (portal + dashboard) */
const ALL_ROUTES: string[] = [...PORTAL_ROUTES, ...DASHBOARD_ROUTES];

describe('Property 2: Role-route isolation', () => {
  it('Client_Portal users can access all portal routes', () => {
    fc.assert(
      fc.property(
        fc.constantFrom(...PORTAL_ROUTES),
        (route) => {
          expect(isRouteAllowed('Client_Portal', route)).toBe(true);
        },
      ),
      { numRuns: 100 },
    );
  });

  it('Client_Portal users cannot access any dashboard route', () => {
    fc.assert(
      fc.property(
        fc.constantFrom(...DASHBOARD_ROUTES),
        (route) => {
          expect(isRouteAllowed('Client_Portal', route)).toBe(false);
        },
      ),
      { numRuns: 100 },
    );
  });

  it('non-Client_Portal users can access all dashboard routes', () => {
    fc.assert(
      fc.property(
        fc.constantFrom(...DASHBOARD_ROLES),
        fc.constantFrom(...DASHBOARD_ROUTES),
        (role, route) => {
          expect(isRouteAllowed(role, route)).toBe(true);
        },
      ),
      { numRuns: 100 },
    );
  });

  it('non-Client_Portal users cannot access any portal route', () => {
    fc.assert(
      fc.property(
        fc.constantFrom(...DASHBOARD_ROLES),
        fc.constantFrom(...PORTAL_ROUTES),
        (role, route) => {
          expect(isRouteAllowed(role, route)).toBe(false);
        },
      ),
      { numRuns: 100 },
    );
  });

  it('for any (role, route) pair, access is permitted iff route belongs to that role allowed set', () => {
    fc.assert(
      fc.property(
        fc.constantFrom(...ALL_ROLES),
        fc.constantFrom(...ALL_ROUTES),
        (role, route) => {
          const allowed = isRouteAllowed(role, route);

          if (role === 'Client_Portal') {
            // Client_Portal: allowed only for portal routes
            expect(allowed).toBe(PORTAL_ROUTES.includes(route));
          } else {
            // Dashboard roles: allowed only for dashboard routes
            expect(allowed).toBe(DASHBOARD_ROUTES.includes(route));
          }
        },
      ),
      { numRuns: 100 },
    );
  });

  it('portal routes and dashboard routes are disjoint sets', () => {
    fc.assert(
      fc.property(
        fc.constantFrom(...ALL_ROUTES),
        (route) => {
          const inPortal = PORTAL_ROUTES.includes(route);
          const inDashboard = DASHBOARD_ROUTES.includes(route);

          // A route cannot be in both sets
          expect(inPortal && inDashboard).toBe(false);

          // A route must be in at least one set (since we draw from ALL_ROUTES)
          expect(inPortal || inDashboard).toBe(true);
        },
      ),
      { numRuns: 100 },
    );
  });
});
