import { describe, test } from 'node:test';
import assert from 'node:assert/strict';
import { buildSeededPermissionNamesForRole } from '@/db/seeders/20200430130760-user-roles';
import { ROLE_NAMES, type RoleName } from '@/shared/constants/roles';
import { FEATURE_PERMISSIONS } from '@/shared/constants/product-permissions';

function granted(role: RoleName): readonly string[] {
  return buildSeededPermissionNamesForRole(role);
}

describe('user-role seed permission contract', () => {
  test('parent communication is seeded for system admins plus office manager, teacher, and guardian', () => {
    const parentCommRoles = Object.values(ROLE_NAMES).filter((role) =>
      granted(role).includes(FEATURE_PERMISSIONS.READ_PARENT_COMM),
    );

    assert.deepEqual(parentCommRoles, [
      ROLE_NAMES.SYSTEM_ADMIN,
      ROLE_NAMES.OFFICE_MANAGER,
      ROLE_NAMES.TEACHER,
      ROLE_NAMES.GUARDIAN,
    ]);
  });

  test('registrar has audit/report reads without parent communication', () => {
    const permissions = granted(ROLE_NAMES.REGISTRAR);

    assert.equal(permissions.includes(FEATURE_PERMISSIONS.READ_PARENT_COMM), false);
    assert.equal(permissions.includes(FEATURE_PERMISSIONS.READ_POLICY_ACKNOWLEDGMENT_REPORTS), true);
    assert.equal(permissions.includes(FEATURE_PERMISSIONS.READ_STAFF_ATTENDANCE_REPORTS), true);
  });

  test('internal alerts read/manage grants match tenant leadership and staff expectations', () => {
    const internalAlertReaders = Object.values(ROLE_NAMES).filter((role) =>
      granted(role).includes(FEATURE_PERMISSIONS.READ_INTERNAL_COMM),
    );
    const internalAlertManagers = Object.values(ROLE_NAMES).filter((role) =>
      granted(role).includes(FEATURE_PERMISSIONS.MANAGE_INTERNAL_COMM),
    );

    assert.deepEqual(internalAlertReaders, [
      ROLE_NAMES.SYSTEM_ADMIN,
      ROLE_NAMES.OWNER,
      ROLE_NAMES.SUPERINTENDENT,
      ROLE_NAMES.PRINCIPAL,
      ROLE_NAMES.REGISTRAR,
      ROLE_NAMES.DIRECTOR,
      ROLE_NAMES.OFFICE_MANAGER,
      ROLE_NAMES.TEACHER,
      ROLE_NAMES.SUPPORT_STAFF,
    ]);
    assert.deepEqual(internalAlertManagers, [
      ROLE_NAMES.SYSTEM_ADMIN,
      ROLE_NAMES.OWNER,
      ROLE_NAMES.SUPERINTENDENT,
      ROLE_NAMES.PRINCIPAL,
      ROLE_NAMES.DIRECTOR,
    ]);
  });

  test('leadership full-access grants do not inherit personal workflow permissions', () => {
    const ownerPermissions = granted(ROLE_NAMES.OWNER);
    const principalPermissions = granted(ROLE_NAMES.PRINCIPAL);
    const directorPermissions = granted(ROLE_NAMES.DIRECTOR);
    const systemAdminPermissions = granted(ROLE_NAMES.SYSTEM_ADMIN);

    assert.equal(ownerPermissions.includes(FEATURE_PERMISSIONS.READ_PARENT_COMM), false);
    assert.equal(ownerPermissions.includes(FEATURE_PERMISSIONS.ACK_POLICY), false);
    assert.equal(ownerPermissions.includes(FEATURE_PERMISSIONS.ZONE_CHECKIN), false);
    assert.equal(principalPermissions.includes(FEATURE_PERMISSIONS.READ_PARENT_COMM), false);
    assert.equal(principalPermissions.includes(FEATURE_PERMISSIONS.ACK_POLICY), false);
    assert.equal(principalPermissions.includes(FEATURE_PERMISSIONS.ZONE_CHECKIN), false);
    assert.equal(directorPermissions.includes(FEATURE_PERMISSIONS.READ_PARENT_COMM), false);
    assert.equal(directorPermissions.includes(FEATURE_PERMISSIONS.ACK_POLICY), true);
    assert.equal(directorPermissions.includes(FEATURE_PERMISSIONS.ZONE_CHECKIN), true);
    assert.equal(systemAdminPermissions.includes(FEATURE_PERMISSIONS.READ_PARENT_COMM), true);
    assert.equal(systemAdminPermissions.includes(FEATURE_PERMISSIONS.ACK_POLICY), true);
    assert.equal(systemAdminPermissions.includes(FEATURE_PERMISSIONS.ZONE_CHECKIN), true);
  });

  test('attendance fill grants match operational writers', () => {
    const attendanceFillRoles = Object.values(ROLE_NAMES).filter((role) =>
      granted(role).includes(FEATURE_PERMISSIONS.FILL_ATTENDANCE),
    );

    assert.deepEqual(attendanceFillRoles, [
      ROLE_NAMES.SYSTEM_ADMIN,
      ROLE_NAMES.OWNER,
      ROLE_NAMES.SUPERINTENDENT,
      ROLE_NAMES.PRINCIPAL,
      ROLE_NAMES.DIRECTOR,
      ROLE_NAMES.OFFICE_MANAGER,
      ROLE_NAMES.TEACHER,
    ]);
  });
});
