import type { Meta, StoryObj } from '@storybook/vue3-vite';
import type { ColumnDef } from '@aleph-alpha/ui-library';
import { computed, h, ref } from 'vue';
import {
  UiDataTable,
  UiDataTableColumnFilter,
  UiDataTableColumnHeader,
  UiDataTablePagination,
  UiDataTableToolbar,
} from './index';
import { UiBadge } from '@/components/UiBadge';
import { UiCheckbox } from '@/components/UiCheckbox';
import { UiButton } from '@/components/UiButton';
import { UiIcon } from '@/components/UiIcon';
import { UiInput } from '@/components/UiInput';
import {
  UiDropdownMenu,
  UiDropdownMenuContent,
  UiDropdownMenuItem,
  UiDropdownMenuLabel,
  UiDropdownMenuSeparator,
  UiDropdownMenuTrigger,
} from '@/components/UiDropdownMenu';
import {
  payments,
  paymentsMedium,
  datasetOptions,
  type Payment,
} from './UiDataTable.mock';

// Basic columns
const basicColumns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: 'Status',
    cell: ({ row }) =>
      h('div', { class: 'capitalize' }, row.getValue('status')),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: 'Email',
    cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: () => h('div', { class: 'text-right' }, 'Amount'),
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'));
      const formatted = new Intl.NumberFormat('de-DE', {
        style: 'currency',
        currency: 'EUR',
      }).format(amount);
      return h('div', { class: 'text-right font-medium' }, formatted);
    },
    size: 120,
  },
];

// Sortable columns using UiDataTableColumnHeader
const sortableColumns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, { column, title: 'Status' }),
    cell: ({ row }) =>
      h('div', { class: 'capitalize' }, row.getValue('status')),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, { column, title: 'Email' }),
    cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, {
        column,
        title: 'Amount',
        class: 'justify-end',
      }),
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'));
      const formatted = new Intl.NumberFormat('de-DE', {
        style: 'currency',
        currency: 'EUR',
      }).format(amount);
      return h('div', { class: 'text-right font-medium' }, formatted);
    },
    size: 120,
  },
];

// Columns with selection using UiDataTableColumnHeader
const selectableColumns: ColumnDef<Payment>[] = [
  {
    id: 'select',
    header: ({ table }) =>
      h(UiCheckbox, {
        modelValue:
          table.getIsAllPageRowsSelected() ||
          (table.getIsSomePageRowsSelected() && 'indeterminate'),
        'onUpdate:modelValue': (value: boolean) =>
          table.toggleAllPageRowsSelected(!!value),
        ariaLabel: 'Select all',
        name: 'select-all',
      }),
    cell: ({ row }) =>
      h(UiCheckbox, {
        modelValue: row.getIsSelected(),
        'onUpdate:modelValue': (value: boolean) => row.toggleSelected(!!value),
        ariaLabel: 'Select row',
        name: `select-${row.id}`,
      }),
    enableSorting: false,
    enableHiding: false,
    size: 40,
  },
  {
    accessorKey: 'status',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, { column, title: 'Status' }),
    cell: ({ row }) =>
      h('div', { class: 'capitalize' }, row.getValue('status')),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, { column, title: 'Email' }),
    cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, {
        column,
        title: 'Amount',
        class: 'justify-end',
      }),
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'));
      const formatted = new Intl.NumberFormat('de-DE', {
        style: 'currency',
        currency: 'EUR',
      }).format(amount);
      return h('div', { class: 'text-right font-medium' }, formatted);
    },
    size: 120,
  },
];

// Column options for controls
const columnOptions = {
  Basic: basicColumns,
  Sortable: sortableColumns,
  'With Selection': selectableColumns,
} as const;

const meta = {
  title: 'Patterns/UiDataTable',
  component: UiDataTable,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component:
          'A powerful data table component built with TanStack Table and Vue 3. Supports sorting, pagination, filtering, and row selection. Use `UiDataTable` for the core table, `UiDataTablePagination` for pagination controls, and `UiDataTableToolbar` for search and filters.',
      },
    },
  },
  argTypes: {
    columns: {
      control: 'select',
      options: Object.keys(columnOptions),
      mapping: columnOptions,
      description:
        'The column definitions for the table. Select from predefined configurations.',
    },
    data: {
      control: 'select',
      options: Object.keys(datasetOptions),
      mapping: datasetOptions,
      description:
        'The data to display in the table. Select from predefined datasets.',
    },
    emptyText: {
      control: 'text',
      description: 'Text to display when there are no results.',
    },
    tableMinHeight: {
      control: 'text',
      description:
        'Minimum height for the table container. Useful for preventing layout shifts during pagination. The last row will have a visible bottom border even when the container is taller than the content.',
    },
  },
  args: {
    data: 'Large (100 items)',
    columns: 'Sortable',
  },
} satisfies Meta<typeof UiDataTable>;

export default meta;
type Story = StoryObj<typeof meta>;

// Templates for source code display
const basicTemplateSource = `<script setup lang="ts">
import { UiDataTable } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
];

const columns: ColumnDef<Payment>[] = [
  { accessorKey: 'status', header: 'Status' },
  { accessorKey: 'email', header: 'Email' },
  { accessorKey: 'amount', header: 'Amount' },
];
</script>

<template>
  <UiDataTable :data="data" :columns="columns" />
</template>`;

const withSortingTemplateSource = `<script setup lang="ts">
import { h } from 'vue';
import { UiDataTable, UiDataTableColumnHeader } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
];

// Use UiDataTableColumnHeader for sortable columns (click to cycle: unsorted → asc → desc)
const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { 
      column, 
      title: 'Amount',
      class: 'justify-end' 
    }),
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'));
      return new Intl.NumberFormat('de-DE', {
        style: 'currency',
        currency: 'EUR',
      }).format(amount);
    },
    size: 120,
  },
];
</script>

<template>
  <UiDataTable :data="data" :columns="columns" />
</template>`;

