<script setup lang="ts">
import { computed } from 'vue'
import { AgGridVue } from 'ag-grid-vue3'
import {
  ClientSideRowModelModule,
  ColumnAutoSizeModule,
  CellStyleModule,
  ValidationModule,
  TextFilterModule,
  themeQuartz,
  ModuleRegistry,
  RowSelectionModule,
  type ColDef,
  type RowClickedEvent
} from 'ag-grid-community'
import type { UiGridColumn } from '../contracts'

ModuleRegistry.registerModules([
  ClientSideRowModelModule,
  ColumnAutoSizeModule,
  CellStyleModule,
  ValidationModule,
  TextFilterModule,
  RowSelectionModule
])

const props = withDefaults(defineProps<{
  rows: unknown[]
  columns: UiGridColumn[]
  loading?: boolean
  height?: string
  rowSelection?: 'single' | 'multiple' | 'none'
}>(), { loading: false, height: '32rem', rowSelection: 'single' })

const emit = defineEmits<{ rowSelected: [row: unknown] }>()

const columnDefs = computed<ColDef[]>(() => props.columns.map(column => ({
  field: column.field,
  headerName: column.header,
  width: column.width,
  minWidth: column.minWidth ?? 120,
  sortable: column.sortable ?? true,
  filter: column.filterable ?? true,
  valueFormatter: column.formatter
    ? params => column.formatter?.(params.value, params.data) ?? ''
    : undefined
})))

const rowSelectionOptions = computed(() => {
  if (props.rowSelection === 'none') return undefined
  return props.rowSelection === 'multiple'
    ? ({ mode: 'multiRow' } as const)
    : ({ mode: 'singleRow' } as const)
})

function onRowClicked(event: RowClickedEvent): void {
  if (event.data) emit('rowSelected', event.data)
}
</script>

<template>
  <div class="ks-grid" :style="{ height }" :aria-busy="loading">
    <AgGridVue
      style="height: 100%; width: 100%"
      :theme="themeQuartz"
      :row-data="rows"
      :column-defs="columnDefs"
      :row-selection="rowSelectionOptions"
      :loading="loading"
      :suppress-no-rows-overlay="rows.length > 0"
      @row-clicked="onRowClicked"
    />
  </div>
</template>

<style scoped>
.ks-grid {
  min-height: 12rem;
  border: 1px solid var(--ks-color-neutral-200);
  border-radius: var(--ks-radius-md);
  overflow: hidden;
  background: #fff;
}
</style>
