import { ReactNode, memo, useState, useMemo } from 'react';
import { Text } from './Text';
import { Button } from './Button';
import { Input } from './Input';
import { Select } from './Select';
import { defaultLayoutConfig, type LayoutConfig } from '~/lib/layout-utils';

interface Column<T> {
  key: keyof T | string;
  header: string;
  render?: (item: T) => ReactNode;
  sortable?: boolean;
  filterable?: boolean;
  filterType?: 'text' | 'select' | 'date' | 'number';
  filterOptions?: { value: string; label: string }[];
  className?: string;
  width?: string;
}

interface FilterState {
  [key: string]: string;
}

interface DataTableProps<T> {
  data: T[];
  columns: Column<T>[];
  loading?: boolean;
  emptyMessage?: string;
  className?: string;
  config?: Partial<LayoutConfig>;
  onSort?: (key: string, direction: 'asc' | 'desc') => void;
  sortKey?: string;
  sortDirection?: 'asc' | 'desc';
  searchable?: boolean;
  searchPlaceholder?: string;
  filterable?: boolean;
  pagination?: {
    enabled: boolean;
    pageSize?: number;
    currentPage?: number;
    totalItems?: number;
    onPageChange?: (page: number) => void;
  };
  actions?: {
    label: string;
    render: (item: T) => ReactNode;
  };
}