const withPaginationTemplateSource = `<script setup lang="ts">
import { h, ref, computed } from 'vue';
import { UiDataTable, UiDataTableColumnHeader, UiDataTablePagination } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  // ... more data (pagination works best with 10+ items)
];

const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Amount' }),
  },
];

// Access the table instance via ref
const tableRef = ref<InstanceType<typeof UiDataTable>>();
const table = computed(() => tableRef.value?.table);
</script>

<template>
  <div class="gap-y-4">
    <!-- tableMinHeight prevents layout shifts during pagination -->
    <UiDataTable ref="tableRef" :data="data" :columns="columns" table-min-height="500px" />
    <UiDataTablePagination v-if="table" :table="table" />
  </div>
</template>`;

const withToolbarTemplateSource = `<script setup lang="ts">
import { h, ref, computed } from 'vue';
import { UiDataTable, UiDataTableColumnHeader, UiDataTableToolbar, UiInput } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
];

const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Amount' }),
  },
];

const tableRef = ref<InstanceType<typeof UiDataTable>>();
const table = computed(() => tableRef.value?.table);
const emailFilter = computed({
  get: () => (table.value?.getColumn('email')?.getFilterValue() as string) ?? '',
  set: (value) => table.value?.getColumn('email')?.setFilterValue(value),
});
</script>

<template>
  <div class="gap-y-4">
    <UiDataTableToolbar>
      <UiInput
        v-model="emailFilter"
        name="email-filter"
        placeholder="Filter emails..."
        aria-label="Filter emails"
        class="h-8 w-full sm:w-[250px]"
      />
      <template #actions>
        <UiDataTableColumnFilter v-if="table" :table="table" />
      </template>
    </UiDataTableToolbar>
    <UiDataTable ref="tableRef" :data="data" :columns="columns" />
  </div>
</template>`;

const WithColumnsFilterTemplateSource = `<script setup lang="ts">
import { computed, h, ref } from 'vue';
import { UiDataTable, UiDataTableColumnFilter, UiDataTableColumnHeader, UiDataTableToolbar, UiInput } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
];

const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Amount' }),
  },
];

const tableRef = ref<InstanceType<typeof UiDataTable>>();
const table = computed(() => tableRef.value?.table);
const emailFilter = computed({
  get: () => (table.value?.getColumn('email')?.getFilterValue() as string) ?? '',
  set: (value) => table.value?.getColumn('email')?.setFilterValue(value),
});
</script>

<template>
  <div class="space-y-4">
    <UiDataTableToolbar>
      <UiInput
        v-model="emailFilter"
        name="email-filter"
        placeholder="Filter emails..."
        aria-label="Filter emails"
        class="h-8 max-w-sm"
      />
      <UiDataTableColumnFilter v-if="table" :table="table" />
    </UiDataTableToolbar>
    <UiDataTable ref="tableRef" :data="data" :columns="columns" />
  </div>
</template>`;

const fullExampleTemplateSource = `<script setup lang="ts">
import { h, ref, computed } from 'vue';
import { 
  UiDataTable, 
  UiDataTableColumnHeader,
  UiDataTableToolbar, 
  UiDataTablePagination,
  UiInput
} from '@aleph-alpha/ui-library';
import { UiCheckbox } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
  // ... more data
];

// Columns with selection checkbox and sortable headers
const columns: ColumnDef<Payment>[] = [
  {
    id: 'select',
    header: ({ table }) => h(UiCheckbox, {
      modelValue: table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),
      'onUpdate:modelValue': (value: boolean) => table.toggleAllPageRowsSelected(!!value),
      ariaLabel: 'Select all',
      name: 'select-all',
    }),
    cell: ({ row }) => h(UiCheckbox, {
      modelValue: row.getIsSelected(),
      'onUpdate:modelValue': (value: boolean) => row.toggleSelected(!!value),
      ariaLabel: 'Select row',
      name: \`select-\${row.id}\`,
    }),
    enableSorting: false,
    enableHiding: false,
    size: 40,
  },
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Amount' }),
    size: 120,
  },
];

const tableRef = ref<InstanceType<typeof UiDataTable>>();
const table = computed(() => tableRef.value?.table);
const globalSearch = computed({
  get: () => (table.value?.getState().globalFilter as string) ?? '',
  set: (value) => table.value?.setGlobalFilter(value),
});
</script>

<template>
  <div class="gap-y-4">
    <UiDataTableToolbar>
      <UiInput
        v-model="globalSearch"
        name="global-search"
        placeholder="Search..."
        aria-label="Search all columns"
        class="h-8 w-full sm:w-[250px]"
      />
    </UiDataTableToolbar>
    <UiDataTable ref="tableRef" :data="data" :columns="columns" />
    <UiDataTablePagination v-if="table" :table="table" />
  </div>
</template>`;

const withGlobalFilterTemplateSource = `<script setup lang="ts">
import { h, ref, computed } from 'vue';
import { UiDataTable, UiDataTableColumnHeader, UiDataTableToolbar, UiInput } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
];

const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Amount' }),
    size: 120,
  },
];

const tableRef = ref<InstanceType<typeof UiDataTable>>();
const table = computed(() => tableRef.value?.table);
const globalSearch = computed({
  get: () => (table.value?.getState().globalFilter as string) ?? '',
  set: (value) => table.value?.setGlobalFilter(value),
});
</script>

<template>
  <div class="gap-y-4">
    <UiDataTableToolbar>
      <UiInput
        v-model="globalSearch"
        name="global-search"
        placeholder="Search all columns..."
        aria-label="Search all columns"
        class="h-8 w-full sm:w-[250px]"
      />
    </UiDataTableToolbar>
    <UiDataTable ref="tableRef" :data="data" :columns="columns" />
  </div>
</template>`;

