/**
 * Shared sorting utilities for data-table and data-grid components
 * @countermeasure/web-components/utils/sorting
 */

export type SortDirection = 'asc' | 'desc' | null

export interface SortState {
  key: string
  direction: 'asc' | 'desc'
}

/** Convert a cell value to a comparable string */
function toComparableString(val: unknown): string {
  if (val === null || val === undefined) return ''
  if (typeof val === 'string' || typeof val === 'number' || typeof val === 'boolean') {
    return String(val)
  }
  return JSON.stringify(val)
}

/**
 * Compare two unknown cell values with numeric-aware comparison.
 * Returns negative if a < b, positive if a > b, zero if equal.
 */
export function compareValues(a: unknown, b: unknown): number {
  const aStr = toComparableString(a)
  const bStr = toComparableString(b)

  const aNum = Number(aStr)
  const bNum = Number(bStr)

  if (!Number.isNaN(aNum) && !Number.isNaN(bNum) && aStr !== '' && bStr !== '') {
    return aNum - bNum
  }
  return aStr.localeCompare(bStr)
}

/**
 * Sort an array of rows by a key, using an accessor to extract the value.
 * Returns a new sorted array (does not mutate the input).
 */
export function sortRows<T>(
  rows: T[],
  direction: 'asc' | 'desc',
  accessor: (row: T) => unknown
): T[] {
  const sorted = [...rows]
  sorted.sort((a, b) => {
    const result = compareValues(accessor(a), accessor(b))
    return direction === 'desc' ? -result : result
  })
  return sorted
}

/**
 * Cycle sort direction through: null → 'asc' → 'desc' → null
 * Given the current state for a column key, returns the next state.
 */
export function cycleSortDirection(
  currentKey: string | null,
  currentDirection: SortDirection,
  targetKey: string
): SortState | null {
  if (currentKey !== targetKey) {
    return { key: targetKey, direction: 'asc' }
  }
  if (currentDirection === 'asc') {
    return { key: targetKey, direction: 'desc' }
  }
  // desc → null (clear sort)
  return null
}
