/**
 * TablePageTemplate - Master template for CRUD table pages
 * Uses exact same styling as Keywords.tsx page
 * 
 * Usage:
 * <TablePageTemplate
 *   title="Keywords"
 *   subtitle="Manage and organize SEO keywords"
 *   columns={columns}
 *   data={data}
 *   filters={filterConfig}
 *   onSort={(field, direction) => ...}
 * />
 */

import React, { ReactNode, useState, useEffect, useRef, useMemo } from 'react';
import { useLocation } from 'react-router';
import {
  Table,
  TableHeader,
  TableBody,
  TableRow,
  TableCell,
} from '../components/ui/table';
import Checkbox from '../components/form/input/Checkbox';
import Button from '../components/ui/button/Button';
import Input from '../components/form/input/InputField';
import SelectDropdown from '../components/form/SelectDropdown';
import { Dropdown } from '../components/ui/dropdown/Dropdown';
import { DropdownItem } from '../components/ui/dropdown/DropdownItem';
import AlertModal from '../components/ui/alert/AlertModal';
import { ChevronDownIcon, MoreDotIcon, PlusIcon } from '../icons';
import { useHeaderMetrics } from '../context/HeaderMetricsContext';
import { useToast } from '../components/ui/toast/ToastContainer';
import { getDeleteModalConfig } from '../config/pages/delete-modal.config';
import { getBulkActionModalConfig } from '../config/pages/bulk-action-modal.config';
import { getTableActionsConfig } from '../config/pages/table-actions.config';
import BulkExportModal from '../components/common/BulkExportModal';
import BulkStatusUpdateModal from '../components/common/BulkStatusUpdateModal';
import { CompactPagination } from '../components/ui/pagination';
import { usePageSizeStore } from '../store/pageSizeStore';
import { useColumnVisibilityStore } from '../store/columnVisibilityStore';
import ToggleTableRow, { ToggleButton } from '../components/common/ToggleTableRow';
import ColumnSelector from '../components/common/ColumnSelector';

interface ColumnConfig {
  key: string;
  label: string;
  sortable?: boolean;
  sortField?: string; // API field name for sorting (if different from key)
  badge?: boolean;
  numeric?: boolean;
  date?: boolean;
  width?: string;
  fixed?: boolean;
  align?: 'left' | 'center' | 'right';
  render?: (value: any, row: any) => ReactNode;
  toggleable?: boolean; // If true, this column will have a toggle button for expanding content
  toggleContentKey?: string; // Key of the field containing content to display when toggled
  toggleContentLabel?: string; // Label for the expanded content (e.g., "Content Outline")
  defaultVisible?: boolean; // Whether column is visible by default (default: true)
}

interface FilterConfig {
  key: string;
  label: string;
  type: 'text' | 'select' | 'daterange' | 'range' | 'custom';
  placeholder?: string;
  options?: Array<{ value: string; label: string }>;
  min?: number;
  max?: number;
  step?: number;
  className?: string;
  customRender?: () => ReactNode; // For complex custom filters like volume range
  dynamicOptions?: string; // e.g., 'clusters' - flag for dynamic option loading
}

// Action configs are now imported from table-actions.config.ts

interface HeaderMetrics {
  label: string;
  value: string | number;
  accentColor: 'blue' | 'green' | 'amber' | 'purple';
}

interface TablePageTemplateProps {
  columns: ColumnConfig[];
  data: any[];
  loading?: boolean;
  showContent?: boolean; // Controls smooth content reveal (like Keywords.tsx)
  filters?: FilterConfig[];
  filterValues?: Record<string, any>; // Current filter values
  onFilterChange?: (key: string, value: any) => void; // Filter change handler
  onFilterReset?: () => void; // Reset all filters handler
  renderFilters?: ReactNode; // Custom filter rendering from parent (deprecated - use filters prop)
  onEdit?: (row: any) => void; // Handler for edit action (always available)
  onCreate?: () => void;
  createLabel?: string;
  onCreateIcon?: ReactNode; // Icon for create button
  onExportCSV?: () => void; // CSV export button handler
  onExportIcon?: ReactNode; // Icon for export button
  onImport?: () => void;
  onImportIcon?: ReactNode; // Icon for import button
  headerMetrics?: HeaderMetrics[]; // Header metrics for top bar
  selectionLabel?: string; // Custom label for selection count (default: "items")
  pagination?: {
    currentPage: number;
    totalPages: number;
    totalCount: number;
    onPageChange: (page: number) => void;
  };
  selection?: {
    selectedIds: string[];
    onSelectionChange: (ids: string[]) => void;
  };
  sorting?: {
    sortBy: string;
    sortDirection: 'asc' | 'desc';
    onSort: (field: string, direction: 'asc' | 'desc') => void;
  };
  // Delete functionality
  onDelete?: (id: number) => Promise<void>;
  onBulkDelete?: (ids: number[]) => Promise<{ deleted_count: number }>;
  // Export functionality
  onExport?: (row: any) => Promise<void> | void; // Single record export
  // Bulk export functionality
  onBulkExport?: (ids: string[]) => Promise<void>;
  // Bulk status update functionality
  onBulkUpdateStatus?: (ids: string[], status: string) => Promise<void>;
  // Custom bulk actions handler (for actions not covered by delete/export/update_status)
  onBulkAction?: (actionKey: string, ids: string[]) => Promise<void>;
  // Custom row actions handler (for actions that need the full row object)
  onRowAction?: (actionKey: string, row: any) => Promise<void>;
  getItemDisplayName?: (row: any) => string; // Function to get display name from row (e.g., row.keyword or row.name)
  className?: string;
}