const withRowSelectionTemplateSource = `<script setup lang="ts">
import { h, ref, computed } from 'vue';
import { UiDataTable, UiDataTableColumnHeader, UiDataTablePagination } from '@aleph-alpha/ui-library';
import { UiCheckbox } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
];

// Add a selection column using UiCheckbox
const columns: ColumnDef<Payment>[] = [
  {
    id: 'select',
    header: ({ table }) => h(UiCheckbox, {
      modelValue: table.getIsAllPageRowsSelected() || (table.getIsSomePageRowsSelected() && 'indeterminate'),
      'onUpdate:modelValue': (value: boolean) => table.toggleAllPageRowsSelected(!!value),
      ariaLabel: 'Select all',
      name: 'select-all',
    }),
    cell: ({ row }) => h(UiCheckbox, {
      modelValue: row.getIsSelected(),
      'onUpdate:modelValue': (value: boolean) => row.toggleSelected(!!value),
      ariaLabel: 'Select row',
      name: \`select-\${row.id}\`,
    }),
    enableSorting: false,
    enableHiding: false,
    size: 40,
  },
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Amount' }),
    size: 120,
  },
];

const tableRef = ref<InstanceType<typeof UiDataTable>>();
const table = computed(() => tableRef.value?.table);
</script>

<template>
  <div class="gap-y-4">
    <UiDataTable ref="tableRef" :data="data" :columns="columns" />
    <!-- Pagination shows selection count -->
    <UiDataTablePagination v-if="table" :table="table" />
  </div>
</template>`;

const withDraggableColumnsTemplateSource = `<script setup lang="ts">
import { h, ref } from 'vue';
import { UiDataTable, UiDataTableColumnHeader } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
];

const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Amount' }),
    size: 120,
  },
];

const columnOrder = ref<string[]>([]);

function handleColumnOrderChange(nextOrder: string[]) {
  columnOrder.value = nextOrder;
}
</script>

<template>
  <div class="space-y-3">
    <UiDataTable
      :data="data"
      :columns="columns"
      draggable-columns
      :on-column-order-change="handleColumnOrderChange"
    />
    <p class="body-14-regular text-muted-foreground">
      Drag a column header to reorder columns.
      <span v-if="columnOrder.length">
        Current order: {{ columnOrder.join(', ') }}
      </span>
    </p>
  </div>
</template>`;

const expandableColumns: ColumnDef<Payment>[] = [
  ...sortableColumns,
  {
    id: 'expand',
    header: () => h('span', { class: 'sr-only' }, 'Expand row'),
    cell: ({ row }) =>
      h(
        UiButton,
        {
          variant: 'ghost',
          size: 'icon',
          class: 'h-8 w-8',
          'aria-expanded': row.getIsExpanded(),
          'aria-label': row.getIsExpanded() ? 'Collapse row' : 'Expand row',
          onClick: () => row.toggleExpanded(),
        },
        () =>
          h(UiIcon, {
            name: row.getIsExpanded() ? 'chevron-down' : 'chevron-right',
            size: 16,
            'aria-hidden': true,
          }),
      ),
    enableSorting: false,
    enableHiding: false,
    size: 48,
  },
];

const withExpandableRowsTemplateSource = `<script setup lang="ts">
import { h } from 'vue';
import { UiButton, UiDataTable, UiDataTableColumnHeader, UiIcon } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
];

const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Amount' }),
  },
  {
    id: 'expand',
    header: () => h('span', { class: 'sr-only' }, 'Expand row'),
    cell: ({ row }) => h(UiButton, {
      variant: 'ghost',
      size: 'icon',
      class: 'h-8 w-8',
      'aria-expanded': row.getIsExpanded(),
      'aria-label': row.getIsExpanded() ? 'Collapse row' : 'Expand row',
      onClick: () => row.toggleExpanded(),
    }, () => h(UiIcon, {
      name: row.getIsExpanded() ? 'chevron-down' : 'chevron-right',
      size: 16,
      'aria-hidden': true,
    })),
    enableSorting: false,
    enableHiding: false,
    size: 48,
  },
];
</script>

<template>
  <UiDataTable :data="data" :columns="columns" :get-row-can-expand="() => true">
    <template #expanded-row="{ row }">
      <div class="body-14-regular rounded-md bg-background-surface-muted p-4">
        Payment {{ row.original.id }} belongs to {{ row.original.email }}.
      </div>
    </template>
  </UiDataTable>
</template>`;

const customEmptyStateTemplateSource = `<script setup lang="ts">
import { UiDataTable } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = []; // Empty data

const columns: ColumnDef<Payment>[] = [
  { accessorKey: 'status', header: 'Status' },
  { accessorKey: 'email', header: 'Email' },
  { accessorKey: 'amount', header: 'Amount' },
];
</script>

<template>
  <!-- Use empty-text prop to customize the empty state message -->
  <UiDataTable 
    :data="data" 
    :columns="columns" 
    empty-text="No payments found." 
  />
</template>`;

const withPageSizeTemplateSource = `<script setup lang="ts">
import { h, ref, computed } from 'vue';
import { UiDataTable, UiDataTableColumnHeader, UiDataTablePagination } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  // ... more data
];

const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Amount' }),
    size: 120,
  },
];

const tableRef = ref<InstanceType<typeof UiDataTable>>();
const table = computed(() => tableRef.value?.table);
</script>

<template>
  <div class="gap-y-4">
    <UiDataTable ref="tableRef" :data="data" :columns="columns" />
    <!-- Customize page sizes and hide selection count -->
    <UiDataTablePagination 
      v-if="table" 
      :table="table"
      :page-size-options="[5, 10, 20, 50]"
      :show-selection="false"
    />
  </div>
</template>`;

/**
 * Basic table with minimal configuration.
 *
 * The simplest way to use UiDataTable - just pass `data` and `columns`.
 * Column headers are plain text, no sorting or filtering.
 */
