import React, { useMemo, useCallback } from 'react';
import { clsx } from 'clsx';
import { ResponsiveTable, Pagination, SearchBar, Checkbox, Button } from '@/components/ui';
import { MoreVertical } from 'lucide-react';
import { DropdownMenu } from '@/components/ui';
import { useTranslation } from '@/hooks/useI18n.tsx';

export interface DataTableColumn<T> {
  key: string;
  header: string;
  render: (item: T, index: number) => React.ReactNode;
  width?: string | number;
  minWidth?: string | number;
  sortable?: boolean;
  align?: 'left' | 'center' | 'right';
}

export interface DataTableAction<T> {
  label: string;
  icon?: React.ReactNode;
  onClick: (item: T) => void;
  variant?: 'default' | 'destructive';
  disabled?: (item: T) => boolean;
}

export interface DataTableProps<T> {
  data: T[];
  columns: DataTableColumn<T>[];
  getRowId: (item: T) => string;
  isLoading?: boolean;
  // Pagination
  pagination?: {
    currentPage: number;
    totalPages: number;
    pageSize: number;
    totalItems: number;
    onPageChange: (page: number) => void;
    onPageSizeChange?: (size: number) => void;
  };
  // Sorting
  sorting?: {
    column: string | null;
    direction: 'asc' | 'desc' | null;
    onSort: (column: string, direction: 'asc' | 'desc') => void;
  };
  // Search
  search?: {
    value: string;
    onChange: (value: string) => void;
    placeholder?: string;
  };
  // Selection
  selection?: {
    selectedRows: Set<string>;
    onSelectionChange: (selected: Set<string>) => void;
  };
  // Actions
  actions?: DataTableAction<T>[];
  bulkActions?: Array<{
    label: string;
    icon?: React.ReactNode;
    onClick: (selectedIds: string[]) => void;
    variant?: 'default' | 'destructive';
  }>;
  // Empty state
  emptyMessage?: string;
  emptyDescription?: string;
  emptyAction?: React.ReactNode;
  // Mobile card renderer
  renderMobileCard?: (item: T, index: number) => React.ReactNode;
  className?: string;
}

/**
 * Enhanced DataTable component with built-in pagination, sorting, filtering, and bulk actions
 */
