import React, { useState, useEffect } from 'react';
import {
  Table,
  Paper,
  Group,
  Button,
  TextInput,
  Select,
  ActionIcon,
  Menu,
  Text,
  Badge,
  Box,
  Stack,
  Pagination,
  LoadingOverlay,
  Center,
} from '@mantine/core';
import {
  IconSearch,
  IconPlus,
  IconDots,
  IconEdit,
  IconTrash,
  IconRefresh,
  IconFilter,
} from '@tabler/icons-react';
import { modals } from '@mantine/modals';
import { notifications } from '@mantine/notifications';
import { ListItem, FilterOptions } from '../../types';

export interface TableColumn {
  key: string;
  label: string;
  sortable?: boolean;
  filterable?: boolean;
  width?: string | number;
  render?: (value: any, item: ListItem) => React.ReactNode;
}

export interface TableAction {
  key: string;
  label: string;
  icon?: React.ReactNode;
  color?: string;
  onClick: (item: ListItem) => void;
  show?: (item: ListItem) => boolean;
}

export interface DataTableProps {
  data: ListItem[];
  columns: TableColumn[];
  loading?: boolean;
  error?: string | null;
  title?: string;
  
  // Pagination
  total?: number;
  page?: number;
  pageSize?: number;
  onPageChange?: (page: number) => void;
  
  // Actions
  onAdd?: () => void;
  onEdit?: (item: ListItem) => void;
  onDelete?: (item: ListItem) => Promise<void>;
  onRefresh?: () => void;
  customActions?: TableAction[];
  
  // Filtering & Search
  searchable?: boolean;
  filterable?: boolean;
  filters?: FilterOptions;
  onFiltersChange?: (filters: FilterOptions) => void;
  
  // Styling
  withBorder?: boolean;
  withColumnBorders?: boolean;
  striped?: boolean;
  highlightOnHover?: boolean;
  
  // Empty state
  emptyMessage?: string;
}