export const Basic: Story = {
  args: {
    data: payments,
    columns: basicColumns,
  },
  parameters: {
    docs: {
      source: {
        code: basicTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable },
    setup() {
      return { args };
    },
    template: '<UiDataTable v-bind="args" />',
  }),
};

/**
 * Table with sortable columns using UiDataTableColumnHeader.
 *
 * Use `UiDataTableColumnHeader` in your column definitions to enable:
 * - Click to sort (ascending/descending)
 * - Dropdown menu with sort options and hide column
 *
 * This is the recommended approach for sortable headers.
 */
export const WithSorting: Story = {
  args: {
    data: payments,
    columns: sortableColumns,
  },
  parameters: {
    docs: {
      source: {
        code: withSortingTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable },
    setup() {
      return { args };
    },
    template: '<UiDataTable v-bind="args" />',
  }),
};

/**
 * Table with pagination controls.
 *
 * Use `UiDataTablePagination` when displaying more than 10 rows.
 * Shows navigation buttons (first, prev, next, last), page info, and rows per page selector.
 *
 * The `tableMinHeight` prop prevents layout shifts during pagination by ensuring
 * the table container maintains a minimum height. The last row has a visible
 * bottom border (Material UI-inspired behavior).
 *
 * Access the table instance via ref to pass to pagination component.
 */
export const WithPagination: Story = {
  args: {
    data: payments,
    columns: sortableColumns,
    tableMinHeight: '500px',
  },
  parameters: {
    docs: {
      source: {
        code: withPaginationTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable, UiDataTablePagination },
    setup() {
      const tableRef = ref<InstanceType<typeof UiDataTable>>();
      const table = computed(() => tableRef.value?.table);
      return { args, tableRef, table };
    },
    template: `
      <div class="gap-y-4">
        <UiDataTable ref="tableRef" v-bind="args" />
        <UiDataTablePagination v-if="table" :table="table" />
      </div>
    `,
  }),
};

/**
 * Table with column-specific filtering.
 *
 * Use `UiDataTableToolbar` as a wrapper for table filter controls.
 */
export const WithToolbar: Story = {
  args: {
    data: payments,
    columns: sortableColumns,
  },
  parameters: {
    docs: {
      source: {
        code: withToolbarTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable, UiDataTableToolbar, UiInput },
    setup() {
      const tableRef = ref<InstanceType<typeof UiDataTable>>();
      const table = computed(() => tableRef.value?.table);
      const emailFilter = computed({
        get: () =>
          (table.value?.getColumn('email')?.getFilterValue() as string) ?? '',
        set: (value) => table.value?.getColumn('email')?.setFilterValue(value),
      });
      return { args, emailFilter, tableRef, table };
    },
    template: `
      <div class="gap-y-4">
        <UiDataTableToolbar>
          <UiInput
            v-model="emailFilter"
            name="email-filter"
            placeholder="Filter emails..."
            aria-label="Filter emails"
            class="h-8 w-full sm:w-[250px]"
          />
        </UiDataTableToolbar>
        <UiDataTable ref="tableRef" v-bind="args" />
      </div>
    `,
  }),
};

/**
 * Table header controls with a focused email filter and a column visibility menu.
 *
 * Put `UiDataTableColumnFilter` inside `UiDataTableToolbar` to show/hide
 * hideable columns from a checklist dropdown.
 */