export function DataTable<T>({
  data,
  columns,
  getRowId,
  isLoading = false,
  pagination,
  sorting,
  search,
  selection,
  actions,
  bulkActions,
  emptyMessage = 'No data available',
  emptyDescription,
  emptyAction,
  renderMobileCard,
  className,
}: DataTableProps<T>) {
  const { t } = useTranslation();
  const selectedCount = selection?.selectedRows.size || 0;
  const hasSelection = selectedCount > 0;

  const handleSelectAll = (checked: boolean) => {
    if (!selection) return;
    if (checked) {
      const allIds = new Set(data.map(getRowId));
      selection.onSelectionChange(allIds);
    } else {
      selection.onSelectionChange(new Set());
    }
  };

  const handleSelectRow = useCallback(
    (id: string, checked: boolean) => {
      if (!selection) return;
      const newSelection = new Set(selection.selectedRows);
      if (checked) {
        newSelection.add(id);
      } else {
        newSelection.delete(id);
      }
      selection.onSelectionChange(newSelection);
    },
    [selection]
  );

  const allSelected =
    data.length > 0 && data.every((item) => selection?.selectedRows.has(getRowId(item)));
  const someSelected = data.some((item) => selection?.selectedRows.has(getRowId(item)));

  // Add selection column if selection is enabled
  const tableColumns = useMemo(() => {
    if (!selection) return columns;

    return [
      {
        key: '__select__',
        header: '',
        render: (_: T, index: number) => {
          const id = getRowId(data[index]);
          const isSelected = selection.selectedRows.has(id);
          return (
            <Checkbox
              checked={isSelected}
              onChange={(e) => handleSelectRow(id, e.target.checked)}
              onClick={(e) => e.stopPropagation()}
            />
          );
        },
        width: 40,
        sortable: false,
        align: 'center' as const,
      },
      ...columns,
    ];
  }, [columns, selection, data, getRowId, handleSelectRow]);

  // Add actions column if actions are provided
  const finalColumns = useMemo(() => {
    if (!actions || actions.length === 0) return tableColumns;

    return [
      ...tableColumns,
      {
        key: '__actions__',
        header: 'Actions',
        render: (item: T) => {
          const enabledActions = actions.filter(
            (action) => !action.disabled || !action.disabled(item)
          );

          if (enabledActions.length === 0) return null;

          return (
            <DropdownMenu
              trigger={
                <Button variant="ghost" size="sm" className="h-8 w-8 p-0">
                  <MoreVertical className="h-4 w-4" />
                </Button>
              }
              items={enabledActions.map((action) => ({
                label: action.label,
                value: action.label,
                icon: action.icon,
                onClick: () => action.onClick(item),
                disabled: action.disabled?.(item),
              }))}
              align="right"
            />
          );
        },
        width: 80,
        sortable: false,
        align: 'right' as const,
      },
    ];
  }, [tableColumns, actions]);

  const handleSort = (key: string) => {
    if (!sorting) return;
    const newDirection = sorting.column === key && sorting.direction === 'asc' ? 'desc' : 'asc';
    sorting.onSort(key, newDirection);
  };

  return (
    <div className={clsx('space-y-4', className)}>
      {/* Toolbar */}
      <div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
        {/* Search */}
        {search && (
          <div className="w-full sm:w-auto sm:min-w-[300px]">
            <SearchBar
              value={search.value}
              onChange={search.onChange}
              placeholder={search.placeholder || 'Search...'}
            />
          </div>
        )}

        {/* Bulk Actions */}
        {hasSelection && bulkActions && bulkActions.length > 0 && (
          <div className="flex items-center gap-2">
            <span className="text-sm text-muted-foreground">
              {t('dataTable.selected', { count: selectedCount })}
            </span>
            {bulkActions.map((action, index) => (
              <Button
                key={index}
                variant={action.variant === 'destructive' ? 'destructive' : 'outline'}
                size="sm"
                onClick={() => {
                  const selectedIds = Array.from(selection!.selectedRows);
                  action.onClick(selectedIds);
                }}
              >
                {action.icon && <span className="mr-2">{action.icon}</span>}
                {action.label}
              </Button>
            ))}
            <Button
              variant="ghost"
              size="sm"
              onClick={() => selection?.onSelectionChange(new Set())}
            >
              {t('dataTable.clear')}
            </Button>
          </div>
        )}
      </div>

      {/* Select All Checkbox (if selection enabled) */}
      {selection && data.length > 0 && (
        <div className="flex items-center gap-2 px-2">
          <Checkbox
            checked={allSelected}
            ref={(el) => {
              if (el) {
                el.indeterminate = someSelected && !allSelected;
              }
            }}
            onChange={(e) => handleSelectAll(e.target.checked)}
          />
          <span className="text-sm text-muted-foreground">
            {t('dataTable.selectAll', { count: data.length })}
          </span>
        </div>
      )}

      {/* Table */}
      <ResponsiveTable
        data={data}
        columns={finalColumns}
        onSort={handleSort}
        sortedColumn={sorting?.column || null}
        sortDirection={sorting?.direction || null}
        emptyMessage={emptyMessage}
        emptyDescription={emptyDescription}
        emptyAction={emptyAction}
        selectedRows={selection?.selectedRows}
        onRowSelect={(id) => {
          const item = data.find((d) => getRowId(d) === id);
          if (item && selection) {
            const isSelected = selection.selectedRows.has(id);
            handleSelectRow(id, !isSelected);
          }
        }}
        getRowId={getRowId}
        renderMobileCard={renderMobileCard}
        isLoading={isLoading}
      />

      {/* Pagination */}
      {pagination && (
        <div className="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
          <Pagination
            currentPage={pagination.currentPage}
            totalPages={pagination.totalPages}
            onPageChange={pagination.onPageChange}
            pageSize={pagination.pageSize}
            totalItems={pagination.totalItems}
          />
          {pagination.onPageSizeChange && (
            <div className="flex items-center gap-2">
              <span className="text-sm text-muted-foreground">{t('dataTable.itemsPerPage')}</span>
              <select
                value={pagination.pageSize}
                onChange={(e) => pagination.onPageSizeChange?.(Number(e.target.value))}
                className="rounded-md border bg-background px-2 py-1 text-sm"
              >
                <option value={10}>10</option>
                <option value={25}>25</option>
                <option value={50}>50</option>
                <option value={100}>100</option>
              </select>
            </div>
          )}
        </div>
      )}
    </div>
  );
}
