import {
  PermissionState,
  RoomPermissionKey,
  RoomPermissionMatrix,
  RoomRole,
  RoomRoleAssignment,
  ROOM_PERMISSION_KEYS
} from '../../../../shared-kernel';
import type { MemberIdentity } from '../models/access-control.model';

export function normalizeName(name: string): string {
  return name.trim().replace(/\s+/g, ' ');
}

export function compareText(firstValue: string, secondValue: string): number {
  return firstValue.localeCompare(secondValue, undefined, { sensitivity: 'base' });
}

export function uniqueStrings(values: readonly string[]): string[] {
  return Array.from(new Set(values.filter((value) => typeof value === 'string' && value.trim().length > 0).map((value) => value.trim())));
}

export function normalizePermissionState(value: unknown): PermissionState {
  return value === 'allow' || value === 'deny' || value === 'inherit' ? value : 'inherit';
}

export function normalizePermissionMatrix(matrix: RoomPermissionMatrix | undefined): RoomPermissionMatrix {
  const normalized: RoomPermissionMatrix = {};

  for (const key of ROOM_PERMISSION_KEYS) {
    const value = normalizePermissionState(matrix?.[key]);

    if (value !== 'inherit') {
      normalized[key] = value;
    }
  }

  return normalized;
}

export function memberIdentityKey(identity: MemberIdentity | null | undefined): string {
  return identity?.oderId?.trim() || identity?.id?.trim() || '';
}

export function matchesIdentity(identity: MemberIdentity | null | undefined, candidate: Pick<RoomRoleAssignment, 'userId' | 'oderId'>): boolean {
  if (!identity) {
    return false;
  }

  return !!(
    (identity.id && (candidate.userId === identity.id || candidate.oderId === identity.id)) ||
    (identity.oderId && (candidate.userId === identity.oderId || candidate.oderId === identity.oderId))
  );
}

export function roleSortAscending(firstRole: RoomRole, secondRole: RoomRole): number {
  if (firstRole.position !== secondRole.position) {
    return firstRole.position - secondRole.position;
  }

  return compareText(firstRole.name, secondRole.name);
}

export function roleSortDescending(firstRole: RoomRole, secondRole: RoomRole): number {
  return roleSortAscending(secondRole, firstRole);
}

export function permissionStateToBoolean(value: PermissionState | undefined, fallbackValue: boolean): boolean {
  if (value === 'allow') {
    return true;
  }

  if (value === 'deny') {
    return false;
  }

  return fallbackValue;
}

export function getRolePermissionState(role: RoomRole | undefined, permission: RoomPermissionKey): PermissionState {
  return normalizePermissionState(role?.permissions?.[permission]);
}

export function buildSystemRole(id: string, name: string, position: number, permissions: RoomPermissionMatrix, color: string): RoomRole {
  return {
    id,
    name,
    position,
    color,
    isSystem: true,
    permissions: normalizePermissionMatrix(permissions)
  };
}

export function buildRoleLookup(roles: readonly RoomRole[]): Map<string, RoomRole> {
  return new Map(roles.map((role) => [role.id, role]));
}

export function nextRolePosition(roles: readonly RoomRole[]): number {
  if (roles.length === 0) {
    return 100;
  }

  return Math.max(...roles.map((role) => role.position)) + 100;
}

export function resolveLegacyAllowState(
  value: boolean | undefined,
  currentState: PermissionState | undefined,
  disabledState: Exclude<PermissionState, 'allow'>
): PermissionState | undefined {
  if (value === undefined) {
    return currentState;
  }

  return value ? 'allow' : disabledState;
}