export const WithColumnsFilter: Story = {
  args: {
    data: payments,
    columns: sortableColumns,
  },
  parameters: {
    docs: {
      source: {
        code: WithColumnsFilterTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: {
      UiDataTable,
      UiDataTableColumnFilter,
      UiDataTableToolbar,
      UiInput,
    },
    setup() {
      const tableRef = ref<InstanceType<typeof UiDataTable>>();
      const table = computed(() => tableRef.value?.table);
      const emailFilter = computed({
        get: () =>
          (table.value?.getColumn('email')?.getFilterValue() as string) ?? '',
        set: (value) => table.value?.getColumn('email')?.setFilterValue(value),
      });

      return { args, emailFilter, table, tableRef };
    },
    template: `
      <div class="space-y-4">
        <UiDataTableToolbar>
          <UiInput
            v-model="emailFilter"
            name="email-filter"
            placeholder="Filter emails..."
            aria-label="Filter emails"
            class="h-8 max-w-sm"
          />
          <UiDataTableColumnFilter v-if="table" :table="table" />
        </UiDataTableToolbar>
        <UiDataTable ref="tableRef" v-bind="args" />
      </div>
    `,
  }),
};

/**
 * Table with global search across all columns.
 *
 * Use a table-bound `UiInput` inside `UiDataTableToolbar` to search across all columns.
 * Matches any value in status, email, amount, or ID.
 *
 * Try typing "success", "gmail", or "316" to see it match different columns.
 */
export const WithGlobalFilter: Story = {
  args: {
    data: payments,
    columns: sortableColumns,
  },
  parameters: {
    docs: {
      source: {
        code: withGlobalFilterTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable, UiDataTableToolbar, UiInput },
    setup() {
      const tableRef = ref<InstanceType<typeof UiDataTable>>();
      const table = computed(() => tableRef.value?.table);
      const globalSearch = computed({
        get: () => (table.value?.getState().globalFilter as string) ?? '',
        set: (value) => table.value?.setGlobalFilter(value),
      });
      return { args, globalSearch, tableRef, table };
    },
    template: `
      <div class="gap-y-4">
        <UiDataTableToolbar>
          <UiInput
            v-model="globalSearch"
            name="global-search"
            placeholder="Search all columns..."
            aria-label="Search all columns"
            class="h-8 w-full sm:w-[250px]"
          />
        </UiDataTableToolbar>
        <UiDataTable ref="tableRef" v-bind="args" />
      </div>
    `,
  }),
};

/**
 * Table with row selection checkboxes.
 *
 * Add a selection column using `UiCheckbox` to enable row selection.
 * Use `table.getIsAllPageRowsSelected()` for the header checkbox and
 * `row.getIsSelected()` for row checkboxes.
 *
 * The pagination component shows the selection count automatically.
 */
export const WithRowSelection: Story = {
  args: {
    data: payments,
    columns: selectableColumns,
  },
  parameters: {
    docs: {
      source: {
        code: withRowSelectionTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable, UiDataTablePagination },
    setup() {
      const tableRef = ref<InstanceType<typeof UiDataTable>>();
      const table = computed(() => tableRef.value?.table);
      return { args, tableRef, table };
    },
    template: `
      <div class="gap-y-4">
        <UiDataTable ref="tableRef" v-bind="args" />
        <UiDataTablePagination v-if="table" :table="table" />
      </div>
    `,
  }),
};

/**
 * Table with draggable columns.
 *
 * Enable `draggable-columns` to let users reorder columns by dragging header cells.
 * The drag-and-drop helpers are exported from the UiDataTable module for reuse in
 * custom table interactions.
 */
export const WithDraggableColumns: Story = {
  args: {
    data: payments,
    columns: sortableColumns,
    draggableColumns: true,
  },
  parameters: {
    docs: {
      source: {
        code: withDraggableColumnsTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable },
    setup() {
      const columnOrder = ref<string[]>([]);
      return {
        args,
        columnOrder,
        handleColumnOrderChange: (nextOrder: string[]) => {
          columnOrder.value = nextOrder;
        },
      };
    },
    template: `
      <div class="space-y-3">
        <UiDataTable
          v-bind="args"
          :on-column-order-change="handleColumnOrderChange"
        />
        <p class="body-14-regular text-muted-foreground">
          Drag a column header to reorder columns.
          <span v-if="columnOrder.length">
            Current order: {{ columnOrder.join(', ') }}
          </span>
        </p>
      </div>
    `,
  }),
};

/**
 * Table with expandable rows.
 *
 * The expanded content is rendered in its own table row via the `expanded-row`
 * slot, keeping the table structure valid for screen readers and browsers.
 */
export const WithExpandableRows: Story = {
  args: {
    data: payments,
    columns: expandableColumns,
    getRowCanExpand: () => true,
  },
  parameters: {
    docs: {
      source: {
        code: withExpandableRowsTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable },
    setup() {
      return { args };
    },
    template: `
      <UiDataTable v-bind="args">
        <template #expanded-row="{ row }">
          <div class="body-14-regular rounded-md bg-background-surface-muted p-4">
            <p class="font-medium">Payment {{ row.original.id }}</p>
            <p class="text-muted-foreground">
              Customer: {{ row.original.email }} - Status: {{ row.original.status }}
            </p>
          </div>
        </template>
      </UiDataTable>
    `,
  }),
};

/**
 * Complete example combining all DataTable features.
 *
 * This example demonstrates the full power of UiDataTable with:
 * - **Sortable columns** using `UiDataTableColumnHeader`
 * - **Row selection** with checkboxes (header + row)
 * - **Global search** across all columns
 * - **Pagination** with page size selector
 *
 * Use this as a reference for building feature-rich data tables.
 */
export const FullExample: Story = {
  args: {
    data: payments,
    columns: selectableColumns,
  },
  parameters: {
    docs: {
      source: {
        code: fullExampleTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: {
      UiDataTable,
      UiDataTableToolbar,
      UiDataTablePagination,
      UiInput,
    },
    setup() {
      const tableRef = ref<InstanceType<typeof UiDataTable>>();
      const table = computed(() => tableRef.value?.table);
      const globalSearch = computed({
        get: () => (table.value?.getState().globalFilter as string) ?? '',
        set: (value) => table.value?.setGlobalFilter(value),
      });
      return { args, globalSearch, tableRef, table };
    },
    template: `
      <div class="gap-y-4">
        <UiDataTableToolbar>
          <UiInput
            v-model="globalSearch"
            name="global-search"
            placeholder="Search..."
            aria-label="Search all columns"
            class="h-8 w-full sm:w-[250px]"
          />
        </UiDataTableToolbar>
        <UiDataTable ref="tableRef" v-bind="args" />
        <UiDataTablePagination v-if="table" :table="table" />
      </div>
    `,
  }),
};

/**
 * Table with custom empty state message using the `empty-text` prop.
 *
 * Use the `empty-text` prop to customize the message shown when there's no data.
 * Defaults to "No results." if not specified.
 */
export const WithCustomEmptyText: Story = {
  args: {
    data: [],
    columns: basicColumns,
    emptyText: 'No payments found.',
  },
  parameters: {
    docs: {
      source: {
        code: customEmptyStateTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable },
    setup() {
      return { args };
    },
    template: '<UiDataTable v-bind="args" />',
  }),
};

const withCustomEmptySlotTemplateSource = `<script setup lang="ts">
import { UiDataTable, UiIcon } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = []; // Empty data

const columns: ColumnDef<Payment>[] = [
  { accessorKey: 'status', header: 'Status' },
  { accessorKey: 'email', header: 'Email' },
  { accessorKey: 'amount', header: 'Amount' },
];
</script>

<template>
  <UiDataTable :data="data" :columns="columns">
    <template #empty>
      <div class="flex flex-col items-center gap-2 text-muted-foreground">
        <UiIcon name="ban" :size="32" />
        <p>No data available for this view.</p>
      </div>
    </template>
  </UiDataTable>
</template>`;

/**
 * Data table with a custom empty state using the `#empty` slot.
 */
export const WithCustomEmptySlot: Story = {
  args: {
    data: [],
    columns: basicColumns,
  },
  parameters: {
    docs: {
      description: {
        story:
          'Use the `#empty` slot to provide a fully custom empty state, such as an icon or formatted text.',
      },
      source: {
        code: withCustomEmptySlotTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable, UiIcon },
    setup() {
      return { args };
    },
    template: `
      <UiDataTable v-bind="args">
        <template #empty>
          <div class="flex flex-col items-center gap-2 text-muted-foreground">
            <UiIcon name="ban" :size="32" />
            <p>No data available for this view.</p>
          </div>
        </template>
      </UiDataTable>
    `,
  }),
};

// Columns using UiDataTableColumnHeader component
const columnHeaderColumns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, { column, title: 'Status' }),
    cell: ({ row }) =>
      h('div', { class: 'capitalize' }, row.getValue('status')),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, { column, title: 'Email' }),
    cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, {
        column,
        title: 'Amount',
        class: 'justify-end',
      }),
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'));
      const formatted = new Intl.NumberFormat('de-DE', {
        style: 'currency',
        currency: 'EUR',
      }).format(amount);
      return h('div', { class: 'text-right font-medium' }, formatted);
    },
    size: 120,
  },
];

