// Permission definitions: resource:action naming convention
// Used by requirePermission() on server and usePermission() on client

/**
 * Role name. Dynamic — roles are stored in the `roles` DB table and can be
 * created/edited/deleted at runtime via the rbac module.
 *
 * `BuiltinRole` covers the 6 system-defined roles that ship with the app and
 * are referenced by name in code paths that need compile-time safety
 * (e.g. `resolveDataScope` checks `roleNames.includes("admin")`).
 */
export type Role = string

/**
 * The 6 system-defined roles. Seeded into the DB with `is_system = true`
 * and cannot be deleted. Their permissions can be edited at runtime
 * (except for `admin`, which is fully locked).
 */
export const BUILTIN_ROLES = [
  "admin",
  "teacher",
  "student",
  "parent",
  "grade_head",
  "teaching_head",
] as const

export type BuiltinRole = (typeof BUILTIN_ROLES)[number]

/**
 * Named role constants for use in DB queries and permission checks.
 * Avoids hardcoding role name strings throughout the codebase.
 */
export const ROLE_NAMES = {
  ADMIN: "admin",
  TEACHER: "teacher",
  STUDENT: "student",
  PARENT: "parent",
  GRADE_HEAD: "grade_head",
  TEACHING_HEAD: "teaching_head",
} as const

/**
 * Type guard: narrows `string` to `BuiltinRole`.
 * Use to filter role names coming from the DB when only built-in roles are meaningful.
 */
export function isBuiltinRole(value: string): value is BuiltinRole {
  return (BUILTIN_ROLES as readonly string[]).includes(value)
}

/**
 * @deprecated Use `isBuiltinRole` instead. Kept for backward compatibility
 * during the RBAC migration; will be removed once all call sites are updated.
 */
export function isRole(value: string): value is Role {
  return typeof value === "string"
}

