const ROLE_PRIORITY = ['Administrator', 'MeetingManager', 'Leader', 'Employee'] as const;

export type MeetingAttendanceRoleCode = (typeof ROLE_PRIORITY)[number];

const ROLE_ALIASES: Record<string, MeetingAttendanceRoleCode> = {
  ADMIN: 'Administrator',
  ADMINISTRATOR: 'Administrator',
  MANAGER: 'MeetingManager',
  MEETINGMANAGER: 'MeetingManager',
  LEADER: 'Leader',
  EMPLOYEE: 'Employee',
};

export const normalizeMeetingRole = (role?: string | null): MeetingAttendanceRoleCode | null => {
  if (!role) return null;
  const trimmed = role.trim();
  if (!trimmed) return null;
  const normalized = ROLE_ALIASES[trimmed.toUpperCase()];
  if (normalized) {
    return normalized;
  }
  return ROLE_PRIORITY.includes(trimmed as MeetingAttendanceRoleCode) ? (trimmed as MeetingAttendanceRoleCode) : null;
};

export const getMeetingRoleFromUser = (
  user:
    | {
        roles?: Array<{ role?: { code?: string } } | string>;
        organizationRoles?: Record<string, string[]>;
      }
    | null,
) => {
  // PR #138 后 sliceAuthPayload 将 roles 切成"系统级 + 当前 org"。"会议管理员"是
  // 跨 org 资格判断，需把所有 org 的 role code 一并纳入考量。
  const rawCodes: Array<string | undefined> = [];

  // user.roles 在新模型里是 string[]，但兼容老的 Array<{role:{code}}> 形态
  if (user?.roles?.length) {
    for (const item of user.roles) {
      rawCodes.push(typeof item === 'string' ? item : item?.role?.code);
    }
  }
  if (user?.organizationRoles) {
    for (const orgRoles of Object.values(user.organizationRoles)) {
      for (const code of orgRoles) rawCodes.push(code);
    }
  }

  const codes = new Set<MeetingAttendanceRoleCode>();
  for (const rawCode of rawCodes) {
    const normalized = normalizeMeetingRole(rawCode);
    if (normalized) codes.add(normalized);
  }
  return ROLE_PRIORITY.find((role) => codes.has(role)) || null;
};

export const getMeetingRolePriorityList = () => [...ROLE_PRIORITY];

export const isMeetingAdminRole = (role?: MeetingAttendanceRoleCode | null) =>
  role === 'Administrator' || role === 'MeetingManager';

/**
 * 系列会议增删改鉴权。优先权限点 `meeting_attendance:manage`（含通配 `meeting_attendance:*`），
 * 兼容旧路径用角色 fallback（Administrator / MeetingManager / Leader）。
 *
 * 调用者通常另接 `|| series.creatorId === actor.id` 让系列创建者也通过。
 *
 * Leader 在当前 seed 里没有 `:manage`，靠角色 fallback 保留现状；后续若要彻底权限化，
 * 给 Leader 加上 `meeting_attendance:manage` 后即可删掉角色 fallback。
 */
export const canMutateSeries = (
  actor: { role?: string | null; permissions?: string[] | null } | null | undefined,
) => {
  if (!actor) return false;
  const perms = actor.permissions ?? [];
  if (perms.includes('meeting_attendance:manage') || perms.includes('meeting_attendance:*')) {
    return true;
  }
  const role = actor.role;
  return role === 'Administrator' || role === 'MeetingManager' || role === 'Leader';
};
