import React, { useState, useMemo, useRef, useCallback } from 'react';
import {
  useReactTable,
  getCoreRowModel,
  getSortedRowModel,
  getFilteredRowModel,
  flexRender,
  ColumnDef,
  SortingState,
  ColumnFiltersState,
} from '@tanstack/react-table';
import { useVirtualizer } from '@tanstack/react-virtual';
import clsx from 'clsx';
import { Pagination } from '@/components/ui/Pagination';
import { useTranslation } from 'react-i18next';

import { Loader2 } from 'lucide-react';

export interface DataGridProps<T> {
  columns: ColumnDef<T, any>[];
  data: T[];
  total: number;
  page: number;
  pageSize: number;
  onPageChange: (page: number) => void;
  onRowClick?: (row: T) => void;
  emptyMessage?: string;
  loading?: boolean;
  enableSorting?: boolean;
  enableGlobalFilter?: boolean;
  globalFilter?: string;
  onGlobalFilterChange?: (value: string) => void;
  testId?: string;
  virtualized?: boolean;
}

export function DataGrid<T extends Record<string, any>>({
  columns,
  data,
  total,
  page,
  pageSize,
  onPageChange,
  onRowClick,
  emptyMessage,
  loading = false,
  enableSorting = true,
  testId,
  virtualized = true,
}: DataGridProps<T>) {
  const { t } = useTranslation();
  const [sorting, setSorting] = useState<SortingState>([]);
  const scrollRef = useRef<HTMLDivElement>(null);

  const table = useReactTable({
    data,
    columns,
    state: { sorting },
    onSortingChange: setSorting,
    getCoreRowModel: getCoreRowModel(),
    getSortedRowModel: enableSorting ? getSortedRowModel() : undefined,
    getFilteredRowModel: getFilteredRowModel(),
  });

  const totalPages = Math.ceil(total / pageSize);

  // Auto-skip virtualization for small datasets
  const shouldVirtualize = virtualized && data.length >= 50;

  const rows = table.getRowModel().rows;

  const rowVirtualizer = useVirtualizer({
    count: shouldVirtualize ? rows.length : 0,
    getScrollElement: () => scrollRef.current,
    estimateSize: () => 53, // approx row height
    overscan: 10,
    enabled: shouldVirtualize,
  });

  const virtualRows = shouldVirtualize ? rowVirtualizer.getVirtualItems() : [];
  const totalHeight = shouldVirtualize ? rowVirtualizer.getTotalSize() : 0;
  const paddingTop = virtualRows.length > 0 ? virtualRows[0].start : 0;
  const paddingBottom = virtualRows.length > 0 ? totalHeight - virtualRows[virtualRows.length - 1].end : 0;

  const renderRow = useCallback(
    (row: typeof rows[number]) => (
      <tr
        key={row.id}
        className={clsx(
          'hover:bg-secondary-50 motion-safe:transition-colors',
          onRowClick && 'cursor-pointer'
        )}
        onClick={onRowClick ? () => onRowClick(row.original) : undefined}
        tabIndex={onRowClick ? 0 : undefined}
        onKeyDown={onRowClick ? (e) => {
          if (e.key === 'Enter') onRowClick(row.original);
        } : undefined}
      >
        {row.getVisibleCells().map((cell) => (
          <td key={cell.id} className="px-6 py-4 text-sm text-secondary-900">
            {flexRender(cell.column.columnDef.cell, cell.getContext())}
          </td>
        ))}
      </tr>
    ),
    [onRowClick]
  );

  return (
    <div className="bg-white rounded-lg shadow-sm border border-secondary-200 overflow-hidden" data-testid={testId}>
      <div
        ref={scrollRef}
        className="overflow-x-auto"
        role="region"
        aria-label="Data grid"
        style={shouldVirtualize ? { maxHeight: '70vh', overflowY: 'auto' } : undefined}
      >
        <table className="min-w-full divide-y divide-secondary-200">
          <thead className="bg-secondary-50 sticky top-0 z-10">
            {table.getHeaderGroups().map((headerGroup) => (
              <tr key={headerGroup.id}>
                {headerGroup.headers.map((header) => {
                  const canSort = header.column.getCanSort();
                  const sortDir = header.column.getIsSorted();
                  return (
                    <th
                      key={header.id}
                      scope="col"
                      className={clsx(
                        'px-6 py-3 text-left text-xs font-semibold text-secondary-600 uppercase tracking-wider',
                        canSort && 'cursor-pointer select-none hover:bg-secondary-100 min-h-touch'
                      )}
                      aria-sort={sortDir === 'asc' ? 'ascending' : sortDir === 'desc' ? 'descending' : 'none'}
                      onClick={canSort ? header.column.getToggleSortingHandler() : undefined}
                      onKeyDown={(e) => {
                        if (canSort && (e.key === 'Enter' || e.key === ' ')) {
                          e.preventDefault();
                          header.column.toggleSorting();
                        }
                      }}
                      tabIndex={canSort ? 0 : undefined}
                      role={canSort ? 'button' : undefined}
                      aria-label={canSort ? `${flexRender(header.column.columnDef.header, header.getContext())}, sortierbar` : undefined}
                    >
                      <div className="flex items-center gap-1">
                        {flexRender(header.column.columnDef.header, header.getContext())}
                        {canSort && (
                          <span aria-hidden="true">
                            {sortDir === 'asc' ? '▲' : sortDir === 'desc' ? '▼' : '↕'}
                          </span>
                        )}
                      </div>
                    </th>
                  );
                })}
              </tr>
            ))}
          </thead>
          <tbody className="divide-y divide-secondary-100 bg-white">
            {loading ? (
              <tr>
                <td colSpan={columns.length} className="px-6 py-8 text-center text-secondary-500">
                  <span className="inline-flex items-center gap-2">
                    <Loader2 className="animate-spin motion-reduce:animate-none h-5 w-5" aria-hidden="true" />
                    {t('common.loading')}
                  </span>
                </td>
              </tr>
            ) : rows.length === 0 ? (
              <tr>
                <td colSpan={columns.length} className="px-6 py-8 text-center text-secondary-500">
                  {emptyMessage || t('table.empty')}
                </td>
              </tr>
            ) : shouldVirtualize ? (
              <>
                {paddingTop > 0 && (
                  <tr key="__padding-top" style={{ height: paddingTop }}>
                    <td colSpan={columns.length} style={{ padding: 0, border: 'none' }} />
                  </tr>
                )}
                {virtualRows.map((virtualRow) => {
                  const row = rows[virtualRow.index];
                  return renderRow(row);
                })}
                {paddingBottom > 0 && (
                  <tr key="__padding-bottom" style={{ height: paddingBottom }}>
                    <td colSpan={columns.length} style={{ padding: 0, border: 'none' }} />
                  </tr>
                )}
              </>
            ) : (
              rows.map((row) => renderRow(row))
            )}
          </tbody>
        </table>
      </div>
      {totalPages > 1 && (
        <Pagination
          currentPage={page}
          totalPages={totalPages}
          total={total}
          pageSize={pageSize}
          onPageChange={onPageChange}
        />
      )}
    </div>
  );
}
