<script setup lang="ts" generic="TData, TValue">
import { defineProps } from 'vue'
import type { DefineComponent } from 'vue'
import type { ColumnDef } from '@tanstack/vue-table'
import {
  useVueTable,
  getCoreRowModel,
  FlexRender,
} from '@tanstack/vue-table'

import {
  Table, TableHeader, TableRow, TableHead, TableBody, TableCell,
} from '@/components/ui/table'
import { ScrollArea, ScrollBar } from '@/components/ui/scroll-area' // <-- add ScrollBar

const props = defineProps<{
  columns: ColumnDef<TData, TValue>[]
  data: TData[]
  dropdownComponent?: DefineComponent<{ row: TData }, any, any>
  dropdownProps?: Record<string, any>
  /** Optional tailwind class to control min table width for horizontal scrolling */
  minTableWidth?: string
}>()

const table = useVueTable({
  get data() { return props.data },
  get columns() { return props.columns },
  getCoreRowModel: getCoreRowModel(),
})

const emit = defineEmits<{
  (e: 'row-updated', row: TData, payload: any): void
  (e: 'row-deleted', row: TData): void
}>()

const minWidthClass = props.minTableWidth ?? 'min-w-[1100px]' // tweak as needed
</script>

<template>
  <!-- Parent must not rely on h-full; use overflow-hidden to contain scrollbars -->
  <div class="w-full max-h-full border rounded-md flex flex-col overflow-hidden">
    <!-- This element grows and can scroll internally -->
    <ScrollArea class="flex-1 min-h-0 w-full">
      <!-- min-width keeps horizontal scroll available when needed -->
      <div :class="['w-full', minWidthClass]">
        <!-- separate borders help sticky headers render above rows -->
        <Table class="w-full border-separate border-spacing-0">
          <TableHeader>
            <TableRow v-for="headerGroup in table.getHeaderGroups()" :key="headerGroup.id">
              <TableHead
                v-for="header in headerGroup.headers"
                :key="header.id"
                class="sticky top-0 bg-background z-10 whitespace-nowrap"
              >
                <FlexRender
                  v-if="!header.isPlaceholder"
                  :render="header.column.columnDef.header"
                  :props="header.getContext()"
                />
              </TableHead>
              <TableHead
                v-if="props.dropdownComponent"
                class="sticky top-0 bg-background z-10 w-12"
              />
            </TableRow>
          </TableHeader>

          <TableBody>
            <template v-if="table.getRowModel().rows.length">
              <TableRow
                v-for="row in table.getRowModel().rows"
                :key="row.id"
                class="whitespace-nowrap"
              >
                <TableCell v-for="cell in row.getVisibleCells()" :key="cell.id">
                  <FlexRender :render="cell.column.columnDef.cell" :props="cell.getContext()" />
                </TableCell>

                <TableCell v-if="props.dropdownComponent" class="text-right">
                  <component
                    :is="props.dropdownComponent"
                    :row="row.original"
                    v-bind="props.dropdownProps"
                    @updated="(payload: any) => emit('row-updated', row.original, payload)"
                    @deleted="() => emit('row-deleted', row.original)"
                  />
                </TableCell>
              </TableRow>
            </template>

            <template v-else>
              <TableRow>
                <TableCell
                  :colspan="props.columns.length + (props.dropdownComponent ? 1 : 0)"
                  class="h-24 text-center"
                >
                  No data.
                </TableCell>
              </TableRow>
            </template>
          </TableBody>
        </Table>
      </div>

      <!-- Always show both scrollbars when needed -->
      <ScrollBar orientation="horizontal" />
      <ScrollBar orientation="vertical" />
    </ScrollArea>
  </div>
</template>