export const DataTable = memo(function DataTable<T extends Record<string, any>>({
  data,
  columns,
  loading = false,
  emptyMessage = "لا توجد بيانات",
  className = '',
  config = {},
  onSort,
  sortKey,
  sortDirection,
  searchable = false,
  searchPlaceholder = "البحث...",
  filterable = false,
  pagination,
  actions,
}: DataTableProps<T>) {
  const layoutConfig = { ...defaultLayoutConfig, ...config };
  const [searchTerm, setSearchTerm] = useState('');
  const [filters, setFilters] = useState<FilterState>({});

  const handleSort = (key: string) => {
    if (!onSort) return;
    
    const newDirection = sortKey === key && sortDirection === 'asc' ? 'desc' : 'asc';
    onSort(key, newDirection);
  };

  const handleFilterChange = (columnKey: string, value: string) => {
    setFilters(prev => ({
      ...prev,
      [columnKey]: value,
    }));
  };

  // Filter and search data
  const filteredData = useMemo(() => {
    let result = [...data];

    // Apply search
    if (searchable && searchTerm) {
      result = result.filter(item => {
        return columns.some(column => {
          const value = item[column.key];
          if (value == null) return false;
          return String(value).toLowerCase().includes(searchTerm.toLowerCase());
        });
      });
    }

    // Apply column filters
    if (filterable) {
      Object.entries(filters).forEach(([columnKey, filterValue]) => {
        if (filterValue) {
          result = result.filter(item => {
            const value = item[columnKey];
            if (value == null) return false;
            return String(value).toLowerCase().includes(filterValue.toLowerCase());
          });
        }
      });
    }

    return result;
  }, [data, searchTerm, filters, columns, searchable, filterable]);

  // Paginate data
  const paginatedData = useMemo(() => {
    if (!pagination?.enabled) return filteredData;
    
    const pageSize = pagination.pageSize || 10;
    const currentPage = pagination.currentPage || 1;
    const startIndex = (currentPage - 1) * pageSize;
    const endIndex = startIndex + pageSize;
    
    return filteredData.slice(startIndex, endIndex);
  }, [filteredData, pagination]);

  const totalPages = pagination?.enabled 
    ? Math.ceil(filteredData.length / (pagination.pageSize || 10))
    : 1;

  if (loading) {
    return (
      <div className={`bg-white rounded-lg border border-gray-200 ${className}`} dir={layoutConfig.direction}>
        <div className="p-8 text-center">
          <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600 mx-auto mb-4"></div>
          <Text color="secondary">جاري التحميل...</Text>
        </div>
      </div>
    );
  }

  if (data.length === 0) {
    return (
      <div className={`bg-white rounded-lg border border-gray-200 ${className}`} dir={layoutConfig.direction}>
        <div className="p-8 text-center">
          <svg
            className="mx-auto h-12 w-12 text-gray-400 mb-4"
            fill="none"
            stroke="currentColor"
            viewBox="0 0 24 24"
          >
            <path
              strokeLinecap="round"
              strokeLinejoin="round"
              strokeWidth={2}
              d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
            />
          </svg>
          <Text size="lg" weight="medium" className="mb-2">
            لا توجد بيانات
          </Text>
          <Text color="secondary">{emptyMessage}</Text>
        </div>
      </div>
    );
  }

  return (
    <div className={`bg-white rounded-lg border border-gray-200 overflow-hidden ${className}`} dir={layoutConfig.direction}>
      {/* Search and Filters */}
      {(searchable || filterable) && (
        <div className="p-4 border-b border-gray-200 bg-gray-50">
          <div className="flex flex-col space-y-4">
            {/* Search */}
            {searchable && (
              <div className="flex-1">
                <Input
                  placeholder={searchPlaceholder}
                  value={searchTerm}
                  onChange={(e) => setSearchTerm(e.target.value)}
                  startIcon={
                    <svg className="h-4 w-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" />
                    </svg>
                  }
                />
              </div>
            )}
            
            {/* Column Filters */}
            {filterable && (
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
                {columns
                  .filter(column => column.filterable)
                  .map(column => (
                    <div key={`filter-${column.key}`}>
                      {column.filterType === 'select' && column.filterOptions ? (
                        <Select
                          placeholder={`تصفية ${column.header}`}
                          value={filters[column.key as string] || ''}
                          onChange={(e) => handleFilterChange(column.key as string, e.target.value)}
                          options={[
                            { value: '', label: `جميع ${column.header}` },
                            ...column.filterOptions
                          ]}
                        />
                      ) : (
                        <Input
                          placeholder={`تصفية ${column.header}`}
                          value={filters[column.key as string] || ''}
                          onChange={(e) => handleFilterChange(column.key as string, e.target.value)}
                        />
                      )}
                    </div>
                  ))}
              </div>
            )}
          </div>
        </div>
      )}

      {/* Table */}
      <div className="overflow-x-auto">
        <table className="min-w-full divide-y divide-gray-200">
          <thead className="bg-gray-50">
            <tr>
              {columns.map((column) => (
                <th
                  key={`header-${column.key}`}
                  className={`px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider ${column.className || ''}`}
                  style={column.width ? { width: column.width } : undefined}
                >
                  {column.sortable && onSort ? (
                    <button
                      onClick={() => handleSort(column.key as string)}
                      className="group inline-flex items-center space-x-1 space-x-reverse hover:text-gray-700"
                    >
                      <span>{column.header}</span>
                      <span className="ml-2 flex-none rounded text-gray-400 group-hover:text-gray-500">
                        {sortKey === column.key ? (
                          sortDirection === 'asc' ? (
                            <svg className="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
                              <path fillRule="evenodd" d="M14.707 12.707a1 1 0 01-1.414 0L10 9.414l-3.293 3.293a1 1 0 01-1.414-1.414l4-4a1 1 0 011.414 0l4 4a1 1 0 010 1.414z" clipRule="evenodd" />
                            </svg>
                          ) : (
                            <svg className="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
                              <path fillRule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clipRule="evenodd" />
                            </svg>
                          )
                        ) : (
                          <svg className="h-4 w-4" fill="currentColor" viewBox="0 0 20 20">
                            <path d="M5 12a1 1 0 102 0V6.414l1.293 1.293a1 1 0 001.414-1.414l-3-3a1 1 0 00-1.414 0l-3 3a1 1 0 001.414 1.414L5 6.414V12zM15 8a1 1 0 10-2 0v5.586l-1.293-1.293a1 1 0 00-1.414 1.414l3 3a1 1 0 001.414 0l3-3a1 1 0 00-1.414-1.414L15 13.586V8z" />
                          </svg>
                        )}
                      </span>
                    </button>
                  ) : (
                    column.header
                  )}
                </th>
              ))}
              {actions && (
                <th className="px-6 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">
                  {actions.label}
                </th>
              )}
            </tr>
          </thead>
          <tbody className="bg-white divide-y divide-gray-200">
            {paginatedData.map((item, rowIndex) => {
              // Use item.id if available, otherwise fall back to rowIndex
              const rowKey = item.id ? `row-${item.id}` : `row-${rowIndex}`;
              return (
                <tr key={rowKey} className="hover:bg-gray-50">
                  {columns.map((column) => (
                    <td
                      key={`${rowKey}-${column.key}`}
                      className={`px-6 py-4 whitespace-nowrap text-sm text-gray-900 ${column.className || ''}`}
                    >
                      {column.render 
                        ? column.render(item)
                        : String(item[column.key] || '')
                      }
                    </td>
                  ))}
                  {actions && (
                    <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
                      {actions.render(item)}
                    </td>
                  )}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      {/* Pagination */}
      {pagination?.enabled && totalPages > 1 && (
        <div className="px-4 py-3 border-t border-gray-200 bg-gray-50">
          <Pagination
            currentPage={pagination.currentPage || 1}
            totalPages={totalPages}
            onPageChange={pagination.onPageChange || (() => {})}
            config={config}
          />
        </div>
      )}

      {/* Results Summary */}
      {(searchable || filterable || pagination?.enabled) && (
        <div className="px-4 py-2 border-t border-gray-200 bg-gray-50">
          <Text size="sm" color="secondary">
            عرض {paginatedData.length} من {filteredData.length} 
            {filteredData.length !== data.length && ` (مفلتر من ${data.length})`}
          </Text>
        </div>
      )}
    </div>
  );
}) as <T extends Record<string, any>>(props: DataTableProps<T>) => JSX.Element;

interface PaginationProps {
  currentPage: number;
  totalPages: number;
  onPageChange: (page: number) => void;
  className?: string;
  config?: Partial<LayoutConfig>;
}

export const Pagination = memo(function Pagination({
  currentPage,
  totalPages,
  onPageChange,
  className = '',
  config = {},
}: PaginationProps) {
  const layoutConfig = { ...defaultLayoutConfig, ...config };

  if (totalPages <= 1) return null;

  const getPageNumbers = () => {
    const pages = [];
    const maxVisible = 5;
    
    if (totalPages <= maxVisible) {
      for (let i = 1; i <= totalPages; i++) {
        pages.push(i);
      }
    } else {
      if (currentPage <= 3) {
        for (let i = 1; i <= 4; i++) {
          pages.push(i);
        }
        pages.push('...');
        pages.push(totalPages);
      } else if (currentPage >= totalPages - 2) {
        pages.push(1);
        pages.push('...');
        for (let i = totalPages - 3; i <= totalPages; i++) {
          pages.push(i);
        }
      } else {
        pages.push(1);
        pages.push('...');
        for (let i = currentPage - 1; i <= currentPage + 1; i++) {
          pages.push(i);
        }
        pages.push('...');
        pages.push(totalPages);
      }
    }
    
    return pages;
  };

  return (
    <div className={`flex items-center justify-between ${className}`} dir={layoutConfig.direction}>
      <div className="flex items-center space-x-2 space-x-reverse">
        <Button
          variant="outline"
          size="sm"
          onClick={() => onPageChange(currentPage - 1)}
          disabled={currentPage === 1}
        >
          السابق
        </Button>
        
        <div className="flex items-center space-x-1 space-x-reverse">
          {getPageNumbers().map((page, index) => (
            <div key={index}>
              {page === '...' ? (
                <span className="px-3 py-2 text-gray-500">...</span>
              ) : (
                <Button
                  variant={currentPage === page ? "primary" : "outline"}
                  size="sm"
                  onClick={() => onPageChange(page as number)}
                >
                  {page}
                </Button>
              )}
            </div>
          ))}
        </div>
        
        <Button
          variant="outline"
          size="sm"
          onClick={() => onPageChange(currentPage + 1)}
          disabled={currentPage === totalPages}
        >
          التالي
        </Button>
      </div>
      
      <Text color="secondary" size="sm">
        صفحة {currentPage} من {totalPages}
      </Text>
    </div>
  );
});