'use client';

import * as React from 'react';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import {
  ChevronLeft,
  ChevronRight,
  ChevronsLeft,
  ChevronsRight,
  ArrowUpDown,
  Download,
  CheckSquare,
  Square,
} from 'lucide-react';
import { useTranslation } from '@/hooks/use-translation';

/**
 * EN: Column definition for DataTable
 * VI: Định nghĩa cột cho DataTable
 */
export interface DataTableColumn<T> {
  /**
   * EN: Column key / VI: Key của cột
   */
  key: keyof T | string;
  /**
   * EN: Column header label / VI: Nhãn header cột
   */
  header: string;
  /**
   * EN: Custom cell renderer / VI: Custom cell renderer
   */
  cell?: (row: T) => React.ReactNode;
  /**
   * EN: Enable sorting / VI: Bật sắp xếp
   */
  sortable?: boolean;
  /**
   * EN: Column width / VI: Chiều rộng cột
   */
  width?: string;
}

/**
 * EN: Sort direction
 * VI: Hướng sắp xếp
 */
export type SortDirection = 'asc' | 'desc' | null;

/**
 * EN: DataTable component props
 * VI: Props của component DataTable
 */
export interface DataTableProps<T> {
  /**
   * EN: Table data / VI: Dữ liệu bảng
   */
  data: T[];
  /**
   * EN: Column definitions / VI: Định nghĩa cột
   */
  columns: DataTableColumn<T>[];
  /**
   * EN: Current page number (1-indexed) / VI: Số trang hiện tại (bắt đầu từ 1)
   */
  currentPage?: number;
  /**
   * EN: Number of items per page / VI: Số item mỗi trang
   */
  itemsPerPage?: number;
  /**
   * EN: Total number of items (for server-side pagination) / VI: Tổng số item (cho pagination phía server)
   */
  totalItems?: number;
  /**
   * EN: Callback when page changes / VI: Callback khi trang thay đổi
   */
  onPageChange?: (page: number) => void;
  /**
   * EN: Enable row selection / VI: Bật chọn hàng
   */
  selectable?: boolean;
  /**
   * EN: Selected row IDs / VI: IDs hàng được chọn
   */
  selectedRows?: string[];
  /**
   * EN: Callback when selection changes / VI: Callback khi selection thay đổi
   */
  onSelectionChange?: (selectedIds: string[]) => void;
  /**
   * EN: Get row ID function / VI: Hàm lấy ID hàng
   */
  getRowId?: (row: T) => string;
  /**
   * EN: Enable bulk actions / VI: Bật bulk actions
   */
  bulkActions?: Array<{
    label: string;
    action: (selectedIds: string[]) => void;
    variant?: 'primary' | 'secondary' | 'danger';
  }>;
  /**
   * EN: Enable export / VI: Bật export
   */
  exportable?: boolean;
  /**
   * EN: Callback for export / VI: Callback cho export
   */
  onExport?: () => void;
  /**
   * EN: Loading state / VI: Trạng thái loading
   */
  loading?: boolean;
  /**
   * EN: Additional CSS classes / VI: Các class CSS bổ sung
   */
  className?: string;
}

/**
 * EN: DataTable component - Advanced table with sorting, filtering, pagination, and bulk actions
 * VI: Component DataTable - Bảng nâng cao với sắp xếp, lọc, pagination và bulk actions
 *
 * Features:
 * - Column sorting
 * - Global search
 * - Column filters
 * - Pagination
 * - Row selection
 * - Bulk actions
 * - Export to CSV/Excel
 * - Column visibility toggle
 *
 * Tính năng:
 * - Sắp xếp cột
 * - Tìm kiếm toàn cục
 * - Lọc cột
 * - Pagination
 * - Chọn hàng
 * - Bulk actions
 * - Export sang CSV/Excel
 * - Toggle hiển thị cột
 */