const withColumnHeaderTemplateSource = `<script setup lang="ts">
import { h } from 'vue';
import { UiDataTable, UiDataTableColumnHeader } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  // ... more data
];

// Using UiDataTableColumnHeader for sortable headers with hide option
const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
    cell: ({ row }) => h('div', { class: 'capitalize' }, row.getValue('status')),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
    cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { 
      column, 
      title: 'Amount',
      class: 'justify-end' 
    }),
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'));
      const formatted = new Intl.NumberFormat('de-DE', {
        style: 'currency',
        currency: 'EUR',
      }).format(amount);
      return h('div', { class: 'text-right font-medium' }, formatted);
    },
    size: 120,
  },
];
</script>

<template>
  <UiDataTable :data="data" :columns="columns" />
</template>`;

/**
 * Table demonstrating sortable columns with UiDataTableColumnHeader.
 *
 * The `UiDataTableColumnHeader` provides a dropdown with sort options.
 *
 * For right-aligned headers (like amounts), pass `class="justify-end"`.
 */
export const WithColumnHeader: Story = {
  args: {
    data: payments,
    columns: columnHeaderColumns,
  },
  parameters: {
    docs: {
      source: {
        code: withColumnHeaderTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable, UiDataTableToolbar, UiInput },
    setup() {
      const tableRef = ref<InstanceType<typeof UiDataTable>>();
      const table = computed(() => tableRef.value?.table);
      const globalSearch = computed({
        get: () => (table.value?.getState().globalFilter as string) ?? '',
        set: (value) => table.value?.setGlobalFilter(value),
      });
      return { args, globalSearch, tableRef, table };
    },
    template: `
      <div class="gap-y-4">
        <UiDataTableToolbar>
          <UiInput
            v-model="globalSearch"
            name="global-search"
            placeholder="Search..."
            aria-label="Search all columns"
            class="h-8 w-full sm:w-[250px]"
          />
        </UiDataTableToolbar>
        <UiDataTable ref="tableRef" v-bind="args" />
      </div>
    `,
  }),
};

/**
 * Table with customized pagination options.
 *
 * Customize `UiDataTablePagination` with:
 * - `page-size-options`: Array of page size options (default: [10, 20, 30, 50])
 * - `show-page-size`: Show/hide the rows per page selector (default: true)
 * - `show-selection`: Show/hide the selection count (default: true)
 */
export const WithPageSizeSelector: Story = {
  args: {
    data: payments,
    columns: sortableColumns,
  },
  parameters: {
    docs: {
      source: {
        code: withPageSizeTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable, UiDataTablePagination },
    setup() {
      const tableRef = ref<InstanceType<typeof UiDataTable>>();
      const table = computed(() => tableRef.value?.table);
      return { args, tableRef, table };
    },
    template: `
      <div class="gap-y-4">
        <UiDataTable ref="tableRef" v-bind="args" />
        <UiDataTablePagination 
          v-if="table" 
          :table="table"
          :page-size-options="[5, 10, 20, 50]"
          :show-selection="false"
        />
      </div>
    `,
  }),
};

/**
 * Table with 14 items, minimum height, and pagination.
 *
 * Demonstrates how `tableMinHeight` keeps stable layout when there's content
 * below the table (pagination). Page 1 shows 10 rows, page 2 shows 4 rows -
 * the table maintains consistent height regardless of how many rows are visible.
 */
export const WithMinHeightSmallDataset: Story = {
  args: {
    // Use 14 items: page 1 = 10 rows, page 2 = 4 rows
    data: paymentsMedium.slice(0, 14),
    columns: sortableColumns,
    tableMinHeight: '500px',
  },
  parameters: {
    docs: {
      description: {
        story:
          'Demonstrates `tableMinHeight` with 14 items and pagination. Page 1 shows 10 rows, page 2 shows only 4 rows. The table keeps a consistent height, preventing layout shifts when navigating between pages.',
      },
      source: {
        code: `<script setup lang="ts">
import { h, ref, computed } from 'vue';
import { UiDataTable, UiDataTableColumnHeader, UiDataTablePagination } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment { id: string; amount: number; status: string; email: string; }

// 14 items: page 1 = 10 rows, page 2 = 4 rows
const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'user1@example.com' },
  { id: '2', amount: 242, status: 'pending', email: 'user2@example.com' },
  { id: '3', amount: 837, status: 'processing', email: 'user3@example.com' },
  { id: '4', amount: 154, status: 'failed', email: 'user4@example.com' },
  { id: '5', amount: 429, status: 'success', email: 'user5@example.com' },
  { id: '6', amount: 512, status: 'pending', email: 'user6@example.com' },
  { id: '7', amount: 623, status: 'processing', email: 'user7@example.com' },
  { id: '8', amount: 734, status: 'failed', email: 'user8@example.com' },
  { id: '9', amount: 845, status: 'success', email: 'user9@example.com' },
  { id: '10', amount: 956, status: 'pending', email: 'user10@example.com' },
  { id: '11', amount: 167, status: 'processing', email: 'user11@example.com' },
  { id: '12', amount: 278, status: 'failed', email: 'user12@example.com' },
  { id: '13', amount: 389, status: 'success', email: 'user13@example.com' },
  { id: '14', amount: 490, status: 'pending', email: 'user14@example.com' },
];

const columns: ColumnDef<Payment>[] = [
  { accessorKey: 'status', header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }) },
  { accessorKey: 'email', header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }) },
  { accessorKey: 'amount', header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Amount', class: 'justify-end' }) },
];

const tableRef = ref<InstanceType<typeof UiDataTable>>();
const table = computed(() => tableRef.value?.table);
</script>

<template>
  <div class="gap-y-4">
    <UiDataTable ref="tableRef" :data="data" :columns="columns" table-min-height="500px" />
    <UiDataTablePagination v-if="table" :table="table" :show-selection="false" />
  </div>
</template>`,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable, UiDataTablePagination },
    setup() {
      const tableRef = ref<InstanceType<typeof UiDataTable>>();
      const table = computed(() => tableRef.value?.table);
      return { args, tableRef, table };
    },
    template: `
      <div class="gap-y-4">
        <UiDataTable ref="tableRef" v-bind="args" />
        <UiDataTablePagination v-if="table" :table="table" :show-selection="false" />
      </div>
    `,
  }),
};