export const Permissions = {
  // Exam
  EXAM_CREATE: "exam:create",
  EXAM_READ: "exam:read",
  EXAM_UPDATE: "exam:update",
  EXAM_DELETE: "exam:delete",
  EXAM_DUPLICATE: "exam:duplicate",
  EXAM_PUBLISH: "exam:publish",
  EXAM_AI_GENERATE: "exam:ai_generate",
  EXAM_SUBMIT: "exam:submit",

  // Homework
  HOMEWORK_CREATE: "homework:create",
  HOMEWORK_GRADE: "homework:grade",
  HOMEWORK_SUBMIT: "homework:submit",

  // Question
  QUESTION_CREATE: "question:create",
  QUESTION_READ: "question:read",
  QUESTION_UPDATE: "question:update",
  QUESTION_DELETE: "question:delete",

  // Textbook
  TEXTBOOK_CREATE: "textbook:create",
  TEXTBOOK_READ: "textbook:read",
  TEXTBOOK_UPDATE: "textbook:update",
  TEXTBOOK_DELETE: "textbook:delete",

  // Class
  CLASS_CREATE: "class:create",
  CLASS_READ: "class:read",
  CLASS_UPDATE: "class:update",
  CLASS_DELETE: "class:delete",
  CLASS_ENROLL: "class:enroll",
  CLASS_SCHEDULE: "class:schedule",

  // School management
  SCHOOL_MANAGE: "school:manage",
  GRADE_MANAGE: "grade:manage",
  USER_MANAGE: "user:manage",

  // User (self-service)
  /** Self-service profile update (all authenticated roles) */
  USER_PROFILE_UPDATE: "user:profile_update",

  // AI
  AI_CHAT: "ai:chat",
  AI_CONFIGURE: "ai:configure",

  // Settings
  SETTINGS_ADMIN: "settings:admin",

  // Audit
  AUDIT_LOG_READ: "audit_log:read",

  // Announcement
  ANNOUNCEMENT_MANAGE: "announcement:manage",
  ANNOUNCEMENT_READ: "announcement:read",

  // Grade Record (成绩录入与查询)
  GRADE_RECORD_MANAGE: "grade_record:manage",
  GRADE_RECORD_READ: "grade_record:read",

  // File (文件上传与管理)
  FILE_UPLOAD: "file:upload",
  FILE_READ: "file:read",
  FILE_DELETE: "file:delete",

  // Course Plan (课程计划管理)
  COURSE_PLAN_MANAGE: "course_plan:manage",
  COURSE_PLAN_READ: "course_plan:read",

  // Attendance (考勤管理)
  ATTENDANCE_MANAGE: "attendance:manage",
  ATTENDANCE_READ: "attendance:read",

  // Leave Request (在线请假流程)
  /** 创建请假申请（家长代子女提交、学生本人提交） */
  LEAVE_REQUEST_CREATE: "leave_request:create",
  /** 读取请假申请（本人/子女/所辖班级） */
  LEAVE_REQUEST_READ: "leave_request:read",
  /** 审批请假申请（班主任、管理员） */
  LEAVE_REQUEST_REVIEW: "leave_request:review",

  // Message (站内消息)
  MESSAGE_SEND: "message:send",
  MESSAGE_READ: "message:read",
  MESSAGE_DELETE: "message:delete",

  // Scheduling (排课与调课)
  SCHEDULE_AUTO: "schedule:auto",
  SCHEDULE_ADJUST: "schedule:adjust",

  // P2: Elective Course (选课管理)
  ELECTIVE_MANAGE: "elective:manage",
  ELECTIVE_READ: "elective:read",
  ELECTIVE_SELECT: "elective:select",

  // P2: Exam Proctoring (考试监考)
  EXAM_PROCTOR: "exam:proctor",
  EXAM_PROCTOR_READ: "exam:proctor:read",

  // P2: Learning Diagnostic (学情诊断)
  DIAGNOSTIC_MANAGE: "diagnostic:manage",
  DIAGNOSTIC_READ: "diagnostic:read",

  // Lesson Plan (备课)
  LESSON_PLAN_CREATE: "lesson_plan:create",
  LESSON_PLAN_READ: "lesson_plan:read",
  LESSON_PLAN_UPDATE: "lesson_plan:update",
  LESSON_PLAN_DELETE: "lesson_plan:delete",
  LESSON_PLAN_PUBLISH: "lesson_plan:publish",
  // Standards (课标管理)
  STANDARD_READ: "standard:read",
  STANDARD_MANAGE: "standard:manage",
  STANDARD_LINK: "standard:link",

  // Dashboard (仪表盘 — 各角色独立读权限)
  DASHBOARD_ADMIN_READ: "dashboard:admin_read",
  DASHBOARD_TEACHER_READ: "dashboard:teacher_read",
  DASHBOARD_STUDENT_READ: "dashboard:student_read",
  DASHBOARD_PARENT_READ: "dashboard:parent_read",

  // Error Book (错题本)
  /** 读取自己的错题本（学生）或子女的错题本（家长） */
  ERROR_BOOK_READ: "error_book:read",
  /** 管理自己的错题本条目：手动添加、编辑笔记、标记掌握、删除 */
  ERROR_BOOK_MANAGE: "error_book:manage",
  /** 读取班级/年级/全校错题统计分析（教师、年级主任、教务主任、管理员） */
  ERROR_BOOK_ANALYTICS_READ: "error_book:analytics_read",

  // Adaptive Practice (专项练习)
  /** 读取自己的专项练习记录（学生）或子女的练习记录（家长） */
  ADAPTIVE_PRACTICE_READ: "adaptive_practice:read",
  /** 发起和管理自己的专项练习（学生） */
  ADAPTIVE_PRACTICE_MANAGE: "adaptive_practice:manage",

  // RBAC (角色与权限管理)
  /** 创建新角色 */
  ROLE_CREATE: "role:create",
  /** 查看角色列表与详情 */
  ROLE_READ: "role:read",
  /** 编辑角色信息与权限分配 */
  ROLE_UPDATE: "role:update",
  /** 删除自定义角色（内置角色不可删除） */
  ROLE_DELETE: "role:delete",
  /** 为用户分配或撤销角色 */
  ROLE_ASSIGN: "role:assign",
  /** 查看权限点目录 */
  PERMISSION_READ: "permission:read",
} as const satisfies Record<string, string>

export type Permission = (typeof Permissions)[keyof typeof Permissions]

/**
 * Data scope for row-level security.
 *
 * Determines which rows a user is allowed to see based on their role:
 * - `all`: no filtering (admin).
 * - `owned`: only rows created by the user.
 * - `class_members`: rows visible to members of the user's enrolled classes (student).
 *    `classIds` is pre-resolved by `resolveDataScope` to avoid N+1 queries downstream.
 *    `gradeIds` is pre-resolved from enrolled classes for grade-based filtering (e.g. lesson plans).
 * - `grade_managed`: rows within grades the user manages (grade_head / teaching_head).
 * - `class_taught`: rows within classes the user teaches (teacher).
 * - `children`: rows belonging to the user's children (parent).
 *    `gradeIds` is pre-resolved from children's enrolled classes for grade-based filtering.
 */
export type DataScope =
  | { type: "all" }
  | { type: "owned"; userId: string }
  | { type: "class_members"; classIds: string[]; gradeIds?: string[] }
  | { type: "grade_managed"; gradeIds: string[] }
  | { type: "class_taught"; classIds: string[]; subjectIds?: string[] }
  | { type: "children"; childrenIds: string[]; gradeIds?: string[] }

/**
 * Authentication context for the current request.
 *
 * - `userId`: the authenticated user's id.
 * - `roles`: all role names assigned to the user (dynamic, from DB).
 * - `permissions`: the merged set of permission strings granted to the user.
 * - `dataScope`: the row-level security scope used to filter queries.
 */
export interface AuthContext {
  userId: string
  roles: Role[]
  permissions: Permission[]
  dataScope: DataScope
}
