/**
 * GraphQL React Hooks（ai14）
 *
 * 封装 urql useQuery / useMutation，解包 ActionState 信封提取业务数据。
 * 每个 Hook 返回统一的 UseQueryResult / UseMutationResult 结构。
 *
 * 16 个查询 Hook + 8 个变更 Hook，对齐 types.ts 操作清单。
 *
 * 缓存策略（02-architecture-design.md §3）：
 * - 学生数据 30s 短缓存（staleTime 30s）
 * - 考试题目数据 0s 禁缓存（防泄露）
 * - 学习路径 5min 长缓存（低频变更）
 */

import { useMutation, useQuery } from "urql";
import type { CombinedError } from "urql";
import type {
  ActionError,
  ActionState,
  AddErrorBookItemInput,
  AddErrorBookItemResult,
  Announcement,
  AssignmentAnalysis,
  AttendanceRecord,
  CancelLeaveRequestInput,
  CancelLeaveRequestResult,
  ChangePasswordInput,
  ChangePasswordResult,
  ChapterNode,
  ClassInfo,
  CoursePlanDetail,
  CoursePlanListItem,
  CourseSelection,
  CreateLeaveRequestInput,
  CreateLeaveRequestResult,
  CurrentUser,
  DeleteErrorBookItemInput,
  DeleteErrorBookItemResult,
  DiagnosticReport,
  DropElectiveCourseInput,
  DropElectiveCourseResult,
  ElectiveCourse,
  ErrorBookData,
  ExamDetail,
  ExamListItem,
  GradeRecord,
  GrowthDataPoint,
  HomeworkDetail,
  HomeworkListItem,
  JoinClassInput,
  JoinClassResult,
  LeaveClassInput,
  LeaveClassResult,
  LeaveRequest,
  LearningPathNode,
  LessonPlanDetail,
  LessonPlanListItem,
  MarkAllAsReadInput,
  MarkAllAsReadResult,
  MarkAnnouncementReadInput,
  MarkAnnouncementReadResult,
  MarkAsReadInput,
  MarkAsReadResult,
  MasterySummary,
  MutationResponses,
  MyPracticeSessionsData,
  NotificationItem,
  PracticeSessionDetail,
  QueryResponses,
  RecordExamViolationInput,
  RecordExamViolationResult,
  RecordPasteEventInput,
  RecordPasteEventResult,
  ReportCardData,
  RequestExtensionInput,
  RequestExtensionResult,
  SaveExamDraftInput,
  SaveExamDraftResult,
  ScheduleItem,
  SelectElectiveCourseInput,
  SelectElectiveCourseResult,
  ServerTime,
  StartPracticeSessionInput,
  StudentDashboard,
  StudentProfile,
  SubmitExamInput,
  SubmitExamResult,
  SubmitHomeworkInput,
  SubmitHomeworkResult,
  SubmitPracticeAnswerInput,
  SubmitPracticeAnswerResult,
  SubjectRef,
  Textbook,
  TrendDataPoint,
  UpdateErrorBookItemInput,
  UpdateErrorBookItemResult,
  UpdateNotificationPreferenceInput,
  UpdateNotificationPreferenceResult,
  UpdateProfileInput,
  UpdateProfileResult,
  WeaknessPoint,
} from "./types";
import {
  ADD_ERROR_BOOK_ITEM_MUTATION,
  ANNOUNCEMENT_DETAIL_QUERY,
  ANNOUNCEMENTS_QUERY,
  ASSIGNMENT_ANALYSIS_QUERY,
  AVAILABLE_ELECTIVE_COURSES_QUERY,
  CANCEL_LEAVE_REQUEST_MUTATION,
  CHANGE_PASSWORD_MUTATION,
  CHAPTERS_QUERY,
  COURSE_PLAN_DETAIL_QUERY,
  CREATE_LEAVE_REQUEST_MUTATION,
  CURRENT_USER_QUERY,
  DELETE_ERROR_BOOK_ITEM_MUTATION,
  DROP_ELECTIVE_COURSE_MUTATION,
  EXAM_DETAIL_QUERY,
  HOMEWORK_DETAIL_QUERY,
  JOIN_CLASS_MUTATION,
  LEAVE_CLASS_MUTATION,
  LEARNING_PATH_QUERY,
  LESSON_PLAN_DETAIL_QUERY,
  MARK_ALL_AS_READ_MUTATION,
  MARK_ANNOUNCEMENT_READ_MUTATION,
  MARK_AS_READ_MUTATION,
  MY_ATTENDANCE_QUERY,
  MY_CLASSES_QUERY,
  MY_COURSE_PLANS_QUERY,
  MY_DIAGNOSTIC_REPORTS_QUERY,
  MY_ELECTIVE_SELECTIONS_QUERY,
  MY_ERROR_BOOK_QUERY,
  MY_EXAMS_QUERY,
  MY_GRADES_QUERY,
  MY_HOMEWORK_QUERY,
  MY_LEAVE_REQUESTS_QUERY,
  MY_LESSON_PLANS_QUERY,
  MY_MASTERY_SUMMARY_QUERY,
  MY_NOTIFICATIONS_QUERY,
  MY_PRACTICE_SESSIONS_QUERY,
  MY_PROFILE_QUERY,
  MY_REPORT_CARD_QUERY,
  MY_SCHEDULE_QUERY,
  MY_TREND_QUERY,
  MY_WEAKNESS_QUERY,
  RECORD_EXAM_VIOLATION_MUTATION,
  RECORD_PASTE_EVENT_MUTATION,
  REQUEST_EXTENSION_MUTATION,
  SAVE_EXAM_DRAFT_MUTATION,
  SELECT_ELECTIVE_COURSE_MUTATION,
  SERVER_TIME_QUERY,
  START_PRACTICE_SESSION_QUERY,
  STUDENT_DASHBOARD_QUERY,
  STUDENT_GROWTH_QUERY,
  SUBMIT_EXAM_MUTATION,
  SUBMIT_HOMEWORK_MUTATION,
  SUBMIT_PRACTICE_ANSWER_MUTATION,
  TEXTBOOKS_QUERY,
  UPDATE_ERROR_BOOK_ITEM_MUTATION,
  UPDATE_NOTIFICATION_PREFERENCE_MUTATION,
  UPDATE_PROFILE_MUTATION,
} from "./operations";