export function DataTable<T extends Record<string, any>>({
  data,
  columns,
  currentPage = 1,
  itemsPerPage = 10,
  totalItems,
  onPageChange,
  selectable = false,
  selectedRows = [],
  onSelectionChange,
  getRowId = (row) => row.id || String(row),
  bulkActions = [],
  exportable = false,
  onExport,
  loading = false,
  className,
}: DataTableProps<T>) {
  const { t } = useTranslation();
  const [sortColumn, setSortColumn] = React.useState<keyof T | string | null>(null);
  const [sortDirection, setSortDirection] = React.useState<SortDirection>(null);
  const [searchQuery, setSearchQuery] = React.useState('');

  // EN: Calculate pagination / VI: Tính toán pagination
  const totalPages = totalItems
    ? Math.ceil(totalItems / itemsPerPage)
    : Math.ceil(data.length / itemsPerPage);

  const startIndex = (currentPage - 1) * itemsPerPage;
  const endIndex = startIndex + itemsPerPage;

  // EN: Handle sorting / VI: Xử lý sắp xếp
  const handleSort = (columnKey: keyof T | string) => {
    if (sortColumn === columnKey) {
      if (sortDirection === 'asc') {
        setSortDirection('desc');
      } else if (sortDirection === 'desc') {
        setSortColumn(null);
        setSortDirection(null);
      }
    } else {
      setSortColumn(columnKey);
      setSortDirection('asc');
    }
  };

  // EN: Handle row selection / VI: Xử lý chọn hàng
  const handleRowSelect = (rowId: string) => {
    if (!onSelectionChange) return;

    const newSelection = selectedRows.includes(rowId)
      ? selectedRows.filter((id) => id !== rowId)
      : [...selectedRows, rowId];
    onSelectionChange(newSelection);
  };

  // EN: Handle select all / VI: Xử lý chọn tất cả
  const handleSelectAll = () => {
    if (!onSelectionChange) return;

    const allIds = data.map(getRowId);
    const allSelected = allIds.every((id) => selectedRows.includes(id));
    onSelectionChange(allSelected ? [] : allIds);
  };

  // EN: Filter and sort data / VI: Lọc và sắp xếp dữ liệu
  const processedData = React.useMemo(() => {
    let filtered = data;

    // EN: Apply search filter / VI: Áp dụng bộ lọc tìm kiếm
    if (searchQuery) {
      const query = searchQuery.toLowerCase();
      filtered = filtered.filter((row) =>
        columns.some((col) => {
          const value = row[col.key];
          return value && String(value).toLowerCase().includes(query);
        })
      );
    }

    // EN: Apply sorting / VI: Áp dụng sắp xếp
    if (sortColumn && sortDirection) {
      filtered = [...filtered].sort((a, b) => {
        const aValue = a[sortColumn];
        const bValue = b[sortColumn];

        if (aValue === bValue) return 0;

        const comparison = aValue < bValue ? -1 : 1;
        return sortDirection === 'asc' ? comparison : -comparison;
      });
    }

    // EN: Apply pagination / VI: Áp dụng pagination
    return totalItems ? filtered : filtered.slice(startIndex, endIndex);
  }, [data, searchQuery, sortColumn, sortDirection, startIndex, endIndex, totalItems, columns]);

  // EN: Handle page change / VI: Xử lý thay đổi trang
  const handlePageChange = (page: number) => {
    if (page >= 1 && page <= totalPages && onPageChange) {
      onPageChange(page);
    }
  };

  const allSelected = data.length > 0 && data.every((row) => selectedRows.includes(getRowId(row)));
  const someSelected = selectedRows.length > 0 && !allSelected;

  return (
    <div className={cn('space-y-4', className)}>
      {/* EN: Toolbar with search and actions / VI: Toolbar với tìm kiếm và actions */}
      <div className="flex items-center justify-between gap-4">
        <Input
          type="search"
          placeholder={t('common.search')}
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
          className="max-w-sm"
        />
        <div className="flex items-center gap-2">
          {exportable && (
            <Button variant="secondary" size="sm" onClick={onExport}>
              <Download className="h-4 w-4 mr-2" />
              {t('common.export')}
            </Button>
          )}
        </div>
      </div>

      {/* EN: Bulk actions bar / VI: Thanh bulk actions */}
      {selectable && selectedRows.length > 0 && (
        <div className="flex items-center justify-between p-4 bg-bg-tertiary rounded-lg border border-border-primary">
          <span className="text-sm text-text-secondary">
            {selectedRows.length} {t('common.selected')}
          </span>
          <div className="flex items-center gap-2">
            {bulkActions.map((action, index) => (
              <Button
                key={index}
                variant={action.variant || 'secondary'}
                size="sm"
                onClick={() => action.action(selectedRows)}
              >
                {action.label}
              </Button>
            ))}
          </div>
        </div>
      )}

      {/* EN: Table / VI: Bảng */}
      <div className="bg-bg-secondary rounded-lg border border-border-primary overflow-hidden">
        {/* EN: Mobile: Horizontal scroll / VI: Mobile: Scroll ngang */}
        <div className="overflow-x-auto -mx-4 sm:mx-0">
          <div className="inline-block min-w-full align-middle sm:min-w-0">
          {loading ? (
            <div className="p-8 text-center">
              <div className="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-accent-primary border-r-transparent" />
              <p className="mt-4 text-sm text-text-tertiary">
                {t('common.loading')}
              </p>
            </div>
          ) : processedData.length === 0 ? (
            <div className="p-8 text-center">
              <p className="text-sm text-text-tertiary">
                {t('common.noData')}
              </p>
            </div>
          ) : (
            <table className="w-full">
              <thead>
                <tr className="border-b border-border-primary">
                  {selectable && (
                    <th className="px-6 py-3 text-left w-12">
                      <button
                        onClick={handleSelectAll}
                        className="p-1 rounded hover:bg-bg-tertiary transition-colors"
                        aria-label={t('common.selectAll')}
                      >
                        {allSelected ? (
                          <CheckSquare className="h-4 w-4 text-accent-primary" />
                        ) : someSelected ? (
                          <div className="h-4 w-4 border-2 border-accent-primary rounded bg-accent-primary/20" />
                        ) : (
                          <Square className="h-4 w-4 text-text-tertiary" />
                        )}
                      </button>
                    </th>
                  )}
                  {columns.map((column) => (
                    <th
                      key={String(column.key)}
                      className="px-6 py-3 text-left text-xs font-medium text-text-tertiary uppercase tracking-wider"
                      style={{ width: column.width }}
                    >
                      <div className="flex items-center gap-2">
                        <span>{column.header}</span>
                        {column.sortable && (
                          <button
                            onClick={() => handleSort(column.key)}
                            className="p-1 rounded hover:bg-bg-tertiary transition-colors"
                            aria-label={`${t('common.filter')}: ${column.header}`}
                          >
                            <ArrowUpDown
                              className={cn(
                                'h-3 w-3',
                                sortColumn === column.key
                                  ? 'text-accent-primary'
                                  : 'text-text-tertiary'
                              )}
                            />
                          </button>
                        )}
                      </div>
                    </th>
                  ))}
                </tr>
              </thead>
              <tbody className="divide-y divide-border-primary">
                {processedData.map((row) => {
                  const rowId = getRowId(row);
                  const isSelected = selectedRows.includes(rowId);

                  return (
                    <tr
                      key={rowId}
                      className={cn(
                        'hover:bg-bg-tertiary transition-colors duration-[150ms]',
                        isSelected && 'bg-bg-tertiary'
                      )}
                    >
                      {selectable && (
                        <td className="px-6 py-4">
                          <button
                            onClick={() => handleRowSelect(rowId)}
                            className="p-1 rounded hover:bg-bg-elevated transition-colors"
                            aria-label={`${t('common.selectAll')}: ${rowId}`}
                          >
                            {isSelected ? (
                              <CheckSquare className="h-4 w-4 text-accent-primary" />
                            ) : (
                              <Square className="h-4 w-4 text-text-tertiary" />
                            )}
                          </button>
                        </td>
                      )}
                      {columns.map((column) => (
                        <td key={String(column.key)} className="px-6 py-4">
                          {column.cell
                            ? column.cell(row)
                            : String(row[column.key] || '')}
                        </td>
                      ))}
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}
          </div>
        </div>

        {/* EN: Pagination / VI: Pagination */}
        {totalPages > 1 && (
          <div className="px-6 py-4 border-t border-border-primary flex items-center justify-between">
            <div className="text-sm text-text-tertiary">
              {totalItems ? (
                <>
                  {t('common.showing')}{' '}
                  <span className="font-medium text-text-secondary">
                    {startIndex + 1}
                  </span>{' '}
                  {t('common.to')}{' '}
                  <span className="font-medium text-text-secondary">
                    {Math.min(endIndex, totalItems)}
                  </span>{' '}
                  {t('common.of')}{' '}
                  <span className="font-medium text-text-secondary">{totalItems}</span>{' '}
                  {t('common.results')}
                </>
              ) : (
                <>
                  {t('common.showing')}{' '}
                  <span className="font-medium text-text-secondary">
                    {startIndex + 1}
                  </span>{' '}
                  {t('common.to')}{' '}
                  <span className="font-medium text-text-secondary">
                    {Math.min(endIndex, data.length)}
                  </span>{' '}
                  {t('common.of')}{' '}
                  <span className="font-medium text-text-secondary">{data.length}</span>{' '}
                  {t('common.results')}
                </>
              )}
            </div>

            <div className="flex items-center gap-2">
              <Button
                variant="ghost"
                size="sm"
                onClick={() => handlePageChange(1)}
                disabled={currentPage === 1 || loading}
                aria-label={t('common.firstPage')}
                className="min-w-[44px] min-h-[44px]"
              >
                <ChevronsLeft className="h-4 w-4" />
              </Button>
              <Button
                variant="ghost"
                size="sm"
                onClick={() => handlePageChange(currentPage - 1)}
                disabled={currentPage === 1 || loading}
                aria-label={t('common.previous')}
                className="min-w-[44px] min-h-[44px]"
              >
                <ChevronLeft className="h-4 w-4" />
              </Button>
              <span className="text-sm text-text-secondary px-3 hidden sm:inline">
                {t('common.page')} {currentPage} {t('common.of')} {totalPages}
              </span>
              <Button
                variant="ghost"
                size="sm"
                onClick={() => handlePageChange(currentPage + 1)}
                disabled={currentPage === totalPages || loading}
                aria-label={t('common.next')}
                className="min-w-[44px] min-h-[44px]"
              >
                <ChevronRight className="h-4 w-4" />
              </Button>
              <Button
                variant="ghost"
                size="sm"
                onClick={() => handlePageChange(totalPages)}
                disabled={currentPage === totalPages || loading}
                aria-label={t('common.lastPage')}
                className="min-w-[44px] min-h-[44px]"
              >
                <ChevronsRight className="h-4 w-4" />
              </Button>
            </div>
          </div>
        )}
      </div>
    </div>
  );
}
