/**
 * Shared client-side table view logic (sort, page size, view-all cap).
 * Admin list pages load full datasets then slice in the browser (see Procedures API).
 */

/** Hard cap when "View All" is active — avoids rendering thousands of DOM rows at once. */
export const MAX_VIEW_ALL_ITEMS = 200

export const DEFAULT_PAGE_SIZE_OPTIONS = [6, 10, 20, 50, 100] as const

export type DashboardTablePageSize = (typeof DEFAULT_PAGE_SIZE_OPTIONS)[number]

export interface DashboardTableViewPersistedState {
  sortKey: string
  itemsPerPage: number
  viewAll: boolean
  currentPage: number
}

export interface DashboardTableSliceResult<T> {
  displayed: T[]
  displayedCount: number
  totalItems: number
  viewAllActive: boolean
  /** True when filtered total exceeds MAX_VIEW_ALL_ITEMS while view-all is on */
  viewAllCapped: boolean
}

export function getDashboardTableStorageKey(tableId: string) {
  return `dashboard-table-view:${tableId}`
}

export function readPersistedTableView(
  tableId: string,
  fallback: DashboardTableViewPersistedState,
): DashboardTableViewPersistedState {
  if (typeof window === "undefined") return fallback
  try {
    const raw = sessionStorage.getItem(getDashboardTableStorageKey(tableId))
    if (!raw) return fallback
    const parsed = JSON.parse(raw) as Partial<DashboardTableViewPersistedState>
    return {
      sortKey: typeof parsed.sortKey === "string" ? parsed.sortKey : fallback.sortKey,
      itemsPerPage:
        typeof parsed.itemsPerPage === "number" && parsed.itemsPerPage > 0
          ? parsed.itemsPerPage
          : fallback.itemsPerPage,
      viewAll: Boolean(parsed.viewAll),
      currentPage:
        typeof parsed.currentPage === "number" && parsed.currentPage >= 1
          ? parsed.currentPage
          : fallback.currentPage,
    }
  } catch {
    return fallback
  }
}

export function writePersistedTableView(tableId: string, state: DashboardTableViewPersistedState) {
  if (typeof window === "undefined") return
  try {
    sessionStorage.setItem(getDashboardTableStorageKey(tableId), JSON.stringify(state))
  } catch {
    // ignore quota / private mode
  }
}

export function sortDashboardItems<T>(
  items: T[],
  sortKey: string,
  comparators: Record<string, (a: T, b: T) => number>,
): T[] {
  const compare = comparators[sortKey]
  if (!compare) return [...items]
  return [...items].sort(compare)
}

export function sliceDashboardItems<T>(
  items: T[],
  options: {
    currentPage: number
    itemsPerPage: number
    viewAll: boolean
    maxViewAll?: number
  },
): DashboardTableSliceResult<T> {
  const totalItems = items.length
  const maxViewAll = options.maxViewAll ?? MAX_VIEW_ALL_ITEMS

  if (options.viewAll) {
    const displayed = items.slice(0, maxViewAll)
    return {
      displayed,
      displayedCount: displayed.length,
      totalItems,
      viewAllActive: true,
      viewAllCapped: totalItems > maxViewAll,
    }
  }

  const totalPages = Math.max(1, Math.ceil(totalItems / options.itemsPerPage) || 1)
  const safePage = Math.min(Math.max(1, options.currentPage), totalPages)
  const start = (safePage - 1) * options.itemsPerPage
  const displayed = items.slice(start, start + options.itemsPerPage)

  return {
    displayed,
    displayedCount: displayed.length,
    totalItems,
    viewAllActive: false,
    viewAllCapped: false,
  }
}

export function getDashboardTotalPages(totalItems: number, itemsPerPage: number) {
  if (totalItems === 0) return 1
  return Math.max(1, Math.ceil(totalItems / itemsPerPage))
}