export default function TablePageTemplate({
  columns,
  data,
  loading: _loading = false, // Unused - component uses showContent for loading state
  showContent = true,
  filters = [],
  filterValues = {},
  onFilterChange,
  onFilterReset,
  renderFilters,
  onEdit,
  onCreate,
  createLabel = '+ Add',
  onCreateIcon,
  onExportCSV,
  onExportIcon,
  onImport,
  onImportIcon,
  headerMetrics = [],
  selectionLabel = 'items',
  pagination,
  selection,
  sorting,
  onDelete,
  onBulkDelete,
  onBulkExport,
  onBulkUpdateStatus,
  onBulkAction,
  onRowAction,
  onExport,
  getItemDisplayName = (row: any) => row.name || row.keyword || row.title || String(row.id),
  className = '',
}: TablePageTemplateProps) {
  const location = useLocation();
  const [isBulkActionsDropdownOpen, setIsBulkActionsDropdownOpen] = useState(false);
  const [openRowActions, setOpenRowActions] = useState<Map<string | number, boolean>>(new Map());
  const rowActionButtonRefs = React.useRef<Map<string | number, React.RefObject<HTMLButtonElement | null>>>(new Map());
  const bulkActionsButtonRef = React.useRef<HTMLButtonElement>(null);
  
  // Get notification config for current page
  const deleteModalConfig = getDeleteModalConfig(location.pathname);
  const bulkActionModalConfig = getBulkActionModalConfig(location.pathname);
  const tableActionsConfig = getTableActionsConfig(location.pathname);
  
  // Get actions from config (edit/delete always included)
  const rowActions = tableActionsConfig?.rowActions || [];
  const bulkActions = tableActionsConfig?.bulkActions || [];
  
  // Selection and expanded rows state
  const [selectedIds, setSelectedIds] = useState<string[]>(selection?.selectedIds || []);
  const [expandedRows, setExpandedRows] = useState<Set<string | number>>(new Set());
  
  // Delete modal state
  const [deleteModal, setDeleteModal] = useState<{
    isOpen: boolean;
    items: any[];
    isBulk: boolean;
    isLoading: boolean;
  }>({
    isOpen: false,
    items: [],
    isBulk: false,
    isLoading: false,
  });

  // Bulk export modal state
  const [exportModal, setExportModal] = useState<{
    isOpen: boolean;
    itemCount: number;
    isLoading: boolean;
  }>({
    isOpen: false,
    itemCount: 0,
    isLoading: false,
  });

  // Bulk status update modal state
  const [statusUpdateModal, setStatusUpdateModal] = useState<{
    isOpen: boolean;
    itemCount: number;
    isLoading: boolean;
  }>({
    isOpen: false,
    itemCount: 0,
    isLoading: false,
  });
  
  const { setMetrics } = useHeaderMetrics();
  const toast = useToast();
  const { pageSize, setPageSize } = usePageSizeStore();
  const { pageColumns, setPageColumns, getPageColumns } = useColumnVisibilityStore();

  // Column visibility state management with Zustand store (same pattern as site/sector stores)
  // Initialize visible columns from store or defaults
  const initializeVisibleColumns = useMemo(() => {
    const savedColumnKeys = getPageColumns(location.pathname);
    
    if (savedColumnKeys.length > 0) {
      const savedSet = new Set(savedColumnKeys);
      // Validate that all saved columns still exist
      const validColumns = columns.filter(col => savedSet.has(col.key));
      if (validColumns.length > 0) {
        // Add any new columns with defaultVisible !== false
        const newColumns = columns
          .filter(col => !savedSet.has(col.key) && col.defaultVisible !== false)
          .map(col => col.key);
        return new Set([...Array.from(validColumns.map(col => col.key)), ...newColumns]);
      }
    }
    
    // Default: show all columns that have defaultVisible !== false
    return new Set(
      columns
        .filter(col => col.defaultVisible !== false)
        .map(col => col.key)
    );
  }, [columns, location.pathname, getPageColumns]);

  const [visibleColumns, setVisibleColumns] = useState<Set<string>>(initializeVisibleColumns);

  // Update visible columns when columns prop or pathname changes
  useEffect(() => {
    const savedColumnKeys = getPageColumns(location.pathname);
    
    if (savedColumnKeys.length > 0) {
      const savedSet = new Set(savedColumnKeys);
      // Validate that all saved columns still exist
      const validColumns = columns.filter(col => savedSet.has(col.key));
      if (validColumns.length > 0) {
        // Add any new columns with defaultVisible !== false
        const newColumns = columns
          .filter(col => !savedSet.has(col.key) && col.defaultVisible !== false)
          .map(col => col.key);
        const newSet = new Set([...Array.from(validColumns.map(col => col.key)), ...newColumns]);
        setVisibleColumns(newSet);
        // Update store with validated columns
        setPageColumns(location.pathname, Array.from(newSet));
        return;
      }
    }
    
    // Default: show all columns that have defaultVisible !== false
    const defaultSet = new Set(
      columns
        .filter(col => col.defaultVisible !== false)
        .map(col => col.key)
    );
    setVisibleColumns(defaultSet);
    // Save defaults to store
    setPageColumns(location.pathname, Array.from(defaultSet));
  }, [columns, location.pathname, getPageColumns, setPageColumns]);

  // Save to store whenever visibleColumns changes (Zustand persist middleware handles localStorage)
  useEffect(() => {
    setPageColumns(location.pathname, Array.from(visibleColumns));
  }, [visibleColumns, location.pathname, setPageColumns]);

  // Filter columns based on visibility
  const visibleColumnsList = useMemo(() => {
    return columns.filter(col => visibleColumns.has(col.key));
  }, [columns, visibleColumns]);

  // Toggle column visibility
  const handleToggleColumn = (columnKey: string) => {
    setVisibleColumns(prev => {
      const newSet = new Set(prev);
      if (newSet.has(columnKey)) {
        newSet.delete(columnKey);
      } else {
        newSet.add(columnKey);
      }
      return newSet;
    });
  };

  // Sync selectedIds with selection prop
  // Use JSON.stringify to compare array contents, not just reference, to avoid unnecessary updates
  const selectedIdsKey = selection?.selectedIds ? JSON.stringify(selection.selectedIds) : '';
  useEffect(() => {
    if (selection?.selectedIds) {
      setSelectedIds(selection.selectedIds);
    }
  }, [selectedIdsKey]); // Only depend on the stringified array, not the selection object

  // Handle delete click - single item
  const handleDeleteClick = (row: any) => {
    if (!onDelete || !deleteModalConfig) return;
    setDeleteModal({ isOpen: true, items: [row], isBulk: false, isLoading: false });
  };

  // Handle bulk delete
  const handleBulkDelete = (ids: string[]) => {
    if (!onBulkDelete || !deleteModalConfig) return;
    const selectedItems = data.filter(row => ids.includes(String(row.id)));
    setDeleteModal({ isOpen: true, items: selectedItems, isBulk: true, isLoading: false });
  };

  const handleDeleteConfirm = async () => {
    if (deleteModal.items.length === 0 || !deleteModalConfig) return;
    
    setDeleteModal(prev => ({ ...prev, isLoading: true }));
    
    try {
      if (deleteModal.isBulk) {
        // Bulk delete
        if (onBulkDelete) {
          const ids = deleteModal.items.map(item => item.id);
          const result = await onBulkDelete(ids);
          const count = result?.deleted_count || deleteModal.items.length;
          toast.success(`${count} ${deleteModalConfig.itemNamePlural} deleted successfully`);
        }
      } else {
        // Single delete
        if (onDelete) {
          await onDelete(deleteModal.items[0].id);
          toast.success(`${deleteModalConfig.itemNameSingular.charAt(0).toUpperCase() + deleteModalConfig.itemNameSingular.slice(1)} deleted successfully`);
        }
      }
      
      setDeleteModal({ isOpen: false, items: [], isBulk: false, isLoading: false });
      // Clear selection - parent component should handle data reload
      if (selection) {
        selection.onSelectionChange([]);
      }
    } catch (error: any) {
      toast.error(`Failed to delete: ${error.message}`);
      setDeleteModal(prev => ({ ...prev, isLoading: false }));
    }
  };

  // Handle row action click - routes to appropriate handler based on action key
  const handleRowActionClick = async (actionKey: string, row: any) => {
    // Close dropdown for this row
    setOpenRowActions(prev => {
      const newMap = new Map(prev);
      newMap.set(row.id || row, false);
      return newMap;
    });
    
    if (actionKey === 'edit' && onEdit) {
      onEdit(row);
    } else if (actionKey === 'delete' && onDelete && deleteModalConfig) {
      handleDeleteClick(row);
    } else if (actionKey === 'export' && onExport) {
      await onExport(row);
    } else if (onRowAction) {
      // For custom row actions, use onRowAction with full row object
      onRowAction(actionKey, row).catch((error: any) => {
        toast.error(`Action failed: ${error.message}`);
      });
    } else if (onBulkAction) {
      // Fallback: For custom actions, use onBulkAction (but with single item)
      onBulkAction(actionKey, [row.id?.toString() || String(row)]);
    } else {
      toast.info(`Action "${actionKey}" not yet implemented`);
    }
  };

  // Handle bulk action click - routes to appropriate handler based on action key
  const handleBulkActionClick = (actionKey: string, ids: string[]) => {
    if (!selection) return;
    const idsToUse = selection.selectedIds.length > 0 ? selection.selectedIds : ids;
    
    if (actionKey === 'delete' && onBulkDelete && deleteModalConfig) {
      handleBulkDelete(idsToUse);
    } else if (actionKey === 'export' && onBulkExport && bulkActionModalConfig) {
      const count = idsToUse.length;
      setExportModal({ 
        isOpen: true, 
        itemCount: count, 
        isLoading: false,
      });
    } else if (actionKey === 'update_status' && onBulkUpdateStatus && bulkActionModalConfig) {
      setStatusUpdateModal({ isOpen: true, itemCount: idsToUse.length, isLoading: false });
    } else if (onBulkAction) {
      // Custom bulk actions - call page-specific handler
      onBulkAction(actionKey, idsToUse).catch((error: any) => {
        toast.error(`Bulk action failed: ${error.message}`);
      });
    } else {
      // No handler available
      toast.info(`Bulk action "${actionKey}" not yet implemented`);
    }
    setIsBulkActionsDropdownOpen(false);
  };

  const handleExportConfirm = async () => {
    if (!onBulkExport || !selection) return;
    const idsToExport = selection.selectedIds.length > 0 ? selection.selectedIds : selectedIds;
    
    setExportModal(prev => ({ ...prev, isLoading: true }));
    try {
      await onBulkExport(idsToExport);
      toast.success('Export successful');
      setExportModal({ isOpen: false, itemCount: 0, isLoading: false });
      selection.onSelectionChange([]);
    } catch (error: any) {
      toast.error(`Export failed: ${error.message}`);
      setExportModal(prev => ({ ...prev, isLoading: false }));
    }
  };

  const handleStatusUpdateConfirm = async (status: string) => {
    if (!onBulkUpdateStatus || !selection) return;
    setStatusUpdateModal(prev => ({ ...prev, isLoading: true }));
    try {
      await onBulkUpdateStatus(selection.selectedIds, status);
      toast.success('Status updated successfully');
      setStatusUpdateModal({ isOpen: false, itemCount: 0, isLoading: false });
      selection.onSelectionChange([]);
    } catch (error: any) {
      toast.error(`Failed to update status: ${error.message}`);
      setStatusUpdateModal(prev => ({ ...prev, isLoading: false }));
    }
  };

  // Set header metrics when provided
  // Use a ref to track previous metrics and only update when values actually change
  const prevMetricsRef = useRef<string>('');
  const hasSetMetricsRef = useRef(false);
  
  // Create a stable key for comparison - only when headerMetrics has values
  const metricsKey = useMemo(() => {
    if (!headerMetrics || headerMetrics.length === 0) return '';
    try {
      return headerMetrics.map(m => `${m.label}:${String(m.value)}`).join('|');
    } catch {
      return '';
    }
  }, [headerMetrics]);
  
  useEffect(() => {
    // Skip if metrics haven't actually changed
    if (metricsKey === prevMetricsRef.current) {
      return;
    }
    
    // Update metrics if we have new values
    // HeaderMetricsContext will automatically merge these with credit balance
    if (metricsKey) {
      setMetrics(headerMetrics);
      hasSetMetricsRef.current = true;
      prevMetricsRef.current = metricsKey;
    } else if (hasSetMetricsRef.current) {
      // Clear page metrics (credit balance will be preserved by HeaderMetricsContext)
      setMetrics([]);
      hasSetMetricsRef.current = false;
      prevMetricsRef.current = '';
    }
    
    // Cleanup: clear page metrics when component unmounts (credit balance preserved)
    return () => {
      if (hasSetMetricsRef.current) {
        setMetrics([]);
        hasSetMetricsRef.current = false;
      }
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [metricsKey]); // Only depend on the stable key

  // Check if any filters are applied
  // When using renderFilters, check filterValues directly; otherwise check filters prop
  const hasActiveFilters = (renderFilters || filters.length > 0) && Object.values(filterValues).some((value) => {
    if (value === '' || value === null || value === undefined) return false;
    if (typeof value === 'object' && ('min' in value || 'max' in value)) {
      return value.min !== '' && value.min !== null && value.min !== undefined || 
             value.max !== '' && value.max !== null && value.max !== undefined;
    }
    return true;
  });


  // Handle sorting
  const handleSort = (column: ColumnConfig) => {
    if (!column.sortable || !sorting) return;
    
    const sortField = column.sortField || column.key;
    const currentSort = sorting.sortBy === sortField ? sorting.sortDirection : null;
    
    // Cycle: none -> asc -> desc -> none
    let newDirection: 'asc' | 'desc' = 'asc';
    if (currentSort === 'asc') {
      newDirection = 'desc';
    } else if (currentSort === 'desc') {
      // Reset to default sort (created_at desc)
      sorting.onSort('created_at', 'desc');
      return;
    }
    
    sorting.onSort(sortField, newDirection);
  };
  
  const getSortIcon = (column: ColumnConfig) => {
    if (!column.sortable || !sorting) return null;
    
    const sortField = column.sortField || column.key;
    if (sorting.sortBy !== sortField) {
      return (
        <span className="ml-1 cursor-pointer text-gray-400 hover:text-gray-600 dark:hover:text-gray-300">
          ⇅
        </span>
      );
    }
    
    if (sorting.sortDirection === 'asc') {
      return (
        <span className="ml-1 cursor-pointer text-brand-500">
          ↑
        </span>
      );
    } else {
      return (
        <span className="ml-1 cursor-pointer text-brand-500">
          ↓
        </span>
      );
    }
  };

  const handleSelectAll = (checked: boolean) => {
    if (checked) {
      // Only select rows that are not already added - use same logic as handleBulkAddSelected (!keyword.isAdded)
      const allIds = data
        .filter((row) => !(row as any).isAdded) // Only select if isAdded is falsy (false, undefined, or null)
        .map((row) => row.id?.toString() || '')
        .filter(id => id !== '');
      setSelectedIds(allIds);
      selection?.onSelectionChange(allIds);
    } else {
      setSelectedIds([]);
      selection?.onSelectionChange([]);
    }
  };

  const handleSelectRow = (id: string, checked: boolean) => {
    // Don't allow selecting rows that are already added - use same logic as handleBulkAddSelected
    const row = data.find(r => String(r.id) === id);
    if (row && !!(row as any).isAdded) {
      return; // Don't allow selection of already added items
    }
    
    const newSelected = checked
      ? [...selectedIds, id]
      : selectedIds.filter((selectedId) => selectedId !== id);
    setSelectedIds(newSelected);
    selection?.onSelectionChange(newSelected);
  };

  return (
    <div className={className}>
      {/* Filters Row - 75% centered, container inside stretched to 100% */}
      {(renderFilters || filters.length > 0) && (
        <div className="flex justify-center mb-4">
          <div 
            className="w-[75%] igny8-filter-bar p-3 rounded-lg bg-transparent"
            style={{ boxShadow: '0 2px 6px 3px rgba(0, 0, 0, 0.08)' }}
          >
            <div className="flex flex-nowrap gap-3 items-center justify-between w-full">
              <div className="flex flex-nowrap gap-3 items-center flex-1 min-w-0 w-full">
              {renderFilters ? (
                <div className="flex flex-nowrap gap-3 items-center flex-1 min-w-0 w-full">
                  {renderFilters}
                </div>
              ) : (
                <>
                  {filters.map((filter) => {
                    // Handle custom render filters (for complex filters like volume range)
                    if (filter.type === 'custom' && (filter as any).customRender) {
                      return <React.Fragment key={filter.key}>{(filter as any).customRender()}</React.Fragment>;
                    }
                    
                    if (filter.type === 'text') {
                      return (
                        <Input
                          key={filter.key}
                          type="text"
                          placeholder={filter.placeholder || `Search ${filter.label.toLowerCase()}...`}
                          value={filterValues[filter.key] || ''}
                          onChange={(e) => {
                            onFilterChange?.(filter.key, e.target.value);
                          }}
                          className="flex-1 min-w-[200px] h-9"
                        />
                      );
                    } else if (filter.type === 'select') {
                      const currentValue = filterValues[filter.key] || '';
                      return (
                        <SelectDropdown
                          key={filter.key}
                          options={filter.options || []}
                          placeholder={filter.label}
                          value={currentValue}
                          onChange={(value) => {
                            // Ensure we pass the value even if it's an empty string
                            const newValue = value === null || value === undefined ? '' : String(value);
                            onFilterChange?.(filter.key, newValue);
                          }}
                          className={filter.className || "flex-1 min-w-[140px]"}
                        />
                      );
                    }
                    return null;
                  })}
                </>
              )}
              </div>
              {hasActiveFilters && onFilterReset && (
                <Button
                  variant="secondary"
                  size="sm"
                  onClick={onFilterReset}
                  className="flex-shrink-0"
                >
                  Clear Filters
                </Button>
              )}
            </div>
          </div>
        </div>
      )}

      {/* Bulk Actions and Action Buttons Row */}
      <div className="flex justify-between items-center mb-4">
        {/* Bulk Actions - Single button if only one action, dropdown if multiple */}
        {bulkActions.length > 0 && (
          <div className="inline-block">
            {bulkActions.length === 1 ? (
              // Single button for single action
              <Button
                size="md"
                onClick={() => {
                  if (selectedIds.length > 0) {
                    handleBulkActionClick(bulkActions[0].key, selectedIds);
                  }
                }}
                disabled={selectedIds.length === 0}
                variant={bulkActions[0].variant === 'success' ? 'success' : bulkActions[0].variant === 'danger' ? 'primary' : 'primary'}
                startIcon={bulkActions[0].icon}
                className={selectedIds.length === 0 ? "opacity-50 cursor-not-allowed" : ""}
              >
                {bulkActions[0].label}
                {selectedIds.length > 0 && (
                  <span className="ml-2 inline-flex items-center justify-center px-2 py-0.5 text-xs font-medium rounded-full bg-white/20 text-white">
                    {selectedIds.length}
                  </span>
                )}
              </Button>
            ) : (
              // Dropdown for multiple actions
              <>
                <Button
                  ref={bulkActionsButtonRef}
                  size="md"
                  onClick={() => selectedIds.length > 0 && setIsBulkActionsDropdownOpen(!isBulkActionsDropdownOpen)}
                  disabled={selectedIds.length === 0}
                  className={`dropdown-toggle ${selectedIds.length === 0 ? "opacity-50 cursor-not-allowed" : ""}`}
                  endIcon={<ChevronDownIcon className="w-4 h-4" />}
                >
                  Bulk Actions
                  {selectedIds.length > 0 && (
                    <span className="ml-2 inline-flex items-center justify-center px-2 py-0.5 text-xs font-medium rounded-full bg-blue-100 text-blue-800 dark:bg-blue-500/20 dark:text-blue-300">
                      {selectedIds.length}
                    </span>
                  )}
                </Button>
                <Dropdown
                  isOpen={isBulkActionsDropdownOpen && selectedIds.length > 0}
                  onClose={() => setIsBulkActionsDropdownOpen(false)}
                  anchorRef={bulkActionsButtonRef as React.RefObject<HTMLElement>}
                  placement="bottom-left"
                  className="w-48 p-2"
                >
                  {bulkActions.map((action, index) => {
                    const isDelete = action.key === 'delete';
                    const showDivider = isDelete && index > 0;
                    return (
                      <React.Fragment key={action.key}>
                        {showDivider && <div className="my-2 border-t border-gray-200 dark:border-gray-800"></div>}
                        <DropdownItem
                          onItemClick={() => {
                            handleBulkActionClick(action.key, selectedIds);
                          }}
                          className={`flex items-center gap-3 px-3 py-2 font-medium rounded-lg text-sm text-left ${
                            isDelete
                              ? "text-error-500 hover:bg-error-50 hover:text-error-600 dark:text-error-400 dark:hover:bg-error-500/15 dark:hover:text-error-300"
                              : "text-gray-700 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-gray-300"
                          }`}
                        >
                          {action.icon && <span className="flex-shrink-0 w-5 h-5">{action.icon}</span>}
                          <span className="text-left">{action.label}</span>
                        </DropdownItem>
                      </React.Fragment>
                    );
                  })}
                </Dropdown>
              </>
            )}
          </div>
        )}
        
        {/* Action Buttons - Right aligned */}
        <div className="flex gap-2 items-center">
          {/* Column Selector */}
          <ColumnSelector
            columns={columns.map(col => ({
              key: col.key,
              label: col.label,
              defaultVisible: col.defaultVisible !== false,
            }))}
            visibleColumns={visibleColumns}
            onToggleColumn={handleToggleColumn}
          />
          {onExportCSV && (
            <Button
              variant="secondary"
              size="md"
              endIcon={onExportIcon}
              onClick={onExportCSV}
            >
              Export CSV
            </Button>
          )}
          {onImport && (
            <Button
              variant="secondary"
              size="md"
              endIcon={onImportIcon}
              onClick={onImport}
            >
              Import
            </Button>
          )}
          {onCreate && (
            <Button
              variant="primary"
              size="md"
              endIcon={onCreateIcon}
              onClick={onCreate}
            >
              {createLabel}
            </Button>
          )}
        </div>
      </div>

      {/* Data Table - Match Keywords.tsx exact styling */}
      <div className={`rounded-xl border border-gray-200 bg-white dark:border-white/[0.05] dark:bg-white/[0.03] igny8-table-container ${!showContent ? 'loading' : 'loaded'}`} style={{ overflowX: 'auto', overflowY: 'visible' }}>
        <div className="igny8-table-wrapper" style={{ overflow: 'visible' }}>
          <Table className="igny8-table-compact igny8-table-smooth">
            <TableHeader className="border-b border-gray-100 dark:border-white/[0.05]">
              <TableRow>
                {selection && (
                  <TableCell
                    isHeader
                    className="px-5 py-3 font-medium text-gray-500 text-start text-theme-xs dark:text-gray-400 w-12"
                  >
                    {showContent && (
                      <Checkbox
                        checked={(() => {
                          // Use same logic as handleBulkAddSelected - filter by !isAdded
                          const selectableRows = data.filter((row) => !(row as any).isAdded);
                          return selectableRows.length > 0 && selectedIds.length === selectableRows.length;
                        })()}
                        onChange={handleSelectAll}
                        id="select-all"
                      />
                    )}
                  </TableCell>
                )}
                {visibleColumnsList.map((column, colIndex) => {
                  const isLastColumn = colIndex === visibleColumnsList.length - 1;
                  return (
                    <TableCell
                      key={column.key}
                      isHeader
                      className={`px-5 py-3 font-medium text-gray-500 text-${column.align || 'start'} text-theme-xs dark:text-gray-400 ${column.sortable ? 'cursor-pointer hover:text-gray-700 dark:hover:text-gray-300' : ''} ${isLastColumn && rowActions.length > 0 ? 'pr-16' : ''}`}
                    >
                      {column.sortable ? (
                        <div onClick={() => handleSort(column)} className="flex items-center">
                          {column.label}
                          {getSortIcon(column)}
                        </div>
                      ) : (
                        <>
                          {column.label}
                          {getSortIcon(column)}
                        </>
                      )}
                    </TableCell>
                  );
                })}
              </TableRow>
            </TableHeader>
            <TableBody className="divide-y divide-gray-100 dark:divide-white/[0.05] igny8-table-body">
              {!showContent ? (
                // Loading Skeleton Rows - Always show 10 rows to match page size
                Array.from({ length: 10 }).map((_, index) => (
                  <TableRow key={`skeleton-${index}`} className="igny8-skeleton-row">
                    {selection && <TableCell><div className="h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div></TableCell>}
                    {visibleColumnsList.map((_, colIndex) => (
                      <TableCell key={colIndex}><div className="h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"></div></TableCell>
                    ))}
                  </TableRow>
                ))
              ) : data.length === 0 ? null : (
                data.map((row, index) => {
                  // Use consistent key for expandedRows (number or index)
                  const rowKey = row.id || index;
                  const isRowExpanded = expandedRows.has(rowKey);
                  
                  // Find toggleable column
                  const toggleableColumn = columns.find(col => col.toggleable);
                  const toggleContentKey = toggleableColumn?.toggleContentKey || toggleableColumn?.key;
                  const toggleContentLabel = toggleableColumn?.toggleContentLabel || 'Content';
                  const toggleContent = toggleContentKey ? row[toggleContentKey] : null;
                  // Check if content exists - handle both strings and objects (JSON)
                  const hasToggleContent = toggleContent && (
                    typeof toggleContent === 'string' 
                      ? toggleContent.trim().length > 0 
                      : typeof toggleContent === 'object' && toggleContent !== null && Object.keys(toggleContent).length > 0
                  );
                  
                  // Calculate colSpan for toggle row
                  const colSpan = (selection ? 1 : 0) + visibleColumnsList.length;
                  
                  const handleToggle = (expanded: boolean, id: string | number) => {
                    setExpandedRows(prev => {
                      const newSet = new Set(prev);
                      // Use the id parameter (which should match rowKey when called from button)
                      const keyToUse = id !== undefined && id !== null ? id : rowKey;
                      if (expanded) {
                        newSet.add(keyToUse);
                      } else {
                        newSet.delete(keyToUse);
                      }
                      return newSet;
                    });
                  };
                  
                  // Check if row is already added (for keyword opportunities)
                  // Use same logic as handleBulkAddSelected - check if isAdded is truthy
                  const isRowAdded = !!(row as any).isAdded;
                  
                  return (
                    <React.Fragment key={row.id || index}>
                      <TableRow 
                        className={`igny8-data-row ${isRowAdded ? 'bg-blue-50 dark:bg-blue-500/10' : ''}`}
                      >
                        {selection && (
                          <TableCell className="px-5 py-4 text-start">
                            <Checkbox
                              checked={selectedIds.includes(row.id?.toString() || '')}
                              onChange={(checked) => handleSelectRow(row.id?.toString() || '', checked)}
                              id={`checkbox-${row.id}`}
                              disabled={isRowAdded}
                            />
                          </TableCell>
                        )}
                        {visibleColumnsList.map((column, colIndex) => {
                          const isLastColumn = colIndex === visibleColumnsList.length - 1;
                          const rowId = row.id || index;
                          
                          // Get or create ref for this row's actions button
                          if (isLastColumn && rowActions.length > 0) {
                            if (!rowActionButtonRefs.current.has(rowId)) {
                              const ref = React.createRef<HTMLButtonElement>();
                              rowActionButtonRefs.current.set(rowId, ref);
                            }
                          }
                          
                          return (
                            <TableCell 
                              key={column.key} 
                              className={`px-5 py-4 text-${column.align || 'start'} text-gray-800 dark:text-white/90 ${isLastColumn && rowActions.length > 0 ? 'relative pr-16' : ''}`}
                            >
                              <div className={`flex items-center ${column.toggleable && hasToggleContent ? 'justify-between w-full' : ''} gap-2`}>
                                <div className="flex-1">
                                  {column.render ? (
                                    column.render(row[column.key], row)
                                  ) : (
                                    <span>{row[column.key]?.toString() || '-'}</span>
                                  )}
                                </div>
                                {column.toggleable && hasToggleContent && (
                                  <div onClick={(e) => e.stopPropagation()}>
                                    <ToggleButton
                                      isExpanded={isRowExpanded}
                                      onClick={() => {
                                        handleToggle(!isRowExpanded, rowKey);
                                      }}
                                      hasContent={hasToggleContent}
                                    />
                                  </div>
                                )}
                              </div>
                              
                              {/* Actions button - absolutely positioned in last column */}
                              {isLastColumn && rowActions.length > 0 && (() => {
                                // Check if row is already added - use same logic as handleBulkAddSelected
                                const isRowAdded = !!(row as any).isAdded;
                                
                                // Single text link if only one action, dropdown if multiple
                                if (rowActions.length === 1) {
                                  const action = rowActions[0];
                                  
                                  // If already added, show "Added" text in info color
                                  if (isRowAdded) {
                                    return (
                                      <div className="absolute right-2 top-1/2 -translate-y-1/2 z-10">
                                        <span className="text-sm font-medium text-blue-light-500 dark:text-blue-light-400">
                                          Added
                                        </span>
                                      </div>
                                    );
                                  }
                                  
                                  // Otherwise show "Add +" button
                                  return (
                                    <div className="absolute right-2 top-1/2 -translate-y-1/2 z-10">
                                      <button
                                        type="button"
                                        onClick={(e) => {
                                          e.stopPropagation();
                                          handleRowActionClick(action.key, row);
                                        }}
                                        className="flex items-center gap-1 text-sm font-medium text-success-500 hover:text-success-600 dark:text-success-400 dark:hover:text-success-300 transition-colors cursor-pointer"
                                      >
                                        {action.label}
                                        <span className="inline-flex items-center">
                                          <PlusIcon className="w-4 h-4 fill-current" />
                                        </span>
                                      </button>
                                    </div>
                                  );
                                }
                                
                                // Multiple actions - use dropdown
                                const buttonRef = rowActionButtonRefs.current.get(rowId);
                                if (!buttonRef) return null;
                                const isOpen = openRowActions.get(rowId) || false;
                                
                                return (
                                  <>
                                    <button
                                      ref={buttonRef}
                                      type="button"
                                      onClick={(e) => {
                                        e.stopPropagation();
                                        setOpenRowActions(prev => {
                                          const newMap = new Map(prev);
                                          // Close all other dropdowns
                                          newMap.forEach((_, key) => {
                                            if (key !== rowId) newMap.set(key, false);
                                          });
                                          // Toggle current row dropdown
                                          newMap.set(rowId, !newMap.get(rowId));
                                          return newMap;
                                        });
                                      }}
                                      className="absolute right-2 top-1/2 -translate-y-1/2 inline-flex items-center justify-center w-8 h-8 rounded-lg transition-colors text-gray-500 hover:text-gray-700 hover:bg-gray-100 dark:text-gray-400 dark:hover:text-gray-300 dark:hover:bg-gray-800 dropdown-toggle z-10"
                                      title="Actions"
                                    >
                                      <MoreDotIcon className="w-5 h-5" />
                                    </button>
                                    <Dropdown
                                      isOpen={isOpen}
                                      onClose={() => {
                                        setOpenRowActions(prev => {
                                          const newMap = new Map(prev);
                                          newMap.set(rowId, false);
                                          return newMap;
                                        });
                                      }}
                                      anchorRef={buttonRef as React.RefObject<HTMLElement>}
                                      placement="right"
                                      className="w-48 p-2"
                                    >
                                      {rowActions.map((action) => {
                                        const isEdit = action.key === 'edit';
                                        const isDelete = action.key === 'delete';
                                        const isExport = action.key === 'export';
                                        
                                        // Clone icon with appropriate color based on action type
                                        const getIconWithColor = () => {
                                          if (!action.icon) return null;
                                          const iconElement = action.icon as React.ReactElement;
                                          const existingClassName = (iconElement.props as any)?.className || "";
                                          const baseSize = existingClassName.includes("w-") ? "" : "w-5 h-5 ";
                                          
                                          if (isEdit) {
                                            return React.cloneElement(iconElement, {
                                              className: `${baseSize}text-blue-light-500 ${existingClassName}`.trim()
                                            } as any);
                                          } else if (isDelete) {
                                            return React.cloneElement(iconElement, {
                                              className: `${baseSize}text-error-500 ${existingClassName}`.trim()
                                            } as any);
                                          } else if (isExport) {
                                            return React.cloneElement(iconElement, {
                                              className: `${baseSize}text-gray-600 dark:text-gray-400 ${existingClassName}`.trim()
                                            } as any);
                                          }
                                          return action.icon;
                                        };
                                        
                                        return (
                                          <React.Fragment key={action.key}>
                                            <DropdownItem
                                              onItemClick={() => handleRowActionClick(action.key, row)}
                                              className={`flex items-center gap-3 px-3 py-2 font-medium rounded-lg text-sm text-left ${
                                                isEdit
                                                  ? "text-blue-light-500 hover:bg-blue-light-50 hover:text-blue-light-600 dark:text-blue-light-400 dark:hover:bg-blue-light-500/15 dark:hover:text-blue-light-300"
                                                  : isDelete
                                                  ? "text-error-500 hover:bg-error-50 hover:text-error-600 dark:text-error-400 dark:hover:bg-error-500/15 dark:hover:text-error-300"
                                                  : "text-gray-700 hover:bg-gray-100 hover:text-gray-700 dark:text-gray-400 dark:hover:bg-white/5 dark:hover:text-gray-300"
                                              }`}
                                            >
                                              <span className="flex-shrink-0 w-5 h-5">{getIconWithColor()}</span>
                                              <span className="text-left">{action.label}</span>
                                            </DropdownItem>
                                            {isExport && (
                                              <div className="my-2 border-t border-gray-200 dark:border-gray-800"></div>
                                            )}
                                          </React.Fragment>
                                        );
                                      })}
                                    </Dropdown>
                                  </>
                                );
                              })()}
                            </TableCell>
                          );
                        })}
                      </TableRow>
                      {/* Toggle Row for expandable content */}
                      {toggleableColumn && hasToggleContent && (
                        <ToggleTableRow
                          row={row}
                          contentKey={toggleContentKey || ''}
                          contentLabel={toggleContentLabel}
                          colSpan={colSpan}
                          isExpanded={isRowExpanded}
                          onToggle={handleToggle}
                        />
                      )}
                    </React.Fragment>
                  );
                })
              )}
            </TableBody>
          </Table>
        </div>
      </div>

      {/* Delete Confirmation Modal */}
      {deleteModalConfig && (
        <AlertModal
          isOpen={deleteModal.isOpen}
          onClose={() => setDeleteModal({ isOpen: false, items: [], isBulk: false, isLoading: false })}
          onConfirm={handleDeleteConfirm}
          title={deleteModalConfig.title}
          message={
            deleteModal.isBulk
              ? deleteModalConfig.multipleItemsMessage(deleteModal.items.length)
              : deleteModalConfig.singleItemMessage
          }
          variant="danger"
          isConfirmation={true}
          confirmText="Delete"
          cancelText="Cancel"
          isLoading={deleteModal.isLoading}
          itemsList={deleteModal.items.map(item => getItemDisplayName(item))}
        />
      )}

      {/* Bulk Export Confirmation Modal */}
      {bulkActionModalConfig && (
        <BulkExportModal
          isOpen={exportModal.isOpen}
          onClose={() => setExportModal({ isOpen: false, itemCount: 0, isLoading: false })}
                onConfirm={handleExportConfirm}
                title={bulkActionModalConfig.export.title}
                message={bulkActionModalConfig.export.message(exportModal.itemCount)}
                confirmText={bulkActionModalConfig.export.confirmText}
                isLoading={exportModal.isLoading}
              />
      )}

      {/* Bulk Status Update Modal */}
      {bulkActionModalConfig && (
        <BulkStatusUpdateModal
          isOpen={statusUpdateModal.isOpen}
          onClose={() => setStatusUpdateModal({ isOpen: false, itemCount: 0, isLoading: false })}
          onConfirm={handleStatusUpdateConfirm}
          title={bulkActionModalConfig.updateStatus.title}
          message={bulkActionModalConfig.updateStatus.message(statusUpdateModal.itemCount)}
          confirmText={bulkActionModalConfig.updateStatus.confirmText}
          statusOptions={bulkActionModalConfig.updateStatus.statusOptions}
          isLoading={statusUpdateModal.isLoading}
        />
      )}

      {/* Pagination - Compact icon-based pagination */}
      {pagination && (
        <div className="mt-6 border-t border-gray-200 dark:border-gray-800 pt-6">
          <div className="flex items-center justify-between">
            <div className="text-sm text-gray-500 dark:text-gray-400">
              Showing {data.length} of {pagination.totalCount} {selectionLabel || 'items'}
            </div>
            <CompactPagination
              currentPage={pagination.currentPage}
              totalPages={pagination.totalPages}
              pageSize={pageSize}
              onPageChange={(page) => {
                pagination.onPageChange(page);
              }}
              onPageSizeChange={(size) => {
                setPageSize(size);
                // Reset to page 1 when page size changes
                // The parent component should handle reloading via useEffect
                pagination.onPageChange(1);
              }}
            />
          </div>
        </div>
      )}

    </div>
  );
}
