import type { KbxLookupDefinition } from './lookup'
import type { KbxStatusDefinition } from './status'

export type KbxGridType =
  | 'text' | 'code' | 'integer' | 'decimal' | 'quantity' | 'money'
  | 'percent' | 'date' | 'datetime' | 'boolean' | 'status' | 'lookup' | 'link'

export type KbxGridDensity = 'compact' | 'comfortable'

export interface KbxGridStatusMap {
  definitions: readonly KbxStatusDefinition[]
  unknownLabel?: string
}

export interface KbxGridColumn<T> {
  field: keyof T & string
  header: string
  type?: KbxGridType
  width?: number
  minWidth?: number
  maxWidth?: number
  pinned?: 'left' | 'right'
  editable?: boolean | ((row: T) => boolean)
  sortable?: boolean
  filterable?: boolean
  permission?: string
  lookup?: KbxLookupDefinition
  /** type='status'일 때 Domain raw value를 사용자 Label/Semantic으로 변환한다. Row 원본은 변경하지 않는다. */
  statusMap?: KbxGridStatusMap
  drilldown?: boolean
}

export interface KbxGridColumnPreference {
  field: string
  order: number
  width?: number
  pinned?: 'left' | 'right' | null
  hidden?: boolean
  sort?: 'asc' | 'desc' | null
  sortIndex?: number | null
}

export interface KbxGridCellRef<T = string> {
  rowKey: T
  field: string
}

export interface KbxGridSummary<T> {
  key: string
  label: string
  field?: keyof T & string
  kind: 'count' | 'sum' | 'custom'
  value?: string | number
}

/** Browser에는 현재 선택 상태만 유지한다. all-filtered에서 전체 ID를 적재하지 않는다. */
export interface KbxSelectionState<TId = string> {
  mode: 'explicit' | 'all-filtered'
  selectedIds: TId[]
  excludedIds?: TId[]
}

/** Server-side bulk command의 canonical selection envelope. */
export interface KbxBulkSelectionRequest<TFilter = Record<string, unknown>, TId = string> {
  mode: 'ids' | 'filter'
  ids?: TId[]
  filter?: TFilter
  excludedIds?: TId[]
}

export interface KbxGridEditingPolicy {
  allowRowAdd?: boolean
  allowRowDuplicate?: boolean
  fillDown?: boolean
  paste?: boolean
  errorNavigation?: boolean
}

export interface KbxGridPasteIssue {
  rowOffset: number
  columnOffset: number
  field?: string
  code: 'INVALID_NUMBER' | 'INVALID_DATE' | 'INVALID_BOOLEAN'
  value: unknown
}

export interface KbxGridPasteResult {
  cellCount: number
  normalizedCount: number
  rejectedCount: number
  issues: KbxGridPasteIssue[]
}

export interface KbxGridContextRequest<T> {
  row: T
  field: keyof T & string
  clientX: number
  clientY: number
}