// ---------------------------------------------------------------------------
// 通用 Hook 返回类型
// ---------------------------------------------------------------------------

/** 查询 Hook 统一返回结构 */
export interface UseQueryResult<T> {
  /** 解包后的业务数据（ActionState.data） */
  data: T | null;
  /** 是否正在请求 */
  fetching: boolean;
  /** urql 错误（网络/GraphQL 顶层错误） */
  error: CombinedError | undefined;
  /** 数据是否 stale */
  stale: boolean;
  /** ActionState.success */
  success: boolean;
  /** ActionState.errors */
  errors: ActionError[];
  /** 降级模式标记 */
  degraded: boolean;
  /** 降级原因 */
  degradedReason: string | undefined;
  /** 重新执行查询 */
  reexecute: (opts?: Record<string, unknown>) => void;
}

/** 变更 Hook 统一返回结构 */
export interface UseMutationResult<T, V> {
  /** 解包后的业务数据（ActionState.data） */
  data: T | null;
  /** 是否正在请求 */
  fetching: boolean;
  /** urql 错误 */
  error: CombinedError | undefined;
  /** ActionState.success */
  success: boolean;
  /** ActionState.errors */
  errors: ActionError[];
  /** 降级模式标记 */
  degraded: boolean;
  /** 降级原因 */
  degradedReason: string | undefined;
  /** 触发变更 */
  execute: (variables: V) => void;
}

/** 通知列表查询响应数据 */
interface NotificationsData {
  items: NotificationItem[];
  totalCount: number;
  unreadCount: number;
}

// ---------------------------------------------------------------------------
// ActionState 解包工具
// ---------------------------------------------------------------------------

