import { test } from 'node:test';
import assert from 'node:assert/strict';
import {
  canManageUserWithRole,
  canDeleteOrganization,
} from '@/services/shared/role-policy';
import { ROLE_NAMES } from '@/shared/constants/roles';
import type { CurrentUser } from '@/db/api/types';

function actor(role: string): CurrentUser {
  return { id: 'actor', app_role: { name: role } };
}

// --- user-management relational constraints (§3.3) ---

test('super_admin can manage every role', () => {
  for (const role of Object.values(ROLE_NAMES)) {
    assert.equal(canManageUserWithRole(actor(ROLE_NAMES.SUPER_ADMIN), role), true);
  }
});

test('system_admin cannot manage super_admin or system_admin', () => {
  const sysAdmin = actor(ROLE_NAMES.SYSTEM_ADMIN);
  assert.equal(canManageUserWithRole(sysAdmin, ROLE_NAMES.SUPER_ADMIN), false);
  assert.equal(canManageUserWithRole(sysAdmin, ROLE_NAMES.SYSTEM_ADMIN), false);
  assert.equal(canManageUserWithRole(sysAdmin, ROLE_NAMES.OWNER), true);
  assert.equal(canManageUserWithRole(sysAdmin, ROLE_NAMES.TEACHER), true);
});

test('superintendent cannot manage owner or another superintendent', () => {
  const sup = actor(ROLE_NAMES.SUPERINTENDENT);
  assert.equal(canManageUserWithRole(sup, ROLE_NAMES.OWNER), false);
  assert.equal(canManageUserWithRole(sup, ROLE_NAMES.SUPERINTENDENT), false);
  assert.equal(canManageUserWithRole(sup, ROLE_NAMES.DIRECTOR), true);
  assert.equal(canManageUserWithRole(sup, ROLE_NAMES.TEACHER), true);
});

test('director manages campus/external roles but not director or above', () => {
  const dir = actor(ROLE_NAMES.DIRECTOR);
  assert.equal(canManageUserWithRole(dir, ROLE_NAMES.DIRECTOR), false);
  assert.equal(canManageUserWithRole(dir, ROLE_NAMES.SUPERINTENDENT), false);
  assert.equal(canManageUserWithRole(dir, ROLE_NAMES.TEACHER), true);
  assert.equal(canManageUserWithRole(dir, ROLE_NAMES.STUDENT), true);
});

test('campus staff (e.g. teacher) cannot manage any user', () => {
  const teacher = actor(ROLE_NAMES.TEACHER);
  for (const role of Object.values(ROLE_NAMES)) {
    assert.equal(canManageUserWithRole(teacher, role), false);
  }
  // ...including a roleless target.
  assert.equal(canManageUserWithRole(teacher, null), false);
});

test('a manager may act on a roleless (null) target', () => {
  assert.equal(canManageUserWithRole(actor(ROLE_NAMES.DIRECTOR), null), true);
});

test('an unauthenticated/roleless actor manages nobody', () => {
  assert.equal(canManageUserWithRole(undefined, ROLE_NAMES.TEACHER), false);
  assert.equal(canManageUserWithRole({ id: 'x' }, ROLE_NAMES.TEACHER), false);
});

// --- organization deletion (§3.3) ---

test('only super_admin / system_admin / owner may delete an organization', () => {
  assert.equal(canDeleteOrganization(actor(ROLE_NAMES.SUPER_ADMIN)), true);
  assert.equal(canDeleteOrganization(actor(ROLE_NAMES.SYSTEM_ADMIN)), true);
  assert.equal(canDeleteOrganization(actor(ROLE_NAMES.OWNER)), true);
  assert.equal(canDeleteOrganization(actor(ROLE_NAMES.SUPERINTENDENT)), false);
  assert.equal(canDeleteOrganization(actor(ROLE_NAMES.DIRECTOR)), false);
  assert.equal(canDeleteOrganization(undefined), false);
});
