<template>
  <div>
    <UTable :data="tableData" :columns="tableColumns" class="w-full" :ui="{ td: 'p-2' }">
      <template v-for="col in dataColumns" :key="col.key" #[`${col.key}-cell`]="slotProps">
        <!-- Column with cross-reference -->
        <USelectMenu
          v-if="hasColumnReference(col.colIndex)"
          :model-value="getCellValueForSelect(slotProps.row as TableRow<TableRowData>, col.key, col.colIndex)"
          :items="getColumnOptions(col.colIndex, (slotProps.row as TableRow<TableRowData>).original)"
          :disabled="disabled"
          :placeholder="$t('applicationForms.formElements.table.selectValue')"
          :multiple="isColumnMultipleAllowed(col.colIndex)"
          class="w-full min-w-32"
          @update:model-value="
            (val: string | string[]) =>
              $emit('update:cellValue', (slotProps.row as TableRow<TableRowData>).index, col.key, col.colIndex, val)
          "
        />
        <!-- Read-only column -->
        <span v-else-if="isColumnReadOnly(col.colIndex)" class="text-muted px-2 py-1">
          {{ formatCellDisplay(slotProps.row as any, col.key, col.colIndex) }}
        </span>
        <!-- Checkbox column -->
        <div v-else-if="isColumnCheckbox(col.colIndex)" class="flex justify-center">
          <UCheckbox
            :model-value="getCellValueForCheckbox(slotProps.row as TableRow<TableRowData>, col.key)"
            :disabled="disabled"
            @update:model-value="
              (val: boolean | 'indeterminate') =>
                $emit(
                  'update:checkboxCell',
                  (slotProps.row as TableRow<TableRowData>).index,
                  col.colIndex,
                  val === true
                )
            "
          />
        </div>
        <!-- Regular text input with auto-resizing textarea -->
        <UTextarea
          v-else
          :model-value="getCellValue(slotProps.row as TableRow<TableRowData>, col.key)"
          :disabled="disabled"
          :rows="1"
          autoresize
          :maxrows="0"
          class="w-full min-w-32"
          @update:model-value="
            (val: string | number) =>
              $emit('update:cell', (slotProps.row as TableRow<TableRowData>).index, col.key, String(val))
          "
        />
      </template>
      <template v-if="canModifyRows" #actions-cell="{ row }">
        <UButton
          v-if="!disabled"
          icon="i-lucide-trash-2"
          color="error"
          variant="ghost"
          size="xs"
          :aria-label="$t('applicationForms.formElements.table.removeRow')"
          @click="$emit('removeRow', row.index)"
        />
      </template>
    </UTable>

    <div v-if="tableData.length === 0" class="text-center text-dimmed py-4">
      {{ $t('applicationForms.formElements.table.noData') }}
    </div>

    <UButton
      v-if="!disabled && canModifyRows"
      variant="outline"
      size="sm"
      leading-icon="i-lucide-plus"
      :class="addRowButtonClass"
      @click="$emit('addRow')"
    >
      {{ $t('applicationForms.formElements.table.addRow') }}
    </UButton>
  </div>
</template>

<script setup lang="ts">
import type { FormOptionDto } from '~~/.api-client'
import type { TableColumn, TableRow } from '@nuxt/ui'

type CellValue = string | string[] | boolean
type TableRowData = Record<string, CellValue>

interface DataColumn {
  key: string
  colIndex: number
}

const props = defineProps<{
  tableData: TableRowData[]
  tableColumns: TableColumn<TableRowData>[]
  dataColumns: DataColumn[]
  formOptions: FormOptionDto[]
  disabled?: boolean
  canModifyRows: boolean
  addRowButtonClass?: string
  getColumnOptions: (colIndex: number, currentRowData?: TableRowData) => string[]
}>()

defineEmits<{
  (e: 'update:cell', rowIndex: number, columnKey: string, value: string): void
  (e: 'update:cellValue', rowIndex: number, columnKey: string, colIndex: number, value: string | string[]): void
  (e: 'update:checkboxCell', rowIndex: number, colIndex: number, value: boolean): void
  (e: 'addRow'): void
  (e: 'removeRow', rowIndex: number): void
}>()

function hasColumnReference(colIndex: number): boolean {
  const option = props.formOptions[colIndex]
  return !!option?.columnConfig?.sourceTableReference && !isColumnReadOnly(colIndex)
}

function isColumnReadOnly(colIndex: number): boolean {
  const option = props.formOptions[colIndex]
  return option?.columnConfig?.isReadOnly === true
}

function isColumnMultipleAllowed(colIndex: number): boolean {
  const option = props.formOptions[colIndex]
  return option?.columnConfig?.isMultipleAllowed === true
}

function isColumnCheckbox(colIndex: number): boolean {
  const option = props.formOptions[colIndex]
  return option?.columnConfig?.isCheckbox === true
}

function getCellValue(row: TableRow<TableRowData>, columnKey: string): string {
  const value = row.original[columnKey]
  return typeof value === 'string' ? value : ''
}

function getCellValueForSelect(row: TableRow<TableRowData>, columnKey: string, colIndex: number): string | string[] {
  const value = row.original[columnKey]
  if (isColumnMultipleAllowed(colIndex)) {
    return Array.isArray(value) ? value : []
  }
  return typeof value === 'string' ? value : ''
}

function getCellValueForCheckbox(row: TableRow<TableRowData>, columnKey: string): boolean {
  const value = row.original[columnKey]
  return value === true
}

function formatCellDisplay(row: TableRow<TableRowData>, columnKey: string, colIndex: number): string {
  const value = row.original[columnKey]
  if (isColumnMultipleAllowed(colIndex) && Array.isArray(value)) {
    return value.length > 0 ? value.join(', ') : '-'
  }
  return (typeof value === 'string' ? value : '') || '-'
}
</script>