/**
 * 从 urql 响应数据中解包 ActionState
 * @param state ActionState 或 null/undefined
 * @returns 解包后的数据或 null
 */
function unwrapData<T>(state: ActionState<T> | null | undefined): T | null {
  return state?.data ?? null;
}

/** 从 ActionState 提取 success */
function getSuccess<T>(state: ActionState<T> | null | undefined): boolean {
  return state?.success ?? false;
}

/** 从 ActionState 提取 errors */
function getErrors<T>(state: ActionState<T> | null | undefined): ActionError[] {
  return state?.errors ?? [];
}

/** 从 ActionState 提取 degraded 标记 */
function getDegraded<T>(state: ActionState<T> | null | undefined): boolean {
  return state?.extensions?.degraded ?? false;
}

/** 从 ActionState 提取 degradedReason */
function getDegradedReason<T>(
  state: ActionState<T> | null | undefined,
): string | undefined {
  return state?.extensions?.degradedReason;
}

// ---------------------------------------------------------------------------
// 查询 Hooks（16 个）
// ---------------------------------------------------------------------------

/** 当前学生信息 + 权限 + 数据范围 */
export function useCurrentUser(): UseQueryResult<CurrentUser> {
  const [result, reexecute] = useQuery<{
    currentUser: ActionState<CurrentUser>;
  }>({ query: CURRENT_USER_QUERY });
  const state = result.data?.currentUser;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的班级列表 */
export function useMyClasses(): UseQueryResult<ClassInfo[]> {
  const [result, reexecute] = useQuery<{
    myClasses: ActionState<ClassInfo[]>;
  }>({ query: MY_CLASSES_QUERY });
  const state = result.data?.myClasses;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的考试列表 */
export function useMyExams(): UseQueryResult<ExamListItem[]> {
  const [result, reexecute] = useQuery<{
    myExams: ActionState<ExamListItem[]>;
  }>({ query: MY_EXAMS_QUERY });
  const state = result.data?.myExams;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 考试详情（含题目，禁缓存防泄露） */
export function useExamDetail(examId: string): UseQueryResult<ExamDetail> {
  const [result, reexecute] = useQuery<{
    examDetail: ActionState<ExamDetail>;
  }>({
    query: EXAM_DETAIL_QUERY,
    variables: { examId },
    // 考试题目数据强制禁缓存（02-architecture-design §3）
    context: { additionalTypenames: [], requestPolicy: "network-only" },
  });
  const state = result.data?.examDetail;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的作业列表 */
export function useMyHomework(): UseQueryResult<HomeworkListItem[]> {
  const [result, reexecute] = useQuery<{
    myHomework: ActionState<HomeworkListItem[]>;
  }>({ query: MY_HOMEWORK_QUERY });
  const state = result.data?.myHomework;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 作业详情（含题目） */
export function useHomeworkDetail(
  homeworkId: string,
): UseQueryResult<HomeworkDetail> {
  const [result, reexecute] = useQuery<{
    homeworkDetail: ActionState<HomeworkDetail>;
  }>({
    query: HOMEWORK_DETAIL_QUERY,
    variables: { homeworkId },
  });
  const state = result.data?.homeworkDetail;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的成绩列表 */
export function useMyGrades(): UseQueryResult<GradeRecord[]> {
  const [result, reexecute] = useQuery<{
    myGrades: ActionState<GradeRecord[]>;
  }>({ query: MY_GRADES_QUERY });
  const state = result.data?.myGrades;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的考勤记录 */
export function useMyAttendance(): UseQueryResult<AttendanceRecord[]> {
  const [result, reexecute] = useQuery<{
    myAttendance: ActionState<AttendanceRecord[]>;
  }>({ query: MY_ATTENDANCE_QUERY });
  const state = result.data?.myAttendance;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 教材列表 */
export function useTextbooks(): UseQueryResult<Textbook[]> {
  const [result, reexecute] = useQuery<{
    textbooks: ActionState<Textbook[]>;
  }>({ query: TEXTBOOKS_QUERY });
  const state = result.data?.textbooks;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 章节列表（树形结构，按教材 ID 查询） */
export function useChapters(textbookId: string): UseQueryResult<ChapterNode[]> {
  const [result, reexecute] = useQuery<{
    chapters: ActionState<ChapterNode[]>;
  }>({
    query: CHAPTERS_QUERY,
    variables: { textbookId },
  });
  const state = result.data?.chapters;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 学习路径（8 知识点 + 掌握度） */
export function useLearningPath(): UseQueryResult<LearningPathNode[]> {
  const [result, reexecute] = useQuery<{
    learningPath: ActionState<LearningPathNode[]>;
  }>({ query: LEARNING_PATH_QUERY });
  const state = result.data?.learningPath;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 学生仪表盘聚合数据 */
export function useStudentDashboard(): UseQueryResult<StudentDashboard> {
  const [result, reexecute] = useQuery<{
    studentDashboard: ActionState<StudentDashboard>;
  }>({ query: STUDENT_DASHBOARD_QUERY });
  const state = result.data?.studentDashboard;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的薄弱点（错题本） */
export function useMyWeakness(): UseQueryResult<WeaknessPoint[]> {
  const [result, reexecute] = useQuery<{
    myWeakness: ActionState<WeaknessPoint[]>;
  }>({ query: MY_WEAKNESS_QUERY });
  const state = result.data?.myWeakness;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 学习趋势（7 数据点） */
export function useMyTrend(): UseQueryResult<TrendDataPoint[]> {
  const [result, reexecute] = useQuery<{
    myTrend: ActionState<TrendDataPoint[]>;
  }>({ query: MY_TREND_QUERY });
  const state = result.data?.myTrend;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 通知列表（分页查询） */
export function useMyNotifications(
  first: number = 10,
  after?: string,
): UseQueryResult<NotificationsData> {
  const [result, reexecute] = useQuery<{
    myNotifications: ActionState<NotificationsData>;
  }>({
    query: MY_NOTIFICATIONS_QUERY,
    variables: { first, after },
  });
  const state = result.data?.myNotifications;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 服务器时间（倒计时校正） */
export function useServerTime(): UseQueryResult<ServerTime> {
  const [result, reexecute] = useQuery<{
    serverTime: ActionState<ServerTime>;
  }>({ query: SERVER_TIME_QUERY });
  const state = result.data?.serverTime;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

// ---------------------------------------------------------------------------
// 变更 Hooks（8 个）
// ---------------------------------------------------------------------------

/** 提交作业 */
export function useSubmitHomework(): UseMutationResult<
  SubmitHomeworkResult,
  SubmitHomeworkInput
> {
  const [result, execute] = useMutation<{
    submitHomework: ActionState<SubmitHomeworkResult>;
  }>(SUBMIT_HOMEWORK_MUTATION);
  const state = result.data?.submitHomework;
  const executeMutation = (input: SubmitHomeworkInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 提交考试 */
export function useSubmitExam(): UseMutationResult<
  SubmitExamResult,
  SubmitExamInput
> {
  const [result, execute] = useMutation<{
    submitExam: ActionState<SubmitExamResult>;
  }>(SUBMIT_EXAM_MUTATION);
  const state = result.data?.submitExam;
  const executeMutation = (input: SubmitExamInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 保存考试草稿（自动保存） */
export function useSaveExamDraft(): UseMutationResult<
  SaveExamDraftResult,
  SaveExamDraftInput
> {
  const [result, execute] = useMutation<{
    saveExamDraft: ActionState<SaveExamDraftResult>;
  }>(SAVE_EXAM_DRAFT_MUTATION);
  const state = result.data?.saveExamDraft;
  const executeMutation = (input: SaveExamDraftInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 标记通知已读 */
export function useMarkAsRead(): UseMutationResult<
  MarkAsReadResult,
  MarkAsReadInput
> {
  const [result, execute] = useMutation<{
    markAsRead: ActionState<MarkAsReadResult>;
  }>(MARK_AS_READ_MUTATION);
  const state = result.data?.markAsRead;
  const executeMutation = (input: MarkAsReadInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 批量标记已读 */
export function useMarkAllAsRead(): UseMutationResult<
  MarkAllAsReadResult,
  MarkAllAsReadInput
> {
  const [result, execute] = useMutation<{
    markAllAsRead: ActionState<MarkAllAsReadResult>;
  }>(MARK_ALL_AS_READ_MUTATION);
  const state = result.data?.markAllAsRead;
  const executeMutation = (input: MarkAllAsReadInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 记录考试违规（防作弊） */
export function useRecordExamViolation(): UseMutationResult<
  RecordExamViolationResult,
  RecordExamViolationInput
> {
  const [result, execute] = useMutation<{
    recordExamViolation: ActionState<RecordExamViolationResult>;
  }>(RECORD_EXAM_VIOLATION_MUTATION);
  const state = result.data?.recordExamViolation;
  const executeMutation = (input: RecordExamViolationInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 记录粘贴事件（防作弊） */
export function useRecordPasteEvent(): UseMutationResult<
  RecordPasteEventResult,
  RecordPasteEventInput
> {
  const [result, execute] = useMutation<{
    recordPasteEvent: ActionState<RecordPasteEventResult>;
  }>(RECORD_PASTE_EVENT_MUTATION);
  const state = result.data?.recordPasteEvent;
  const executeMutation = (input: RecordPasteEventInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 更新通知偏好 */
export function useUpdateNotificationPreference(): UseMutationResult<
  UpdateNotificationPreferenceResult,
  UpdateNotificationPreferenceInput
> {
  const [result, execute] = useMutation<{
    updateNotificationPreference: ActionState<UpdateNotificationPreferenceResult>;
  }>(UPDATE_NOTIFICATION_PREFERENCE_MUTATION);
  const state = result.data?.updateNotificationPreference;
  const executeMutation = (input: UpdateNotificationPreferenceInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

// ---------------------------------------------------------------------------
// 扩展查询 Hooks（4 个）
// ---------------------------------------------------------------------------

/** 我的课表（周视图） */
export function useMySchedule(): UseQueryResult<ScheduleItem[]> {
  const [result, reexecute] = useQuery<{
    mySchedule: ActionState<ScheduleItem[]>;
  }>({ query: MY_SCHEDULE_QUERY });
  const state = result.data?.mySchedule;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 学生成长曲线（vs 班级平均） */
export function useStudentGrowth(): UseQueryResult<GrowthDataPoint[]> {
  const [result, reexecute] = useQuery<{
    studentGrowth: ActionState<GrowthDataPoint[]>;
  }>({ query: STUDENT_GROWTH_QUERY });
  const state = result.data?.studentGrowth;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 作业分析 */
export function useAssignmentAnalysis(
  homeworkId: string,
): UseQueryResult<AssignmentAnalysis> {
  const [result, reexecute] = useQuery<{
    assignmentAnalysis: ActionState<AssignmentAnalysis>;
  }>({
    query: ASSIGNMENT_ANALYSIS_QUERY,
    variables: { homeworkId },
  });
  const state = result.data?.assignmentAnalysis;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 学生个人资料 */
export function useMyProfile(): UseQueryResult<StudentProfile> {
  const [result, reexecute] = useQuery<{
    myProfile: ActionState<StudentProfile>;
  }>({ query: MY_PROFILE_QUERY });
  const state = result.data?.myProfile;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

// ---------------------------------------------------------------------------
// 扩展变更 Hooks（5 个）
// ---------------------------------------------------------------------------

/** 更新个人资料 */
export function useUpdateProfile(): UseMutationResult<
  UpdateProfileResult,
  UpdateProfileInput
> {
  const [result, execute] = useMutation<{
    updateProfile: ActionState<UpdateProfileResult>;
  }>(UPDATE_PROFILE_MUTATION);
  const state = result.data?.updateProfile;
  const executeMutation = (input: UpdateProfileInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 修改密码 */
export function useChangePassword(): UseMutationResult<
  ChangePasswordResult,
  ChangePasswordInput
> {
  const [result, execute] = useMutation<{
    changePassword: ActionState<ChangePasswordResult>;
  }>(CHANGE_PASSWORD_MUTATION);
  const state = result.data?.changePassword;
  const executeMutation = (input: ChangePasswordInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 作业延期申请 */
export function useRequestExtension(): UseMutationResult<
  RequestExtensionResult,
  RequestExtensionInput
> {
  const [result, execute] = useMutation<{
    requestExtension: ActionState<RequestExtensionResult>;
  }>(REQUEST_EXTENSION_MUTATION);
  const state = result.data?.requestExtension;
  const executeMutation = (input: RequestExtensionInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 加入班级 */
export function useJoinClass(): UseMutationResult<
  JoinClassResult,
  JoinClassInput
> {
  const [result, execute] = useMutation<{
    joinClass: ActionState<JoinClassResult>;
  }>(JOIN_CLASS_MUTATION);
  const state = result.data?.joinClass;
  const executeMutation = (input: JoinClassInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 退出班级 */
export function useLeaveClass(): UseMutationResult<
  LeaveClassResult,
  LeaveClassInput
> {
  const [result, execute] = useMutation<{
    leaveClass: ActionState<LeaveClassResult>;
  }>(LEAVE_CLASS_MUTATION);
  const state = result.data?.leaveClass;
  const executeMutation = (input: LeaveClassInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

// ---------------------------------------------------------------------------
// 批次 A 扩展查询 Hooks
// ---------------------------------------------------------------------------

/** 我的错题本 */
export function useMyErrorBook(): UseQueryResult<ErrorBookData> {
  const [result, reexecute] = useQuery<{
    myErrorBook: ActionState<ErrorBookData>;
  }>({ query: MY_ERROR_BOOK_QUERY });
  const state = result.data?.myErrorBook;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的请假记录 */
export function useMyLeaveRequests(): UseQueryResult<LeaveRequest[]> {
  const [result, reexecute] = useQuery<{
    myLeaveRequests: ActionState<LeaveRequest[]>;
  }>({ query: MY_LEAVE_REQUESTS_QUERY });
  const state = result.data?.myLeaveRequests;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的选课记录 */
export function useMyElectiveSelections(): UseQueryResult<CourseSelection[]> {
  const [result, reexecute] = useQuery<{
    myElectiveSelections: ActionState<CourseSelection[]>;
  }>({ query: MY_ELECTIVE_SELECTIONS_QUERY });
  const state = result.data?.myElectiveSelections;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 可选课程列表 */
export function useAvailableElectiveCourses(): UseQueryResult<ElectiveCourse[]> {
  const [result, reexecute] = useQuery<{
    availableElectiveCourses: ActionState<ElectiveCourse[]>;
  }>({ query: AVAILABLE_ELECTIVE_COURSES_QUERY });
  const state = result.data?.availableElectiveCourses;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的练习会话列表 */
export function useMyPracticeSessions(): UseQueryResult<MyPracticeSessionsData> {
  const [result, reexecute] = useQuery<{
    myPracticeSessions: ActionState<MyPracticeSessionsData>;
  }>({ query: MY_PRACTICE_SESSIONS_QUERY });
  const state = result.data?.myPracticeSessions;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 启动练习会话 */
export function useStartPracticeSession(): UseMutationResult<
  PracticeSessionDetail,
  StartPracticeSessionInput
> {
  const [result, execute] = useMutation<{
    startPracticeSession: ActionState<PracticeSessionDetail>;
  }>(START_PRACTICE_SESSION_QUERY);
  const state = result.data?.startPracticeSession;
  const executeMutation = (input: StartPracticeSessionInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 公告列表 */
export function useAnnouncements(): UseQueryResult<Announcement[]> {
  const [result, reexecute] = useQuery<{
    announcements: ActionState<Announcement[]>;
  }>({ query: ANNOUNCEMENTS_QUERY });
  const state = result.data?.announcements;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 公告详情 */
export function useAnnouncementDetail(
  announcementId: string,
): UseQueryResult<Announcement> {
  const [result, reexecute] = useQuery<{
    announcementDetail: ActionState<Announcement>;
  }>({
    query: ANNOUNCEMENT_DETAIL_QUERY,
    variables: { announcementId },
  });
  const state = result.data?.announcementDetail;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的课案列表（仅已发布） */
export function useMyLessonPlans(): UseQueryResult<LessonPlanListItem[]> {
  const [result, reexecute] = useQuery<{
    myLessonPlans: ActionState<LessonPlanListItem[]>;
  }>({ query: MY_LESSON_PLANS_QUERY });
  const state = result.data?.myLessonPlans;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 课案详情 */
export function useLessonPlanDetail(
  planId: string,
): UseQueryResult<LessonPlanDetail> {
  const [result, reexecute] = useQuery<{
    lessonPlanDetail: ActionState<LessonPlanDetail>;
  }>({
    query: LESSON_PLAN_DETAIL_QUERY,
    variables: { planId },
  });
  const state = result.data?.lessonPlanDetail;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的课程计划列表 */
export function useMyCoursePlans(): UseQueryResult<CoursePlanListItem[]> {
  const [result, reexecute] = useQuery<{
    myCoursePlans: ActionState<CoursePlanListItem[]>;
  }>({ query: MY_COURSE_PLANS_QUERY });
  const state = result.data?.myCoursePlans;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 课程计划详情 */
export function useCoursePlanDetail(
  planId: string,
): UseQueryResult<CoursePlanDetail> {
  const [result, reexecute] = useQuery<{
    coursePlanDetail: ActionState<CoursePlanDetail>;
  }>({
    query: COURSE_PLAN_DETAIL_QUERY,
    variables: { planId },
  });
  const state = result.data?.coursePlanDetail;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 成绩报告卡 */
export function useMyReportCard(
  academicYearId?: string,
  semester?: string,
): UseQueryResult<ReportCardData> {
  const [result, reexecute] = useQuery<{
    myReportCard: ActionState<ReportCardData>;
  }>({
    query: MY_REPORT_CARD_QUERY,
    variables: { academicYearId, semester },
  });
  const state = result.data?.myReportCard;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的诊断报告列表 */
export function useMyDiagnosticReports(): UseQueryResult<DiagnosticReport[]> {
  const [result, reexecute] = useQuery<{
    myDiagnosticReports: ActionState<DiagnosticReport[]>;
  }>({ query: MY_DIAGNOSTIC_REPORTS_QUERY });
  const state = result.data?.myDiagnosticReports;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

/** 我的掌握度摘要 */
export function useMyMasterySummary(): UseQueryResult<MasterySummary> {
  const [result, reexecute] = useQuery<{
    myMasterySummary: ActionState<MasterySummary>;
  }>({ query: MY_MASTERY_SUMMARY_QUERY });
  const state = result.data?.myMasterySummary;
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    stale: result.stale,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    reexecute: (opts?: Record<string, unknown>): void => reexecute(opts),
  };
}

// ---------------------------------------------------------------------------
// 批次 A 扩展变更 Hooks
// ---------------------------------------------------------------------------

/** 添加错题 */
export function useAddErrorBookItem(): UseMutationResult<
  AddErrorBookItemResult,
  AddErrorBookItemInput
> {
  const [result, execute] = useMutation<{
    addErrorBookItem: ActionState<AddErrorBookItemResult>;
  }>(ADD_ERROR_BOOK_ITEM_MUTATION);
  const state = result.data?.addErrorBookItem;
  const executeMutation = (input: AddErrorBookItemInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 更新错题（含复习自评） */
export function useUpdateErrorBookItem(): UseMutationResult<
  UpdateErrorBookItemResult,
  UpdateErrorBookItemInput
> {
  const [result, execute] = useMutation<{
    updateErrorBookItem: ActionState<UpdateErrorBookItemResult>;
  }>(UPDATE_ERROR_BOOK_ITEM_MUTATION);
  const state = result.data?.updateErrorBookItem;
  const executeMutation = (input: UpdateErrorBookItemInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 删除错题 */
export function useDeleteErrorBookItem(): UseMutationResult<
  DeleteErrorBookItemResult,
  DeleteErrorBookItemInput
> {
  const [result, execute] = useMutation<{
    deleteErrorBookItem: ActionState<DeleteErrorBookItemResult>;
  }>(DELETE_ERROR_BOOK_ITEM_MUTATION);
  const state = result.data?.deleteErrorBookItem;
  const executeMutation = (input: DeleteErrorBookItemInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 创建请假申请 */
export function useCreateLeaveRequest(): UseMutationResult<
  CreateLeaveRequestResult,
  CreateLeaveRequestInput
> {
  const [result, execute] = useMutation<{
    createLeaveRequest: ActionState<CreateLeaveRequestResult>;
  }>(CREATE_LEAVE_REQUEST_MUTATION);
  const state = result.data?.createLeaveRequest;
  const executeMutation = (input: CreateLeaveRequestInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 撤销请假申请 */
export function useCancelLeaveRequest(): UseMutationResult<
  CancelLeaveRequestResult,
  CancelLeaveRequestInput
> {
  const [result, execute] = useMutation<{
    cancelLeaveRequest: ActionState<CancelLeaveRequestResult>;
  }>(CANCEL_LEAVE_REQUEST_MUTATION);
  const state = result.data?.cancelLeaveRequest;
  const executeMutation = (input: CancelLeaveRequestInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 选课 */
export function useSelectElectiveCourse(): UseMutationResult<
  SelectElectiveCourseResult,
  SelectElectiveCourseInput
> {
  const [result, execute] = useMutation<{
    selectElectiveCourse: ActionState<SelectElectiveCourseResult>;
  }>(SELECT_ELECTIVE_COURSE_MUTATION);
  const state = result.data?.selectElectiveCourse;
  const executeMutation = (input: SelectElectiveCourseInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 退选 */
export function useDropElectiveCourse(): UseMutationResult<
  DropElectiveCourseResult,
  DropElectiveCourseInput
> {
  const [result, execute] = useMutation<{
    dropElectiveCourse: ActionState<DropElectiveCourseResult>;
  }>(DROP_ELECTIVE_COURSE_MUTATION);
  const state = result.data?.dropElectiveCourse;
  const executeMutation = (input: DropElectiveCourseInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 提交练习答题 */
export function useSubmitPracticeAnswer(): UseMutationResult<
  SubmitPracticeAnswerResult,
  SubmitPracticeAnswerInput
> {
  const [result, execute] = useMutation<{
    submitPracticeAnswer: ActionState<SubmitPracticeAnswerResult>;
  }>(SUBMIT_PRACTICE_ANSWER_MUTATION);
  const state = result.data?.submitPracticeAnswer;
  const executeMutation = (input: SubmitPracticeAnswerInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

/** 标记公告已读 */
export function useMarkAnnouncementRead(): UseMutationResult<
  MarkAnnouncementReadResult,
  MarkAnnouncementReadInput
> {
  const [result, execute] = useMutation<{
    markAnnouncementRead: ActionState<MarkAnnouncementReadResult>;
  }>(MARK_ANNOUNCEMENT_READ_MUTATION);
  const state = result.data?.markAnnouncementRead;
  const executeMutation = (input: MarkAnnouncementReadInput): void => {
    void execute({ input });
  };
  return {
    data: unwrapData(state),
    fetching: result.fetching,
    error: result.error,
    success: getSuccess(state),
    errors: getErrors(state),
    degraded: getDegraded(state),
    degradedReason: getDegradedReason(state),
    execute: executeMutation,
  };
}

// ---------------------------------------------------------------------------
// 类型导出（供响应映射使用）
// ---------------------------------------------------------------------------

export type { QueryResponses, MutationResponses };
export type { SubjectRef };