// Row Actions columns with dropdown menu
const rowActionsColumns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, { column, title: 'Status' }),
    cell: ({ row }) =>
      h('div', { class: 'capitalize' }, row.getValue('status')),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, { column, title: 'Email' }),
    cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) =>
      h(UiDataTableColumnHeader, {
        column,
        title: 'Amount',
        class: 'justify-end',
      }),
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'));
      const formatted = new Intl.NumberFormat('de-DE', {
        style: 'currency',
        currency: 'EUR',
      }).format(amount);
      return h('div', { class: 'text-right font-medium' }, formatted);
    },
    size: 120,
  },
  {
    id: 'actions',
    enableHiding: false,
    enableSorting: false,
    header: () => h('span', { class: 'sr-only' }, 'Actions'),
    cell: ({ row }) => {
      const payment = row.original;
      return h(
        UiDropdownMenu,
        {},
        {
          default: () => [
            h(UiDropdownMenuTrigger, { asChild: true }, () =>
              h(
                UiButton,
                { variant: 'ghost', size: 'icon', class: 'h-8 w-8' },
                () => [
                  h('span', { class: 'sr-only' }, 'Open menu'),
                  h(UiIcon, { name: 'more-horizontal', size: 16 }),
                ],
              ),
            ),
            h(UiDropdownMenuContent, { align: 'end' }, () => [
              h(UiDropdownMenuLabel, {}, () => 'Actions'),
              h(
                UiDropdownMenuItem,
                { onClick: () => navigator.clipboard.writeText(payment.id) },
                () => 'Copy payment ID',
              ),
              h(UiDropdownMenuSeparator),
              h(UiDropdownMenuItem, {}, () => 'View details'),
              h(UiDropdownMenuItem, {}, () => 'View customer'),
            ]),
          ],
        },
      );
    },
    size: 50,
  },
];

const withRowActionsTemplateSource = `<script setup lang="ts">
import { h } from 'vue';
import { UiDataTable, UiDataTableColumnHeader } from '@aleph-alpha/ui-library';
import {
  UiDropdownMenu,
  UiDropdownMenuContent,
  UiDropdownMenuItem,
  UiDropdownMenuLabel,
  UiDropdownMenuSeparator,
  UiDropdownMenuTrigger,
} from '@aleph-alpha/ui-library';
import { UiButton } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
];

// Define a component for row actions (or use inline h() calls)
const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
    cell: ({ row }) => h('div', { class: 'capitalize' }, row.getValue('status')),
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
    cell: ({ row }) => h('div', { class: 'lowercase' }, row.getValue('email')),
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, { 
      column, 
      title: 'Amount',
      class: 'justify-end' 
    }),
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'));
      const formatted = new Intl.NumberFormat('de-DE', {
        style: 'currency',
        currency: 'EUR',
      }).format(amount);
      return h('div', { class: 'text-right font-medium' }, formatted);
    },
  },
  {
    id: 'actions',
    enableHiding: false,
    cell: ({ row }) => {
      const payment = row.original;

      // You can return a Vue component or use h() to render dropdown
      // For complex actions, create a separate component like DataTableRowActions.vue
      return h(UiDropdownMenu, {}, {
        default: () => [
          h(UiDropdownMenuTrigger, { asChild: true }, () =>
            h(UiButton, { variant: 'ghost', size: 'sm' }, () => '⋮')
          ),
          h(UiDropdownMenuContent, { align: 'end' }, () => [
            h(UiDropdownMenuLabel, {}, () => 'Actions'),
            h(UiDropdownMenuItem, { 
              onClick: () => navigator.clipboard.writeText(payment.id) 
            }, () => 'Copy payment ID'),
            h(UiDropdownMenuSeparator),
            h(UiDropdownMenuItem, {}, () => 'View details'),
            h(UiDropdownMenuItem, {}, () => 'View customer'),
          ]),
        ],
      });
    },
  },
];
</script>

<template>
  <UiDataTable :data="data" :columns="columns" />
</template>`;

/**
 * Table with row actions dropdown menu.
 *
 * Add an actions column with a dropdown menu for each row.
 * Use `row.original` to access the full row data for actions.
 *
 * For complex actions, create a separate component (e.g., `DataTableRowActions.vue`)
 * and import it in your column definition.
 */
export const WithRowActions: Story = {
  args: {
    data: payments,
    columns: rowActionsColumns,
  },
  parameters: {
    docs: {
      source: {
        code: withRowActionsTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable },
    setup() {
      return { args };
    },
    template: '<UiDataTable v-bind="args" />',
  }),
};

