{"version":3,"sources":["../src/utils/categoryDataUtils.ts","../src/utils/useDynamicStudentFetching.ts"],"sourcesContent":["import type { BaseApiClient } from '../types/api';\nimport type { CategoryConfig } from '../components/CheckBoxGroup/CheckBoxGroup';\n\n/**\n * School type for categories data\n */\nexport interface School {\n  id: string;\n  companyName: string;\n}\n\n/**\n * SchoolYear type for categories data\n */\nexport interface SchoolYear {\n  id: string;\n  name: string;\n  schoolId: string;\n}\n\n/**\n * Class type for categories data\n */\nexport interface Class {\n  id: string;\n  name: string;\n  schoolYearId: string;\n}\n\n/**\n * Student type for categories data with nested school/schoolYear/class\n */\nexport interface Student {\n  id: string;\n  email: string;\n  name: string;\n  active: boolean;\n  createdAt: string;\n  updatedAt: string;\n  userInstitutionId: string;\n  institutionId: string;\n  profileId: string;\n  school: {\n    id: string;\n    name: string;\n  };\n  schoolYear: {\n    id: string;\n    name: string;\n  };\n  class: {\n    id: string;\n    name: string;\n  };\n}\n\n/**\n * Fetch students using POST /students/filters based on selected schools, schoolYears, and classes\n *\n * @param apiClient - API client instance\n * @param filters - Object with schoolIds, schoolYearIds, and classIds arrays\n * @returns Promise resolving to array of students\n *\n * @example\n * ```ts\n * const students = await fetchStudentsByFilters(apiClient, {\n *   schoolIds: ['school-1'],\n *   schoolYearIds: ['year-1'],\n *   classIds: ['class-1']\n * });\n * ```\n */\nexport async function fetchStudentsByFilters(\n  apiClient: BaseApiClient,\n  filters: {\n    schoolIds?: string[];\n    schoolYearIds?: string[];\n    classIds?: string[];\n  }\n): Promise<Student[]> {\n  // Only make request if at least one filter is provided\n  if (\n    (!filters.schoolIds || filters.schoolIds.length === 0) &&\n    (!filters.schoolYearIds || filters.schoolYearIds.length === 0) &&\n    (!filters.classIds || filters.classIds.length === 0)\n  ) {\n    return [];\n  }\n\n  const response = await apiClient.post<{\n    message: string;\n    data: {\n      students: Student[];\n    };\n  }>('/students/filters', {\n    ...(filters.schoolIds &&\n      filters.schoolIds.length > 0 && {\n        schoolIds: filters.schoolIds,\n      }),\n    ...(filters.schoolYearIds &&\n      filters.schoolYearIds.length > 0 && {\n        schoolYearIds: filters.schoolYearIds,\n      }),\n    ...(filters.classIds &&\n      filters.classIds.length > 0 && {\n        classIds: filters.classIds,\n      }),\n  });\n\n  return response.data.data.students || [];\n}\n\n/**\n * Fetch classes filtered by selected schools/schoolYears via GET /classes.\n * Wire format is comma-joined strings (NOT arrays): axios serializes an array\n * param with brackets (`schoolId[]=a`) which the backend's default querystring\n * parser does not fold into `schoolId`; a comma-joined string (`schoolId=a,b`)\n * is serializer-agnostic and the backend splits it. A UUID never contains a comma.\n *\n * @param apiClient - API client instance\n * @param filters - Object with schoolIds and/or schoolYearIds arrays\n * @returns Promise resolving to array of classes\n *\n * @example\n * ```ts\n * const classes = await fetchClassesByFilters(apiClient, {\n *   schoolIds: ['school-1'],\n *   schoolYearIds: ['year-1'],\n * });\n * ```\n */\nexport async function fetchClassesByFilters(\n  apiClient: BaseApiClient,\n  filters: { schoolIds?: string[]; schoolYearIds?: string[] }\n): Promise<Class[]> {\n  const hasSchools = !!filters.schoolIds && filters.schoolIds.length > 0;\n  const hasYears = !!filters.schoolYearIds && filters.schoolYearIds.length > 0;\n  if (!hasSchools && !hasYears) return [];\n  // Paginate ALL matching pages: a regional manager selecting many schools +\n  // series can have > 100 filtered classes, which a single page would truncate.\n  return fetchAllPages<Class>(\n    apiClient,\n    '/classes',\n    (data) => {\n      const d = data as {\n        classes: Class[];\n        pagination?: { totalPages: number };\n      };\n      return {\n        items: d.classes ?? [],\n        totalPages: d.pagination?.totalPages ?? 1,\n      };\n    },\n    {\n      ...(hasSchools && { schoolId: filters.schoolIds!.join(',') }),\n      ...(hasYears && { schoolYearId: filters.schoolYearIds!.join(',') }),\n    }\n  );\n}\n\n/**\n * Fetch every page of a paginated list endpoint and aggregate the items.\n *\n * @param apiClient - API client instance\n * @param url - Endpoint to fetch (e.g. '/school')\n * @param extract - Reads `data.data` and returns the page items and totalPages\n * @param extraParams - Extra query params merged into `{ page, limit }` on every\n *   request (e.g. comma-joined `schoolId`/`schoolYearId` filters for `/classes`)\n * @returns Promise resolving to all items across every page\n */\nasync function fetchAllPages<T>(\n  apiClient: BaseApiClient,\n  url: string,\n  extract: (data: unknown) => { items: T[]; totalPages: number },\n  extraParams: Record<string, unknown> = {}\n): Promise<T[]> {\n  // Fetch page 1 first to learn totalPages and get the initial items.\n  const firstResponse = await apiClient.get<{ message: string; data: unknown }>(\n    url,\n    { params: { ...extraParams, page: 1, limit: 100 } }\n  );\n  const first = extract(firstResponse.data.data);\n  const totalPages = first.totalPages || 1;\n  const all: T[] = [...(first.items ?? [])];\n\n  // Single page: return page-1 items unchanged.\n  if (totalPages <= 1) {\n    return all;\n  }\n\n  // Fetch remaining pages 2..totalPages in parallel. The browser caps\n  // concurrent requests per host (~6), so firing them all is safe.\n  const remainingPages = Array.from(\n    { length: totalPages - 1 },\n    (_, i) => i + 2\n  );\n  const responses = await Promise.all(\n    remainingPages.map((page) =>\n      apiClient.get<{ message: string; data: unknown }>(url, {\n        params: { ...extraParams, page, limit: 100 },\n      })\n    )\n  );\n\n  // Concatenate in PAGE ORDER via the array index (Promise.all preserves\n  // input order regardless of resolution order).\n  for (const response of responses) {\n    const { items } = extract(response.data.data);\n    all.push(...(items ?? []));\n  }\n\n  return all;\n}\n\n/**\n * Load categories data from API and transform to CategoryConfig format\n *\n * @param apiClient - API client instance\n * @param existingCategories - Current categories array to check if already loaded\n * @returns Promise resolving to array of CategoryConfig\n *\n * @example\n * ```ts\n * const categories = await loadCategoriesData(apiClient, []);\n * ```\n */\nexport async function loadCategoriesData(\n  apiClient: BaseApiClient,\n  existingCategories: CategoryConfig[]\n): Promise<CategoryConfig[]> {\n  if (existingCategories.length > 0) {\n    return existingCategories;\n  }\n\n  const [schools, schoolYears] = await Promise.all([\n    fetchAllPages<School>(apiClient, '/school', (data) => {\n      const d = data as {\n        schools: School[];\n        pagination?: { totalPages: number };\n      };\n      return { items: d.schools, totalPages: d.pagination?.totalPages ?? 1 };\n    }),\n    fetchAllPages<SchoolYear>(apiClient, '/schoolYear', (data) => {\n      const d = data as {\n        schoolYears: SchoolYear[];\n        pagination?: { totalPages: number };\n      };\n      return {\n        items: d.schoolYears,\n        totalPages: d.pagination?.totalPages ?? 1,\n      };\n    }),\n  ]);\n\n  const transformedCategories: CategoryConfig[] = [\n    {\n      key: 'escola',\n      label: 'Escola',\n      itens: schools.map((s) => ({ id: s.id, name: s.companyName })),\n      selectedIds: [],\n    },\n    {\n      key: 'serie',\n      label: 'Série',\n      dependsOn: ['escola'],\n      filteredBy: [{ key: 'escola', internalField: 'schoolId' }],\n      itens: schoolYears.map((sy) => ({\n        id: sy.id,\n        name: sy.name,\n        schoolId: sy.schoolId,\n      })),\n      selectedIds: [],\n    },\n    {\n      key: 'turma',\n      label: 'Turma',\n      dependsOn: ['serie'],\n      filteredBy: [{ key: 'serie', internalField: 'schoolYearId' }],\n      // Classes are loaded dynamically based on selected schools/schoolYears\n      itens: [],\n      selectedIds: [],\n    },\n    {\n      key: 'students',\n      label: 'Alunos',\n      dependsOn: ['turma'],\n      filteredBy: [\n        { key: 'escola', internalField: 'escolaId' },\n        { key: 'serie', internalField: 'serieId' },\n        { key: 'turma', internalField: 'turmaId' },\n      ],\n      // Students will be loaded dynamically based on selections\n      itens: [],\n      selectedIds: [],\n    },\n  ];\n\n  return transformedCategories;\n}\n\n/**\n * Format time for display (HH:mm format)\n *\n * @param date - Date object to format\n * @returns Formatted time string in HH:mm format\n *\n * @example\n * ```ts\n * const time = formatTime(new Date('2025-01-01T14:30:00'));\n * // Returns: '14:30'\n * ```\n */\nexport function formatTime(date: Date): string {\n  const hours = date.getHours().toString().padStart(2, '0');\n  const minutes = date.getMinutes().toString().padStart(2, '0');\n  return `${hours}:${minutes}`;\n}\n","import { useCallback, useRef } from 'react';\nimport type { Dispatch, SetStateAction } from 'react';\nimport type { CategoryConfig } from '../components/CheckBoxGroup/CheckBoxGroup';\nimport type { BaseApiClient } from '../types/api';\nimport {\n  fetchStudentsByFilters,\n  fetchClassesByFilters as defaultFetchClassesByFilters,\n} from './categoryDataUtils';\nimport type { Class } from './categoryDataUtils';\nimport type {\n  FetchStudentsByFiltersFunction,\n  StudentWithNestedData,\n} from './studentTypes';\n\n/**\n * Function type for fetching classes by filters\n */\nexport type FetchClassesByFiltersFunction = (\n  apiClient: BaseApiClient,\n  filters: { schoolIds?: string[]; schoolYearIds?: string[] }\n) => Promise<Class[]>;\n\nexport interface UseDynamicStudentFetchingOptions {\n  apiClient?: BaseApiClient;\n  fetchStudentsByFilters?: FetchStudentsByFiltersFunction;\n  fetchClassesByFilters?: FetchClassesByFiltersFunction;\n  onError?: (error: Error) => void;\n}\n\n/**\n * Extract selected IDs from categories\n */\nfunction extractSelectedIds(updatedCategories: CategoryConfig[]): {\n  schoolIds: string[];\n  schoolYearIds: string[];\n  classIds: string[];\n  studentsCategory: CategoryConfig | undefined;\n} {\n  const escolaCategory = updatedCategories.find((c) => c.key === 'escola');\n  const serieCategory = updatedCategories.find((c) => c.key === 'serie');\n  const turmaCategory = updatedCategories.find((c) => c.key === 'turma');\n  const studentsCategory = updatedCategories.find((c) => c.key === 'students');\n\n  return {\n    schoolIds: escolaCategory?.selectedIds || [],\n    schoolYearIds: serieCategory?.selectedIds || [],\n    classIds: turmaCategory?.selectedIds || [],\n    studentsCategory,\n  };\n}\n\n/**\n * Detect if selections have changed compared to previous selections\n */\nfunction detectSelectionChanges(\n  previousSelections: {\n    schoolIds: string[];\n    schoolYearIds: string[];\n    classIds: string[];\n  },\n  currentSelections: {\n    schoolIds: string[];\n    schoolYearIds: string[];\n    classIds: string[];\n  }\n): {\n  schoolIdsChanged: boolean;\n  schoolYearIdsChanged: boolean;\n  classIdsChanged: boolean;\n  shouldFetchStudents: boolean;\n} {\n  const isInitialState =\n    previousSelections.schoolIds.length === 0 &&\n    previousSelections.schoolYearIds.length === 0 &&\n    previousSelections.classIds.length === 0;\n\n  const arraysEqual = (a: string[], b: string[]) => {\n    if (a.length !== b.length) return false;\n    return a.every((id) => b.includes(id)) && b.every((id) => a.includes(id));\n  };\n\n  const schoolIdsChanged =\n    isInitialState ||\n    !arraysEqual(previousSelections.schoolIds, currentSelections.schoolIds);\n\n  const schoolYearIdsChanged =\n    isInitialState ||\n    !arraysEqual(\n      previousSelections.schoolYearIds,\n      currentSelections.schoolYearIds\n    );\n\n  const classIdsChanged =\n    isInitialState ||\n    !arraysEqual(previousSelections.classIds, currentSelections.classIds);\n\n  const shouldFetchStudents =\n    schoolIdsChanged || schoolYearIdsChanged || classIdsChanged;\n\n  return {\n    schoolIdsChanged,\n    schoolYearIdsChanged,\n    classIdsChanged,\n    shouldFetchStudents,\n  };\n}\n\n/**\n * Transform students to items format with nested data\n */\nfunction transformStudentsToItems(students: StudentWithNestedData[]): Array<{\n  id: string;\n  name: string;\n  classId: string;\n  schoolId: string;\n  schoolYearId: string;\n  studentId: string;\n  userInstitutionId: string;\n  escolaId: string;\n  serieId: string;\n  turmaId: string;\n}> {\n  return students.map((s) => ({\n    id: `${s.userInstitutionId}-${s.class.id}`,\n    name: s.name,\n    classId: String(s.class.id),\n    schoolId: String(s.school.id),\n    schoolYearId: String(s.schoolYear.id),\n    studentId: s.id,\n    userInstitutionId: s.userInstitutionId,\n    escolaId: String(s.school.id),\n    serieId: String(s.schoolYear.id),\n    turmaId: String(s.class.id),\n  }));\n}\n\n/**\n * Transform classes to items format.\n *\n * Each item MUST carry `schoolYearId`: the turma category's `filteredBy` is\n * `[{ key: 'serie', internalField: 'schoolYearId' }]`, so items without it are\n * filtered out and never render.\n */\nfunction transformClassesToItems(classes: Class[]): Array<{\n  id: string;\n  name: string;\n  schoolYearId: string;\n}> {\n  return classes.map((c) => ({\n    id: c.id,\n    name: c.name,\n    schoolYearId: c.schoolYearId,\n  }));\n}\n\n/**\n * Immutably replace the `itens` of a single category (by key), leaving every\n * other category untouched. Clearing a category is `setCategoryItems(cats, key, [])`.\n */\nfunction setCategoryItems(\n  categories: CategoryConfig[],\n  key: string,\n  itens: NonNullable<CategoryConfig['itens']>\n): CategoryConfig[] {\n  return categories.map((cat) => (cat.key === key ? { ...cat, itens } : cat));\n}\n\n/**\n * Commit the new `selectedIds` from a change while preserving each category's\n * prior `itens`. The `itens` for turma/alunos are owned exclusively by the async\n * write-backs, so the eager commit must never overwrite them (which would revert\n * async-loaded options when a rapid second call carries a stale snapshot).\n */\nfunction commitSelectionsPreservingItems(\n  updatedCategories: CategoryConfig[],\n  prev: CategoryConfig[]\n): CategoryConfig[] {\n  return updatedCategories.map((cat) => {\n    const prior = prev.find((p) => p.key === cat.key);\n    return prior ? { ...cat, itens: prior.itens } : cat;\n  });\n}\n\n/**\n * Hook to dynamically load BOTH turmas and alunos based on category selections.\n *\n * This hook provides a `handleCategoriesChange` function that:\n * - Detects changes in school/series/class selections\n * - Fetches turmas (classes) when the school/série selection changes and a série\n *   is selected; clears turmas when the série selection becomes empty\n * - Fetches alunos (students) only when school/series/class selections change and\n *   a turma is selected (not when only students are toggled); clears alunos otherwise\n * - Writes each fetched set back into ONLY its own category via functional state\n *   updates, so a late turma response never clobbers a student write and vice-versa\n * - Transforms fetched turmas/alunos into the correct format for CategoryConfig\n *   (turma items carry `schoolYearId` so the turma `filteredBy` does not hide them)\n * - Uses separate request-id guards for turmas and alunos to drop stale responses\n * - Handles errors gracefully\n *\n * @param setCategories - React state setter for categories (supports functional updates)\n * @param options - Configuration options\n * @returns Object with handleCategoriesChange function\n */\nexport function useDynamicStudentFetching(\n  setCategories: Dispatch<SetStateAction<CategoryConfig[]>>,\n  options: UseDynamicStudentFetchingOptions = {}\n): {\n  handleCategoriesChange: (\n    updatedCategories: CategoryConfig[]\n  ) => Promise<void>;\n} {\n  const {\n    apiClient,\n    fetchStudentsByFilters: customFetchStudents,\n    fetchClassesByFilters: fetchClasses = defaultFetchClassesByFilters,\n    onError,\n  } = options;\n\n  // Refs to track previous selections and prevent unnecessary API calls\n  const previousSelectionsRef = useRef<{\n    schoolIds: string[];\n    schoolYearIds: string[];\n    classIds: string[];\n  }>({\n    schoolIds: [],\n    schoolYearIds: [],\n    classIds: [],\n  });\n\n  // Refs to track fetch request IDs and prevent race conditions.\n  // Separate ids for turmas and alunos so the two async writes never invalidate\n  // each other.\n  const fetchRequestId = useRef(0);\n  const fetchClassesRequestId = useRef(0);\n\n  /**\n   * Build filters object for student fetching\n   */\n  const buildStudentFilters = useCallback(\n    (\n      selectedSchoolIds: string[],\n      selectedSchoolYearIds: string[],\n      selectedClassIds: string[]\n    ) => ({\n      schoolIds: selectedSchoolIds.length > 0 ? selectedSchoolIds : undefined,\n      schoolYearIds:\n        selectedSchoolYearIds.length > 0 ? selectedSchoolYearIds : undefined,\n      classIds: selectedClassIds.length > 0 ? selectedClassIds : undefined,\n    }),\n    []\n  );\n\n  /**\n   * Fetch students using custom function\n   */\n  const fetchWithCustomFunction = useCallback(\n    async (\n      selectedSchoolIds: string[],\n      selectedSchoolYearIds: string[],\n      selectedClassIds: string[],\n      localRequestId: number\n    ): Promise<StudentWithNestedData[] | null> => {\n      if (!customFetchStudents) {\n        return null;\n      }\n\n      const filters = buildStudentFilters(\n        selectedSchoolIds,\n        selectedSchoolYearIds,\n        selectedClassIds\n      );\n      const students = await customFetchStudents(filters);\n\n      if (localRequestId !== fetchRequestId.current) {\n        return null;\n      }\n\n      return students;\n    },\n    [customFetchStudents, buildStudentFilters]\n  );\n\n  /**\n   * Fetch students using API client\n   */\n  const fetchWithApiClient = useCallback(\n    async (\n      selectedSchoolIds: string[],\n      selectedSchoolYearIds: string[],\n      selectedClassIds: string[],\n      localRequestId: number\n    ): Promise<StudentWithNestedData[] | null> => {\n      if (!apiClient) {\n        return null;\n      }\n\n      const filters = buildStudentFilters(\n        selectedSchoolIds,\n        selectedSchoolYearIds,\n        selectedClassIds\n      );\n      const students = await fetchStudentsByFilters(apiClient, filters);\n\n      if (localRequestId !== fetchRequestId.current) {\n        return null;\n      }\n\n      return students;\n    },\n    [apiClient, buildStudentFilters]\n  );\n\n  /**\n   * Fetch students using the appropriate method (custom function or API client)\n   */\n  const performStudentFetch = useCallback(\n    async (\n      selectedSchoolIds: string[],\n      selectedSchoolYearIds: string[],\n      selectedClassIds: string[],\n      localRequestId: number\n    ): Promise<StudentWithNestedData[] | null> => {\n      const students = await fetchWithCustomFunction(\n        selectedSchoolIds,\n        selectedSchoolYearIds,\n        selectedClassIds,\n        localRequestId\n      );\n\n      if (students !== null) {\n        return students;\n      }\n\n      return fetchWithApiClient(\n        selectedSchoolIds,\n        selectedSchoolYearIds,\n        selectedClassIds,\n        localRequestId\n      );\n    },\n    [fetchWithCustomFunction, fetchWithApiClient]\n  );\n\n  /**\n   * Fetch classes (turmas) filtered by selected schools/schoolYears\n   */\n  const performClassFetch = useCallback(\n    async (\n      selectedSchoolIds: string[],\n      selectedSchoolYearIds: string[],\n      localRequestId: number\n    ): Promise<Class[] | null> => {\n      if (!apiClient) {\n        return null;\n      }\n\n      const filters = {\n        schoolIds: selectedSchoolIds.length > 0 ? selectedSchoolIds : undefined,\n        schoolYearIds:\n          selectedSchoolYearIds.length > 0 ? selectedSchoolYearIds : undefined,\n      };\n      const classes = await fetchClasses(apiClient, filters);\n\n      if (localRequestId !== fetchClassesRequestId.current) {\n        return null;\n      }\n\n      return classes;\n    },\n    [apiClient, fetchClasses]\n  );\n\n  /**\n   * Handle successful student fetch. Patches ONLY the students category on top of\n   * the latest state so a concurrent turma write is not clobbered.\n   */\n  const handleSuccessfulFetch = useCallback(\n    (students: StudentWithNestedData[], localRequestId: number): boolean => {\n      if (localRequestId !== fetchRequestId.current) {\n        return false;\n      }\n\n      const studentItems = transformStudentsToItems(students);\n      setCategories((prev) => setCategoryItems(prev, 'students', studentItems));\n      return true;\n    },\n    [setCategories]\n  );\n\n  /**\n   * Handle error during student fetch\n   */\n  const handleFetchError = useCallback(\n    (error: unknown, localRequestId: number): boolean => {\n      console.error('Error fetching students:', error);\n      if (onError && error instanceof Error) {\n        onError(error);\n      }\n\n      if (localRequestId !== fetchRequestId.current) {\n        return false;\n      }\n\n      setCategories((prev) => setCategoryItems(prev, 'students', []));\n      return true;\n    },\n    [onError, setCategories]\n  );\n\n  /**\n   * Handle successful class fetch. Patches ONLY the turma category on top of the\n   * latest state so a concurrent student write is not clobbered.\n   */\n  const handleSuccessfulClassFetch = useCallback(\n    (classes: Class[], localRequestId: number): boolean => {\n      if (localRequestId !== fetchClassesRequestId.current) {\n        return false;\n      }\n\n      const classItems = transformClassesToItems(classes);\n      setCategories((prev) => setCategoryItems(prev, 'turma', classItems));\n      return true;\n    },\n    [setCategories]\n  );\n\n  /**\n   * Handle error during class fetch\n   */\n  const handleClassFetchError = useCallback(\n    (error: unknown, localRequestId: number): boolean => {\n      console.error('Error fetching classes:', error);\n      if (onError && error instanceof Error) {\n        onError(error);\n      }\n\n      if (localRequestId !== fetchClassesRequestId.current) {\n        return false;\n      }\n\n      setCategories((prev) => setCategoryItems(prev, 'turma', []));\n      return true;\n    },\n    [onError, setCategories]\n  );\n\n  /**\n   * Fetch turmas (or clear them) in response to a school/série selection change\n   */\n  const handleClassesChange = useCallback(\n    async (\n      selectedSchoolIds: string[],\n      selectedSchoolYearIds: string[]\n    ): Promise<void> => {\n      // No apiClient => this consumer manages `turma` itself (e.g. AlertsManager\n      // with pre-populated categories). Never fetch OR clear turma in that case.\n      if (!apiClient) return;\n\n      // Turma depends on a selected série: fetch only when a série is selected.\n      if (selectedSchoolYearIds.length > 0) {\n        fetchClassesRequestId.current += 1;\n        const localRequestId = fetchClassesRequestId.current;\n\n        try {\n          const classes = await performClassFetch(\n            selectedSchoolIds,\n            selectedSchoolYearIds,\n            localRequestId\n          );\n\n          if (classes === null) {\n            return; // Request was invalidated\n          }\n\n          handleSuccessfulClassFetch(classes, localRequestId);\n        } catch (error) {\n          handleClassFetchError(error, localRequestId);\n        }\n      } else {\n        // Série selection became empty -> reset turma options\n        fetchClassesRequestId.current += 1;\n        setCategories((prev) => setCategoryItems(prev, 'turma', []));\n      }\n    },\n    [\n      apiClient,\n      performClassFetch,\n      handleSuccessfulClassFetch,\n      handleClassFetchError,\n      setCategories,\n    ]\n  );\n\n  /**\n   * Fetch alunos (or clear them) in response to a selection change\n   */\n  const handleStudentsChange = useCallback(\n    async (\n      selectedSchoolIds: string[],\n      selectedSchoolYearIds: string[],\n      selectedClassIds: string[],\n      studentsCategory: CategoryConfig | undefined\n    ): Promise<void> => {\n      if (selectedClassIds.length > 0 && studentsCategory) {\n        // Increment request ID to invalidate any in-flight requests\n        fetchRequestId.current += 1;\n        const localRequestId = fetchRequestId.current;\n\n        try {\n          const students = await performStudentFetch(\n            selectedSchoolIds,\n            selectedSchoolYearIds,\n            selectedClassIds,\n            localRequestId\n          );\n\n          if (students === null) {\n            return; // Request was invalidated\n          }\n\n          handleSuccessfulFetch(students, localRequestId);\n        } catch (error) {\n          handleFetchError(error, localRequestId);\n        }\n      } else if (studentsCategory) {\n        // If no classes selected after a change, clear students\n        fetchRequestId.current += 1;\n        setCategories((prev) => setCategoryItems(prev, 'students', []));\n      }\n    },\n    [\n      performStudentFetch,\n      handleSuccessfulFetch,\n      handleFetchError,\n      setCategories,\n    ]\n  );\n\n  const handleCategoriesChange = useCallback(\n    async (updatedCategories: CategoryConfig[]) => {\n      // If no fetch function is provided, just update categories\n      if (!customFetchStudents && !apiClient) {\n        setCategories(updatedCategories);\n        return;\n      }\n\n      // Extract selected IDs from categories\n      const {\n        schoolIds: selectedSchoolIds,\n        schoolYearIds: selectedSchoolYearIds,\n        classIds: selectedClassIds,\n        studentsCategory,\n      } = extractSelectedIds(updatedCategories);\n\n      // Detect if selections have changed\n      const previousSelections = previousSelectionsRef.current;\n      const { schoolIdsChanged, schoolYearIdsChanged, shouldFetchStudents } =\n        detectSelectionChanges(previousSelections, {\n          schoolIds: selectedSchoolIds,\n          schoolYearIds: selectedSchoolYearIds,\n          classIds: selectedClassIds,\n        });\n\n      // Update previous selections\n      previousSelectionsRef.current = {\n        schoolIds: [...selectedSchoolIds],\n        schoolYearIds: [...selectedSchoolYearIds],\n        classIds: [...selectedClassIds],\n      };\n\n      // Commit the new selections immediately, but NEVER the snapshot's `itens`\n      // (owned exclusively by the async write-backs below). This keeps the\n      // no-clobber invariant regardless of caller timing.\n      setCategories((prev) =>\n        commitSelectionsPreservingItems(updatedCategories, prev)\n      );\n\n      // Dynamic TURMA fetching: react to school/série selection changes\n      if (schoolIdsChanged || schoolYearIdsChanged) {\n        await handleClassesChange(selectedSchoolIds, selectedSchoolYearIds);\n      }\n\n      // Dynamic ALUNOS fetching: react to school/série/turma selection changes\n      // (skipped when only student selections changed)\n      if (shouldFetchStudents) {\n        await handleStudentsChange(\n          selectedSchoolIds,\n          selectedSchoolYearIds,\n          selectedClassIds,\n          studentsCategory\n        );\n      }\n    },\n    [\n      apiClient,\n      customFetchStudents,\n      setCategories,\n      handleClassesChange,\n      handleStudentsChange,\n    ]\n  );\n\n  return {\n    handleCategoriesChange,\n  };\n}\n"],"mappings":"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","names":[]}