const DataTable: React.FC<DataTableProps> = ({
  data,
  columns,
  loading = false,
  error = null,
  title,
  total = 0,
  page = 1,
  pageSize = 10,
  onPageChange,
  onAdd,
  onEdit,
  onDelete,
  onRefresh,
  customActions = [],
  searchable = true,
  filterable = false,
  filters = {},
  onFiltersChange,
  withBorder = true,
  withColumnBorders = false,
  striped = true,
  highlightOnHover = true,
  emptyMessage = 'No data available',
}) => {
  const [localFilters, setLocalFilters] = useState<FilterOptions>(filters);
  
  useEffect(() => {
    setLocalFilters(filters);
  }, [filters]);

  const handleFilterChange = (key: string, value: string) => {
    const newFilters = { ...localFilters, [key]: value };
    setLocalFilters(newFilters);
    onFiltersChange?.(newFilters);
  };

  const handleSearchChange = (value: string) => {
    handleFilterChange('search', value);
  };

  const handleDeleteConfirm = (item: ListItem) => {
    modals.openConfirmModal({
      title: 'Confirm Delete',
      children: (
        <Text size="sm">
          Are you sure you want to delete this item? This action cannot be undone.
        </Text>
      ),
      labels: { confirm: 'Delete', cancel: 'Cancel' },
      confirmProps: { color: 'red' },
      onConfirm: async () => {
        try {
          if (onDelete) {
            await onDelete(item);
            notifications.show({
              title: 'Success',
              message: 'Item deleted successfully',
              color: 'green',
            });
          }
        } catch (error: any) {
          notifications.show({
            title: 'Error',
            message: error.message || 'Failed to delete item',
            color: 'red',
          });
        }
      },
    });
  };

  const renderCellValue = (column: TableColumn, item: ListItem) => {
    const value = item[column.key];
    
    if (column.render) {
      return column.render(value, item);
    }
    
    // Default rendering for common data types
    if (value === null || value === undefined) {
      return <Text c="dimmed">-</Text>;
    }
    
    if (typeof value === 'boolean') {
      return (
        <Badge color={value ? 'green' : 'gray'} size="sm">
          {value ? 'Yes' : 'No'}
        </Badge>
      );
    }
    
    if (column.key === 'status') {
      const statusColors: Record<string, string> = {
        active: 'green',
        inactive: 'gray',
        pending: 'yellow',
        suspended: 'red',
        success: 'green',
        error: 'red',
        warning: 'yellow',
      };
      return (
        <Badge color={statusColors[value] || 'blue'} size="sm">
          {value}
        </Badge>
      );
    }
    
    return <Text>{value.toString()}</Text>;
  };

  const renderActionMenu = (item: ListItem) => {
    const actions: TableAction[] = [];
    
    if (onEdit) {
      actions.push({
        key: 'edit',
        label: 'Edit',
        icon: <IconEdit size={14} />,
        onClick: onEdit,
      });
    }
    
    if (onDelete) {
      actions.push({
        key: 'delete',
        label: 'Delete',
        icon: <IconTrash size={14} />,
        color: 'red',
        onClick: () => handleDeleteConfirm(item),
      });
    }
    
    actions.push(...customActions);
    
    const visibleActions = actions.filter(action => 
      !action.show || action.show(item)
    );
    
    if (visibleActions.length === 0) {
      return null;
    }
    
    return (
      <Menu position="bottom-end">
        <Menu.Target>
          <ActionIcon variant="subtle" color="gray">
            <IconDots size={16} />
          </ActionIcon>
        </Menu.Target>
        <Menu.Dropdown>
          {visibleActions.map((action) => (
            <Menu.Item
              key={action.key}
              leftSection={action.icon}
              color={action.color}
              onClick={() => action.onClick(item)}
            >
              {action.label}
            </Menu.Item>
          ))}
        </Menu.Dropdown>
      </Menu>
    );
  };

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

  return (
    <Stack gap="md">
      {/* Header with title and actions */}
      <Group justify="space-between">
        <Group>
          {title && <Text size="xl" fw={600}>{title}</Text>}
        </Group>
        
        <Group>
          {onRefresh && (
            <ActionIcon variant="light" onClick={onRefresh}>
              <IconRefresh size={16} />
            </ActionIcon>
          )}
          
          {onAdd && (
            <Button leftSection={<IconPlus size={16} />} onClick={onAdd}>
              Add New
            </Button>
          )}
        </Group>
      </Group>

      {/* Filters and Search */}
      {(searchable || filterable) && (
        <Group>
          {searchable && (
            <TextInput
              placeholder="Search..."
              leftSection={<IconSearch size={16} />}
              value={localFilters.search || ''}
              onChange={(e) => handleSearchChange(e.currentTarget.value)}
              style={{ flex: 1 }}
            />
          )}
          
          {filterable && (
            <Group>
              <ActionIcon variant="light">
                <IconFilter size={16} />
              </ActionIcon>
              {/* Add specific filter components as needed */}
            </Group>
          )}
        </Group>
      )}

      {/* Table */}
      <Paper withBorder={withBorder} pos="relative">
        <LoadingOverlay visible={loading} />
        
        {error ? (
          <Center p="xl">
            <Stack align="center" gap="xs">
              <Text c="red" fw={500}>Error loading data</Text>
              <Text c="dimmed" size="sm">{error}</Text>
              {onRefresh && (
                <Button variant="light" size="sm" onClick={onRefresh}>
                  Try Again
                </Button>
              )}
            </Stack>
          </Center>
        ) : data.length === 0 ? (
          <Center p="xl">
            <Stack align="center" gap="xs">
              <Text c="dimmed">{emptyMessage}</Text>
              {onAdd && (
                <Button variant="light" size="sm" onClick={onAdd}>
                  Add First Item
                </Button>
              )}
            </Stack>
          </Center>
        ) : (
          <Table
            striped={striped}
            highlightOnHover={highlightOnHover}
            withColumnBorders={withColumnBorders}
          >
            <Table.Thead>
              <Table.Tr>
                {columns.map((column) => (
                  <Table.Th key={column.key} style={{ width: column.width }}>
                    {column.label}
                  </Table.Th>
                ))}
                {(onEdit || onDelete || customActions.length > 0) && (
                  <Table.Th style={{ width: 50 }}>Actions</Table.Th>
                )}
              </Table.Tr>
            </Table.Thead>
            <Table.Tbody>
              {data.map((item) => (
                <Table.Tr key={item.id}>
                  {columns.map((column) => (
                    <Table.Td key={`${item.id}-${column.key}`}>
                      {renderCellValue(column, item)}
                    </Table.Td>
                  ))}
                  {(onEdit || onDelete || customActions.length > 0) && (
                    <Table.Td>
                      {renderActionMenu(item)}
                    </Table.Td>
                  )}
                </Table.Tr>
              ))}
            </Table.Tbody>
          </Table>
        )}
      </Paper>

      {/* Pagination */}
      {totalPages > 1 && (
        <Group justify="center">
          <Pagination
            total={totalPages}
            value={page}
            onChange={onPageChange}
            size="sm"
          />
        </Group>
      )}
    </Stack>
  );
};

export default DataTable;