// Cell formatting columns
const cellFormattingColumns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: 'Status',
    cell: ({ row }) => {
      const status = row.getValue('status') as Payment['status'];
      const statusVariants = {
        success: 'success',
        processing: 'secondary',
        pending: 'warning',
        failed: 'destructive',
      } as const;
      return h(
        UiBadge,
        {
          variant: statusVariants[status],
          size: 'small',
          class: 'capitalize',
        },
        () => status,
      );
    },
    size: 120,
  },
  {
    accessorKey: 'email',
    header: 'Email',
    cell: ({ row }) =>
      h(
        'div',
        { class: 'body-14-regular font-mono lowercase' },
        row.getValue('email'),
      ),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: () => h('div', { class: 'text-right' }, 'Amount'),
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'));
      const formatted = new Intl.NumberFormat('de-DE', {
        style: 'currency',
        currency: 'EUR',
      }).format(amount);
      return h(
        'div',
        {
          class: `text-right font-medium ${amount > 500 ? 'text-green-800' : 'text-muted-foreground'}`,
        },
        formatted,
      );
    },
    size: 120,
  },
];

const withCellFormattingTemplateSource = `<script setup lang="ts">
import { h } from 'vue';
import { UiBadge, UiDataTable } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: 'pending' | 'processing' | 'success' | 'failed';
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'pending', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
  { id: '4', amount: 721, status: 'failed', email: 'carmella@hotmail.com' },
];

const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: 'Status',
    // Status badge with built-in UiBadge variants
    cell: ({ row }) => {
      const status = row.getValue('status') as Payment['status'];
      const statusVariants = {
        success: 'success',
        processing: 'secondary',
        pending: 'warning',
        failed: 'destructive',
      } as const;
      return h(UiBadge, {
        variant: statusVariants[status],
        size: 'small',
        class: 'capitalize',
      }, () => status);
    },
  },
  {
    accessorKey: 'email',
    header: 'Email',
    // Monospace font for emails
    cell: ({ row }) => h('div', { 
      class: 'body-14-regular font-mono lowercase'
    }, row.getValue('email')),
  },
  {
    accessorKey: 'amount',
    // Right-aligned header
    header: () => h('div', { class: 'text-right' }, 'Amount'),
    // Conditional formatting: green for high amounts
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'));
      const formatted = new Intl.NumberFormat('de-DE', {
        style: 'currency',
        currency: 'EUR',
      }).format(amount);
      return h('div', {
        class: \`text-right font-medium \${amount > 500 ? 'text-green-800' : 'text-muted-foreground'}\`,
      }, formatted);
    },
  },
];
</script>

<template>
  <UiDataTable :data="data" :columns="columns" />
</template>`;

/**
 * Table with custom cell formatting.
 *
 * Use the `cell` property in column definitions to customize how data is displayed:
 * - **Status badges** with semantic colors (green=success, yellow=processing, etc.)
 * - **Monospace font** for emails
 * - **Currency formatting** with conditional colors based on value
 *
 * Access cell value with `row.getValue('columnKey')` and return a VNode using `h()`.
 */
export const WithCellFormatting: Story = {
  args: {
    data: payments,
    columns: cellFormattingColumns,
  },
  parameters: {
    docs: {
      source: {
        code: withCellFormattingTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable },
    setup() {
      return { args };
    },
    template: '<UiDataTable v-bind="args" />',
  }),
};

const withRowClickTemplateSource = `<script setup lang="ts">
import { ref, h } from 'vue';
import { UiDataTable, UiDataTableColumnHeader } from '@aleph-alpha/ui-library';
import type { ColumnDef } from '@aleph-alpha/ui-library';

interface Payment {
  id: string;
  amount: number;
  status: string;
  email: string;
}

const data: Payment[] = [
  { id: '1', amount: 316, status: 'success', email: 'ken99@yahoo.com' },
  { id: '2', amount: 242, status: 'success', email: 'abe45@gmail.com' },
  { id: '3', amount: 837, status: 'processing', email: 'monserrat44@gmail.com' },
];

const columns: ColumnDef<Payment>[] = [
  {
    accessorKey: 'status',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Status' }),
    size: 120,
  },
  {
    accessorKey: 'email',
    header: ({ column }) => h(UiDataTableColumnHeader, { column, title: 'Email' }),
    size: 250,
  },
  {
    accessorKey: 'amount',
    header: ({ column }) => h(UiDataTableColumnHeader, {
      column,
      title: 'Amount',
      class: 'justify-end'
    }),
    cell: ({ row }) => {
      const amount = Number.parseFloat(row.getValue('amount'));
      return new Intl.NumberFormat('de-DE', {
        style: 'currency',
        currency: 'EUR',
      }).format(amount);
    },
    size: 120,
  },
];

const clickedRow = ref<Payment | null>(null);
</script>

<template>
  <UiDataTable
    :data="data"
    :columns="columns"
    :on-row-click="(row) => (clickedRow = row)"
  />
  <div v-if="clickedRow" class="body-14-regular mt-4 rounded border p-3">
    Clicked: {{ clickedRow.email }} - {{ clickedRow.status }}
  </div>
</template>`;

export const WithRowClick: Story = {
  args: {
    data: payments,
    columns: sortableColumns,
  },
  parameters: {
    docs: {
      source: {
        code: withRowClickTemplateSource,
      },
    },
  },
  render: (args) => ({
    components: { UiDataTable },
    setup() {
      const clickedRow = ref<Payment | null>(null);
      return {
        args,
        clickedRow,
        handleRowClick: (row: Payment) => {
          clickedRow.value = row;
        },
      };
    },
    template: `
      <div>
        <UiDataTable v-bind="args" :on-row-click="handleRowClick" />
        <div v-if="clickedRow" class="body-14-regular mt-4 rounded border p-3">
          Clicked: <strong>{{ clickedRow.email }}</strong> - {{ clickedRow.status }} - {{ new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(clickedRow.amount) }}
        </div>
        <div v-else class="body-14-regular text-muted-foreground mt-4">Click a row to see its data</div>
      </div>
    `,
  }),
};
