// aislop-ignore-file: duplicate-block -- 表格/表单声明结构相似且参数不同，渲染逻辑已共享组件化
export interface AppMenuItem {
  key: string;
  label: string;
  icon?: string;
  children?: AppMenuItem[];
}

interface MenuEntry extends AppMenuItem {
  permission: string;
}

interface MenuSection extends AppMenuItem {
  roles: string[];
  children: MenuEntry[];
}

const ROLE_ALIASES: Record<string, string> = {
  老师: 'teacher',
  任课老师: 'teacher',
  teacher: 'teacher',
  教务: 'academic',
  教务管理员: 'academic',
  academic: 'academic',
  宿管老师: 'accommodation',
  宿管: 'accommodation',
  财务: 'accommodation',
  住宿运营管理员: 'accommodation',
  accommodation_operations: 'accommodation',
  机构负责人: 'classroom',
  教室运营管理员: 'classroom',
  classroom_operations: 'classroom',
  系统管理员: 'system',
  system_admin: 'system',
  超管: 'super',
  超级管理员: 'super',
  super_admin: 'super',
};

function entry(key: string, label: string, icon: string, permission: string): MenuEntry {
  return { key, label, icon, permission };
}

function section(
  key: string,
  label: string,
  icon: string,
  roles: string[],
  children: MenuEntry[],
): MenuSection {
  return { key, label, icon, roles, children };
}

const SECTIONS: MenuSection[] = [
  section(
    'teaching-group',
    '教学工作',
    'calendar',
    ['teacher'],
    [
      entry('/teacher-workspace', '今日教学', 'workspace', 'teacher-workspace:view'),

      entry('/schedules', '我的排课', 'calendar', 'schedule:view'),

      entry('/attendance', '课程考勤', 'attendance', 'attendance:view'),
    ],
  ),
  section(
    'academic-group',
    '教务管理',
    'academic',
    ['academic', 'super'],
    [
      entry('/students', '学生管理', 'students', 'student:view'),

      entry('/classes', '班级管理', 'classes', 'class:view'),

      entry('/exams', '考试管理', 'exam', 'exam:view'),

      entry('/teachers', '教师管理', 'teachers', 'teacher:view'),

      entry('/schedules', '排课管理', 'calendar', 'schedule:view'),

      entry('/attendance', '历史考勤', 'attendance', 'attendance:view'),

      entry('/classrooms', '教室查看', 'classroom', 'classroom:view'),
    ],
  ),
  section(
    'accommodation-group',
    '住宿运营',
    'home',
    ['accommodation', 'super'],
    [
      entry('/room-visual', '住宿总览', 'overview', 'room:view'),

      entry('/rooms', '房间管理', 'home', 'room:view'),

      entry('/occupancies', '入住管理', 'occupancy', 'occupancy:view'),

      entry('/expenses', '费用管理', 'expense', 'expense:view'),

      entry('/bills', '账单管理', 'bill', 'bill:view'),

      entry('/wallets', '学生余额', 'wallet', 'wallet:view'),

      entry('/deposits', '押金管理', 'deposit', 'deposit:view'),
    ],
  ),
  section(
    'classroom-group',
    '教室运营',
    'classroom',
    ['classroom', 'super'],
    [
      entry('/classroom-schedule', '教室排期', 'calendar', 'rental:view'),

      entry('/classrooms', '教室管理', 'classroom', 'classroom:view'),

      entry('/attendance-devices', '考勤机绑定', 'attendance', 'classroom:view'),

      entry('/classroom-rentals', '租赁订单', 'rental', 'rental:view'),

      entry('/organizations', '机构管理', 'organization', 'organization:view'),
    ],
  ),
  section(
    'system-group',
    '系统管理',
    'settings',
    ['system', 'super'],
    [
      entry('/users', '账号管理', 'users', 'user:view'),

      entry('/roles', '角色管理', 'role', 'role:view'),

      entry('/permissions', '权限一览', 'permission', 'role:view'),

      entry('/operation-logs', '操作日志', 'log', 'log:view'),

      entry('/integration-config', '钉钉集成', 'integration', 'integration:read'),

      entry('/ai-config', 'AI 配置', 'ai', 'ai:config:read'),
    ],
  ),
];

export function getRoleDomains(
  roles: readonly string[],
  permissions: readonly string[],
): Set<string> {
  const normalized = new Set(roles.map((role) => ROLE_ALIASES[role]).filter(Boolean));
  // 权限可以来自多个叠加角色，因此业务域按能力累加，而不是只选择一个。
  if (permissions.includes('student:view') || permissions.includes('class:view')) {
    normalized.add('academic');
  }
  if (
    (permissions.includes('room:view') &&
      (permissions.includes('occupancy:view') || permissions.includes('expense:view'))) ||
    permissions.includes('wallet:view')
  ) {
    normalized.add('accommodation');
  }
  if (permissions.includes('rental:view') || permissions.includes('organization:view')) {
    normalized.add('classroom');
  }
  if (permissions.includes('user:view') || permissions.includes('role:view')) {
    normalized.add('system');
  }
  const hasAdministrativeDomain = [...normalized].some((role) => role !== 'teacher');
  if (!hasAdministrativeDomain && permissions.includes('teacher-workspace:view')) {
    normalized.add('teacher');
  }
  return normalized;
}

function dedupeMenu(items: AppMenuItem[]): AppMenuItem[] {
  const usedPaths = new Set<string>();
  const result: AppMenuItem[] = [];
  for (const item of items) {
    if (item.children) {
      const children = item.children.filter((child) => {
        if (usedPaths.has(child.key)) return false;
        usedPaths.add(child.key);
        return true;
      });
      if (children.length > 0) result.push({ ...item, children });
      continue;
    }
    if (!usedPaths.has(item.key)) {
      usedPaths.add(item.key);
      result.push(item);
    }
  }
  return result;
}

export function buildMenu(roles: readonly string[], permissions: readonly string[]): AppMenuItem[] {
  const roleSet = getRoleDomains(roles, permissions);
  const permissionSet = new Set(permissions);
  const sections: AppMenuItem[] = [];

  if (permissionSet.has('dashboard:view') && !roleSet.has('teacher')) {
    sections.push({ key: '/dashboard', label: '数据面板', icon: 'dashboard' });
  }

  for (const section of SECTIONS) {
    if (!section.roles.some((role) => roleSet.has(role))) continue;
    const children = section.children
      .filter((child) => permissionSet.has(child.permission))
      .map(({ permission: _, ...child }) => child);
    if (children.length > 0)
      sections.push({ ...section, children, roles: undefined } as AppMenuItem);
  }

  if (permissionSet.has('notification:view')) {
    sections.push({ key: '/notifications', label: '通知中心', icon: 'notification' });
  }

  return dedupeMenu(sections);
}

export function collectMenuPaths(items: readonly AppMenuItem[]): string[] {
  return items.flatMap((item) => (item.children ? collectMenuPaths(item.children) : [item.key]));
}

export function findRoleAwareLandingPath(
  roles: readonly string[],
  permissions: readonly string[],
): string | null {
  return collectMenuPaths(buildMenu(roles, permissions))[0] ?? null;
}
