'use strict';

/**
 * Single source of truth for all granular permissions.
 * Keys here MUST match what controllers/routes use in requirePermission(...).
 *
 * Shape:
 *   <key>: {
 *     role:    'teacher' | 'student',   // primary role for admin UI grouping
 *     roles:   string[],                // all roles this key applies to
 *     default: 0 | 1,                   // PERM_DEFAULTS value
 *     label:   'Short label for admin UI',
 *     desc:    'Russian description for admin UI'
 *   }
 *
 * DISCREPANCY NOTE (2026-05-17):
 *   auth.js PERM_DEFAULTS includes a 'free_student' role with the same 8
 *   permission keys as 'student' (identical key strings, identical defaults).
 *   permissionsController.js ALL_PERMISSIONS does NOT list free_student entries
 *   (seedDefaults/admin UI only handles teacher and student).
 *   Resolution: each student-role key carries roles:['student','free_student']
 *   so that requirePermission() fallback works correctly for free_student users.
 *   The admin UI behaviour (filtering to teacher/student only) is preserved —
 *   permissionsController reads from registry.byRole('teacher') and
 *   registry.byRole('student').
 */

const PERMISSIONS = {
  /* ── Teacher ─────────────────────────────────────────────────────────── */
  'questions.manage': {
    role: 'teacher', roles: ['teacher'], default: 0,
    label: 'Управление вопросами',
    desc: 'Создавать, редактировать и копировать вопросы в банке',
    requireConfirmOff: true,
  },
  'questions.delete': {
    role: 'teacher', roles: ['teacher'], default: 0,
    label: 'Удалять вопросы',
    desc: 'Удалять вопросы из банка (требует "Управление вопросами")',
  },
  'students.invite': {
    role: 'teacher', roles: ['teacher'], default: 0,
    label: 'Регистрировать учеников',
    desc: 'Создавать новые аккаунты учеников напрямую из панели',
  },
  'sessions.reset': {
    role: 'teacher', roles: ['teacher'], default: 1,
    label: 'Сброс попыток',
    desc: 'Сбрасывать прохождение теста ученика в своём классе',
    requireConfirmOff: true,
  },
  'results.export': {
    role: 'teacher', roles: ['teacher'], default: 1,
    label: 'Экспорт результатов',
    desc: 'Выгружать результаты и оценки класса в CSV',
  },
  'classes.manage': {
    role: 'teacher', roles: ['teacher'], default: 1,
    label: 'Управление классами',
    desc: 'Создавать, редактировать и удалять свои классы',
    requireConfirmOff: true,
  },
  'library.upload': {
    role: 'teacher', roles: ['teacher'], default: 1,
    label: 'Загрузка файлов',
    desc: 'Загружать файлы в библиотеку',
    requireConfirmOff: true,
  },
  'library.folders': {
    role: 'teacher', roles: ['teacher'], default: 1,
    label: 'Управление папками',
    desc: 'Создавать папки и настраивать доступ к ним',
  },
  'schedule.manage': {
    role: 'teacher', roles: ['teacher'], default: 1,
    label: 'Дедлайны заданий',
    desc: 'Устанавливать дедлайны и временные окна для заданий',
  },
  'announcements.send': {
    role: 'teacher', roles: ['teacher'], default: 1,
    label: 'Объявления',
    desc: 'Публиковать объявления в своих классах',
  },
  'templates.manage': {
    role: 'teacher', roles: ['teacher'], default: 1,
    label: 'Управление шаблонами',
    desc: 'Создавать и использовать шаблоны курсов и уроков',
  },
  'templates.public': {
    role: 'teacher', roles: ['teacher'], default: 0,
    label: 'Публикация шаблонов',
    desc: 'Делать свои шаблоны публичными для всех учителей',
  },
  'courses.manage': {
    role: 'teacher', roles: ['teacher'], default: 1,
    label: 'Управление курсами',
    desc: 'Создавать и редактировать теоретические курсы и уроки',
    requireConfirmOff: true,
  },
  'courses.interactive': {
    role: 'teacher', roles: ['teacher'], default: 1,
    label: 'Интерактивные блоки',
    desc: 'Добавлять интерактивные задания в уроки (сопоставление, пропуски, порядок)',
  },
  'shop.manage': {
    role: 'teacher', roles: ['teacher'], default: 0,
    label: 'Управление магазином',
    desc: 'Создавать и редактировать товары в магазине наград',
  },
  'gamification.manage': {
    role: 'teacher', roles: ['teacher'], default: 0,
    label: 'Управление геймификацией',
    desc: 'Начислять XP/монеты ученикам, управлять достижениями',
  },

  /* ── Student (also applies to free_student — same keys, same defaults) ── */
  'tests.free': {
    role: 'student', roles: ['student', 'free_student'], default: 1,
    label: 'Свободные тесты',
    desc: 'Проходить тесты без задания (по предмету / случайно)',
  },
  'board.post': {
    role: 'student', roles: ['student', 'free_student'], default: 1,
    label: 'Реакции на доске',
    desc: 'Ставить реакции на задания на доске',
  },
  'profile.edit': {
    role: 'student', roles: ['student', 'free_student'], default: 1,
    label: 'Редактирование профиля',
    desc: 'Изменять своё имя и пароль',
  },
  'shop.purchase': {
    role: 'student', roles: ['student', 'free_student'], default: 1,
    label: 'Покупки в магазине',
    desc: 'Покупать предметы в магазине наград за монеты',
  },
  'gamification.challenges': {
    role: 'student', roles: ['student', 'free_student'], default: 1,
    label: 'Испытания недели',
    desc: 'Участвовать в еженедельных испытаниях и получать награды',
  },
  'theory.access': {
    role: 'student', roles: ['student', 'free_student'], default: 1,
    label: 'Доступ к теории',
    desc: 'Просматривать теоретические курсы и уроки',
    requireConfirmOff: true,
  },
  'simulations.access': {
    role: 'student', roles: ['student', 'free_student'], default: 1,
    label: 'Доступ к симуляциям',
    desc: 'Открывать лабораторию с физическими, химическими и биологическими симуляциями',
    requireConfirmOff: true,
  },
  'simulations.quiz': {
    role: 'student', roles: ['student', 'free_student'], default: 1,
    label: 'Задания в симуляциях',
    desc: 'Использовать режим "Задания" в симуляциях (квиз-режим)',
  },
};

/**
 * Check whether a given permission key exists in the registry.
 * Used by perm() helper in auth.js to fail early on typos.
 */
function isKnown(key) {
  return Object.prototype.hasOwnProperty.call(PERMISSIONS, key);
}

/** Return all registered permission keys. */
function listKeys() {
  return Object.keys(PERMISSIONS);
}

/**
 * Return all entries whose primary role matches.
 * Returns objects shaped like ALL_PERMISSIONS entries (key, role, default, label, desc).
 */
function byRole(role) {
  return Object.entries(PERMISSIONS)
    .filter(([, v]) => v.role === role)
    .map(([key, v]) => ({ key, role: v.role, default: v.default, label: v.label, desc: v.desc, requireConfirmOff: !!v.requireConfirmOff }));
}

/**
 * Build a PERM_DEFAULTS-style lookup: { role: { key: bool } }
 * Used by auth.js requirePermission fallback.
 */
function buildDefaultsMap() {
  const map = {};
  for (const [key, v] of Object.entries(PERMISSIONS)) {
    for (const r of v.roles) {
      if (!map[r]) map[r] = {};
      map[r][key] = v.default === 1;
    }
  }
  return map;
}

module.exports = { PERMISSIONS, isKnown, listKeys, byRole, buildDefaultsMap };
