import { 
  Component, 
  Input, 
  Output, 
  EventEmitter, 
  ChangeDetectionStrategy, 
  ViewEncapsulation,
  ContentChild, 
  TemplateRef,
  ViewChild,
  ElementRef,
  OnInit,
  OnDestroy,
  AfterViewInit,
  HostListener,
  signal,
  computed
} from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

export type EnhancedTableVariant = 'default' | 'striped' | 'bordered' | 'minimal';
export type EnhancedTableSize = 'compact' | 'default' | 'comfortable';
export type EnhancedTableColumnAlign = 'left' | 'center' | 'right';
export type FilterOperator = 'equals' | 'contains' | 'startsWith' | 'endsWith' | 'gt' | 'gte' | 'lt' | 'lte' | 'range' | 'in' | 'notIn';

export interface EnhancedTableColumn {
  key: string;
  label: string;
  sortable?: boolean;
  filterable?: boolean;
  resizable?: boolean;
  draggable?: boolean;
  align?: EnhancedTableColumnAlign;
  width?: number;
  minWidth?: number;
  maxWidth?: number;
  sticky?: boolean;
  filterType?: 'text' | 'number' | 'date' | 'select' | 'multi-select';
  filterOptions?: Array<{label: string, value: any}>;
  hidden?: boolean;
}

export interface TableFilter {
  column: string;
  operator: FilterOperator;
  value: any;
  value2?: any; // For range filters
}

export interface TableSort {
  column: string;
  direction: 'asc' | 'desc';
  priority: number; // For multi-column sorting
}

export interface EnhancedTableSortEvent {
  sorting: TableSort[];
}

export interface EnhancedTableFilterEvent {
  filters: TableFilter[];
}

export interface EnhancedTableColumnResizeEvent {
  column: string;
  width: number;
  columnWidths: Record<string, number>;
}

export interface EnhancedTableColumnReorderEvent {
  fromIndex: number;
  toIndex: number;
  columnOrder: string[];
}

export interface VirtualScrollConfig {
  enabled: boolean;
  itemHeight: number;
  buffer?: number;
  trackBy?: (index: number, item: any) => any;
}

@Component({
  selector: 'ui-enhanced-table',
  standalone: true,
  imports: [CommonModule, FormsModule],
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
  template: `
    <div [class]="tableContainerClasses" #tableContainer>
      
      <!-- Filter Row (Optional) -->
      @if (showFilterRow) {
        <div class="ui-enhanced-table__filter-row">
          @for (column of visibleColumns(); track column.key) {
            @if (column.filterable) {
              <div class="ui-enhanced-table__filter-cell" [style.width.px]="getColumnWidth(column.key)">
                @switch (column.filterType || 'text') {
                  @case ('text') {
                    <input
                      type="text"
                      class="ui-enhanced-table__filter-input"
                      [placeholder]="'Filter ' + column.label"
                      [value]="getFilterValue(column.key)"
                      (input)="updateFilter(column.key, 'contains', $any($event.target).value)"
                    />
                  }
                  @case ('number') {
                    <input
                      type="number"
                      class="ui-enhanced-table__filter-input"
                      [placeholder]="'Filter ' + column.label"
                      [value]="getFilterValue(column.key)"
                      (input)="updateFilter(column.key, 'equals', $any($event.target).value)"
                    />
                  }
                  @case ('select') {
                    <select
                      class="ui-enhanced-table__filter-select"
                      [value]="getFilterValue(column.key)"
                      (change)="updateFilter(column.key, 'equals', $any($event.target).value)"
                    >
                      <option value="">All</option>
                      @for (option of column.filterOptions || []; track option.value) {
                        <option [value]="option.value">{{ option.label }}</option>
                      }
                    </select>
                  }
                }
              </div>
            } @else {
              <div class="ui-enhanced-table__filter-cell" [style.width.px]="getColumnWidth(column.key)"></div>
            }
          }
        </div>
      }

      <!-- Virtual Scroll Container -->
      <div class="ui-enhanced-table__scroll-container" #scrollContainer>
        
        <!-- Header -->
        <div class="ui-enhanced-table__header" [class.ui-enhanced-table__header--sticky]="stickyHeader">
          <div class="ui-enhanced-table__header-row">
            @for (column of visibleColumns(); track column.key; let colIndex = $index) {
              <div
                class="ui-enhanced-table__header-cell"
                [class.ui-enhanced-table__header-cell--sortable]="column.sortable"
                [class.ui-enhanced-table__header-cell--sorted]="getSortInfo(column.key).active"
                [class.ui-enhanced-table__header-cell--draggable]="column.draggable"
                [style.width.px]="getColumnWidth(column.key)"
                [style.text-align]="column.align || 'left'"
                [attr.data-column]="column.key"
                [attr.aria-sort]="getSortAttribute(column.key)"
                (click)="handleSort(column, $event)"
                (mousedown)="startColumnReorder($event, colIndex)"
              >
                <div class="ui-enhanced-table__header-content">
                  <span class="ui-enhanced-table__header-text">{{ column.label }}</span>
                  
                  <!-- Sort indicators -->
                  @if (column.sortable) {
                    <div class="ui-enhanced-table__sort-indicators">
                      @for (sort of getCurrentSorting(column.key); track sort.priority) {
                        <span 
                          class="ui-enhanced-table__sort-indicator"
                          [attr.data-direction]="sort.direction"
                          [attr.data-priority]="sort.priority"
                        >
                          @if (sort.direction === 'asc') {
                            ↑
                          } @else {
                            ↓
                          }
                          @if (sorting().length > 1) {
                            <sup>{{ sort.priority + 1 }}</sup>
                          }
                        </span>
                      }
                    </div>
                  }
                </div>
                
                <!-- Resize handle -->
                @if (column.resizable) {
                  <div 
                    class="ui-enhanced-table__resize-handle"
                    (mousedown)="startColumnResize($event, column.key)"
                    (dblclick)="autoSizeColumn(column.key)"
                  ></div>
                }
              </div>
            }
          </div>
        </div>

        <!-- Virtual Scroll Viewport -->
        @if (virtualScrolling.enabled) {
          <div 
            class="ui-enhanced-table__virtual-viewport"
            [style.height.px]="virtualViewportHeight()"
            (scroll)="onVirtualScroll($event)"
          >
            <!-- Spacer before visible items -->
            @if (virtualStartOffset() > 0) {
              <div [style.height.px]="virtualStartOffset()"></div>
            }

            <!-- Visible rows -->
            @for (row of virtualRows(); track virtualScrolling.trackBy ? virtualScrolling.trackBy($index, row) : $index; let rowIndex = $index) {
              <div 
                class="ui-enhanced-table__virtual-row"
                [class.ui-enhanced-table__virtual-row--selected]="selectedRows.has(row)"
                [class.ui-enhanced-table__virtual-row--hover]="hoverable"
                [style.height.px]="virtualScrolling.itemHeight"
                (click)="handleRowClick(row, virtualStartIndex() + rowIndex)"
              >
                @for (column of visibleColumns(); track column.key) {
                  <div 
                    class="ui-enhanced-table__virtual-cell"
                    [style.width.px]="getColumnWidth(column.key)"
                    [style.text-align]="column.align || 'left'"
                  >
                    @if (getCellTemplate(column.key)) {
                      <ng-container 
                        [ngTemplateOutlet]="getCellTemplate(column.key)!" 
                        [ngTemplateOutletContext]="{
                          $implicit: getCellValue(row, column.key),
                          row: row,
                          column: column,
                          index: virtualStartIndex() + rowIndex
                        }"
                      ></ng-container>
                    } @else {
                      <span class="ui-enhanced-table__cell-content">
                        {{ getCellValue(row, column.key) }}
                      </span>
                    }
                  </div>
                }
              </div>
            }

            <!-- Spacer after visible items -->
            @if (virtualEndOffset() > 0) {
              <div [style.height.px]="virtualEndOffset()"></div>
            }
          </div>
        } @else {
          <!-- Traditional table body -->
          <div class="ui-enhanced-table__body">
            @if (filteredAndSortedData().length === 0 && showEmptyState) {
              <div class="ui-enhanced-table__empty-row">
                <div class="ui-enhanced-table__empty-cell">
                  <div class="ui-enhanced-table__empty-content">
                    @if (emptyTemplate) {
                      <ng-container [ngTemplateOutlet]="emptyTemplate"></ng-container>
                    } @else {
                      <div class="ui-enhanced-table__empty-text">{{ emptyMessage }}</div>
                    }
                  </div>
                </div>
              </div>
            } @else {
              @for (row of filteredAndSortedData(); track trackByFn ? trackByFn($index, row) : $index; let rowIndex = $index) {
                <div 
                  class="ui-enhanced-table__row"
                  [class.ui-enhanced-table__row--selected]="selectedRows.has(row)"
                  [class.ui-enhanced-table__row--hover]="hoverable"
                  [class.ui-enhanced-table__row--striped]="rowIndex % 2 === 1 && variant === 'striped'"
                  (click)="handleRowClick(row, rowIndex)"
                >
                  @for (column of visibleColumns(); track column.key) {
                    <div 
                      class="ui-enhanced-table__cell"
                      [style.width.px]="getColumnWidth(column.key)"
                      [style.text-align]="column.align || 'left'"
                    >
                      @if (getCellTemplate(column.key)) {
                        <ng-container 
                          [ngTemplateOutlet]="getCellTemplate(column.key)!" 
                          [ngTemplateOutletContext]="{
                            $implicit: getCellValue(row, column.key),
                            row: row,
                            column: column,
                            index: rowIndex
                          }"
                        ></ng-container>
                      } @else {
                        <span class="ui-enhanced-table__cell-content">
                          {{ getCellValue(row, column.key) }}
                        </span>
                      }
                    </div>
                  }
                </div>
              }
            }
          </div>
        }
      </div>

      <!-- Loading Overlay -->
      @if (loading) {
        <div class="ui-enhanced-table__loading-overlay">
          <div class="ui-enhanced-table__loading-spinner"></div>
          <div class="ui-enhanced-table__loading-text">{{ loadingMessage }}</div>
        </div>
      }

      <!-- Column Reorder Ghost -->
      @if (columnReorderState.dragging) {
        <div 
          class="ui-enhanced-table__column-ghost"
          [style.left.px]="columnReorderState.ghostX"
          [style.top.px]="columnReorderState.ghostY"
        >
          {{ columnReorderState.draggedColumn?.label }}
        </div>
      }
    </div>
  `,
  styleUrl: './enhanced-table.component.scss'
})
export class EnhancedTableComponent implements OnInit, OnDestroy, AfterViewInit {
  @Input() data: any[] = [];
  @Input() columns: EnhancedTableColumn[] = [];
  @Input() variant: EnhancedTableVariant = 'default';
  @Input() size: EnhancedTableSize = 'default';
  @Input() showFilterRow: boolean = false;
  @Input() showEmptyState: boolean = true;
  @Input() emptyMessage: string = 'No data available';
  @Input() loading: boolean = false;
  @Input() loadingMessage: string = 'Loading...';
  @Input() hoverable: boolean = true;
  @Input() selectable: boolean = false;
  @Input() stickyHeader: boolean = false;
  @Input() maxHeight: string = '';
  @Input() trackByFn?: (index: number, item: any) => any;
  @Input() cellTemplates: Record<string, TemplateRef<any>> = {};
  @Input() class: string = '';

  // Enhanced features
  @Input() virtualScrolling: VirtualScrollConfig = { enabled: false, itemHeight: 48, buffer: 5 };
  @Input() multiSort: boolean = false;
  @Input() initialSorting: TableSort[] = [];
  @Input() initialFilters: TableFilter[] = [];
  @Input() initialColumnWidths: Record<string, number> = {};
  @Input() initialColumnOrder: string[] = [];

  @Output() rowClick = new EventEmitter<{row: any, index: number}>();
  @Output() sortChange = new EventEmitter<EnhancedTableSortEvent>();
  @Output() filterChange = new EventEmitter<EnhancedTableFilterEvent>();
  @Output() columnResize = new EventEmitter<EnhancedTableColumnResizeEvent>();
  @Output() columnReorder = new EventEmitter<EnhancedTableColumnReorderEvent>();
  @Output() selectionChange = new EventEmitter<any[]>();

  @ContentChild('emptyTemplate') emptyTemplate?: TemplateRef<any>;
  @ViewChild('tableContainer') tableContainer?: ElementRef<HTMLDivElement>;
  @ViewChild('scrollContainer') scrollContainer?: ElementRef<HTMLDivElement>;

  // Signals for reactive state management
  sorting = signal<TableSort[]>([]);
  filters = signal<TableFilter[]>([]);
  columnWidths = signal<Record<string, number>>({});
  columnOrder = signal<string[]>([]);
  selectedRows: Set<any> = new Set();

  // Virtual scrolling state
  virtualStartIndex = signal(0);
  virtualEndIndex = signal(0);
  virtualViewportHeight = signal(400);

  // Column resizing state
  columnResizeState = {
    resizing: false,
    columnKey: '',
    startX: 0,
    startWidth: 0
  };

  // Column reordering state
  columnReorderState = {
    dragging: false,
    draggedIndex: -1,
    draggedColumn: null as EnhancedTableColumn | null,
    ghostX: 0,
    ghostY: 0
  };

  // Computed properties
  visibleColumns = computed(() => {
    const order = this.columnOrder();
    const cols = this.columns.filter(col => !col.hidden);
    
    if (order.length === 0) {
      return cols;
    }
    
    // Sort columns by order array
    return order
      .map(key => cols.find(col => col.key === key))
      .filter(Boolean) as EnhancedTableColumn[];
  });

  filteredAndSortedData = computed(() => {
    let result = [...this.data];
    
    // Apply filters
    const currentFilters = this.filters();
    currentFilters.forEach(filter => {
      result = this.applyFilter(result, filter);
    });
    
    // Apply sorting
    const currentSorting = this.sorting();
    if (currentSorting.length > 0) {
      result.sort((a, b) => {
        for (const sort of currentSorting.sort((x, y) => x.priority - y.priority)) {
          const valueA = this.getCellValue(a, sort.column);
          const valueB = this.getCellValue(b, sort.column);
          const comparison = this.compareValues(valueA, valueB);
          
          if (comparison !== 0) {
            return sort.direction === 'desc' ? -comparison : comparison;
          }
        }
        return 0;
      });
    }
    
    return result;
  });

  virtualRows = computed(() => {
    if (!this.virtualScrolling.enabled) return [];
    
    const data = this.filteredAndSortedData();
    const start = this.virtualStartIndex();
    const end = Math.min(this.virtualEndIndex(), data.length);
    
    return data.slice(start, end);
  });

  virtualStartOffset = computed(() => {
    return this.virtualStartIndex() * this.virtualScrolling.itemHeight;
  });

  virtualEndOffset = computed(() => {
    const data = this.filteredAndSortedData();
    const remainingItems = data.length - this.virtualEndIndex();
    return remainingItems > 0 ? remainingItems * this.virtualScrolling.itemHeight : 0;
  });

  ngOnInit() {
    // Initialize state from inputs
    this.sorting.set([...this.initialSorting]);
    this.filters.set([...this.initialFilters]);
    this.columnWidths.set({...this.initialColumnWidths});
    this.columnOrder.set([...this.initialColumnOrder]);

    // Set default column widths
    this.initializeColumnWidths();
  }

  ngAfterViewInit() {
    if (this.virtualScrolling.enabled) {
      this.calculateVirtualScrolling();
    }
  }

  ngOnDestroy() {
    // Cleanup event listeners
    document.removeEventListener('mousemove', this.onColumnResize);
    document.removeEventListener('mouseup', this.onColumnResizeEnd);
    document.removeEventListener('mousemove', this.onColumnReorderMove);
    document.removeEventListener('mouseup', this.onColumnReorderEnd);
  }

  get tableContainerClasses(): string {
    return [
      'ui-enhanced-table-container',
      `ui-enhanced-table-container--${this.variant}`,
      `ui-enhanced-table-container--${this.size}`,
      this.stickyHeader ? 'ui-enhanced-table-container--sticky-header' : '',
      this.maxHeight ? 'ui-enhanced-table-container--max-height' : '',
      this.loading ? 'ui-enhanced-table-container--loading' : '',
      this.virtualScrolling.enabled ? 'ui-enhanced-table-container--virtual' : '',
      this.class
    ].filter(Boolean).join(' ');
  }

  private initializeColumnWidths(): void {
    const widths = {...this.columnWidths()};
    this.columns.forEach(column => {
      if (!widths[column.key]) {
        widths[column.key] = column.width || 150;
      }
    });
    this.columnWidths.set(widths);
  }

  getColumnWidth(columnKey: string): number {
    return this.columnWidths()[columnKey] || 150;
  }

  // Virtual scrolling methods
  calculateVirtualScrolling(): void {
    if (!this.scrollContainer) return;

    const container = this.scrollContainer.nativeElement;
    const containerHeight = container.clientHeight;
    const itemHeight = this.virtualScrolling.itemHeight;
    const buffer = this.virtualScrolling.buffer || 5;
    
    const visibleCount = Math.ceil(containerHeight / itemHeight);
    const startIndex = Math.floor(container.scrollTop / itemHeight);
    const bufferedStart = Math.max(0, startIndex - buffer);
    const bufferedEnd = Math.min(
      this.filteredAndSortedData().length,
      startIndex + visibleCount + buffer
    );

    this.virtualStartIndex.set(bufferedStart);
    this.virtualEndIndex.set(bufferedEnd);
    this.virtualViewportHeight.set(this.filteredAndSortedData().length * itemHeight);
  }

  onVirtualScroll(event: Event): void {
    this.calculateVirtualScrolling();
  }

  // Sorting methods
  handleSort(column: EnhancedTableColumn, event?: MouseEvent): void {
    if (!column.sortable) return;

    const currentSorting = [...this.sorting()];
    const existingIndex = currentSorting.findIndex(s => s.column === column.key);

    if (this.multiSort && event?.ctrlKey) {
      // Multi-sort mode
      if (existingIndex >= 0) {
        const existing = currentSorting[existingIndex];
        if (existing.direction === 'asc') {
          existing.direction = 'desc';
        } else {
          currentSorting.splice(existingIndex, 1);
        }
      } else {
        currentSorting.push({
          column: column.key,
          direction: 'asc',
          priority: currentSorting.length
        });
      }
    } else {
      // Single sort mode
      if (existingIndex >= 0) {
        const existing = currentSorting[existingIndex];
        if (existing.direction === 'asc') {
          existing.direction = 'desc';
          currentSorting.splice(0, currentSorting.length, existing);
        } else {
          currentSorting.splice(0, currentSorting.length);
        }
      } else {
        currentSorting.splice(0, currentSorting.length, {
          column: column.key,
          direction: 'asc',
          priority: 0
        });
      }
    }

    // Update priorities
    currentSorting.forEach((sort, index) => {
      sort.priority = index;
    });

    this.sorting.set(currentSorting);
    this.sortChange.emit({ sorting: currentSorting });
  }

  getSortInfo(columnKey: string): {active: boolean, direction?: 'asc' | 'desc', priority?: number} {
    const sort = this.sorting().find(s => s.column === columnKey);
    return sort ? {
      active: true,
      direction: sort.direction,
      priority: sort.priority
    } : { active: false };
  }

  getCurrentSorting(columnKey: string): TableSort[] {
    return this.sorting().filter(s => s.column === columnKey);
  }

  getSortAttribute(columnKey: string): string | null {
    const sort = this.sorting().find(s => s.column === columnKey);
    return sort ? (sort.direction === 'asc' ? 'ascending' : 'descending') : null;
  }

  private compareValues(a: any, b: any): number {
    if (a == null && b == null) return 0;
    if (a == null) return -1;
    if (b == null) return 1;

    // Handle different data types
    if (typeof a === 'string' && typeof b === 'string') {
      return a.localeCompare(b);
    }

    if (typeof a === 'number' && typeof b === 'number') {
      return a - b;
    }

    if (a instanceof Date && b instanceof Date) {
      return a.getTime() - b.getTime();
    }

    // Fallback to string comparison
    return String(a).localeCompare(String(b));
  }

  // Filtering methods
  updateFilter(columnKey: string, operator: FilterOperator, value: any): void {
    const currentFilters = [...this.filters()];
    const existingIndex = currentFilters.findIndex(f => f.column === columnKey);

    if (value === '' || value == null) {
      // Remove filter if value is empty
      if (existingIndex >= 0) {
        currentFilters.splice(existingIndex, 1);
      }
    } else {
      const filter: TableFilter = { column: columnKey, operator, value };
      
      if (existingIndex >= 0) {
        currentFilters[existingIndex] = filter;
      } else {
        currentFilters.push(filter);
      }
    }

    this.filters.set(currentFilters);
    this.filterChange.emit({ filters: currentFilters });
  }

  getFilterValue(columnKey: string): any {
    const filter = this.filters().find(f => f.column === columnKey);
    return filter?.value || '';
  }

  private applyFilter(data: any[], filter: TableFilter): any[] {
    return data.filter(row => {
      const cellValue = this.getCellValue(row, filter.column);
      const filterValue = filter.value;

      switch (filter.operator) {
        case 'equals':
          return cellValue == filterValue;
        case 'contains':
          return String(cellValue).toLowerCase().includes(String(filterValue).toLowerCase());
        case 'startsWith':
          return String(cellValue).toLowerCase().startsWith(String(filterValue).toLowerCase());
        case 'endsWith':
          return String(cellValue).toLowerCase().endsWith(String(filterValue).toLowerCase());
        case 'gt':
          return Number(cellValue) > Number(filterValue);
        case 'gte':
          return Number(cellValue) >= Number(filterValue);
        case 'lt':
          return Number(cellValue) < Number(filterValue);
        case 'lte':
          return Number(cellValue) <= Number(filterValue);
        case 'range':
          const numValue = Number(cellValue);
          return numValue >= Number(filterValue) && numValue <= Number(filter.value2);
        case 'in':
          return Array.isArray(filterValue) && filterValue.includes(cellValue);
        case 'notIn':
          return Array.isArray(filterValue) && !filterValue.includes(cellValue);
        default:
          return true;
      }
    });
  }

  // Column resizing methods
  startColumnResize = (event: MouseEvent, columnKey: string): void => {
    event.preventDefault();
    event.stopPropagation();

    this.columnResizeState = {
      resizing: true,
      columnKey,
      startX: event.clientX,
      startWidth: this.getColumnWidth(columnKey)
    };

    document.addEventListener('mousemove', this.onColumnResize);
    document.addEventListener('mouseup', this.onColumnResizeEnd);
  };

  private onColumnResize = (event: MouseEvent): void => {
    if (!this.columnResizeState.resizing) return;

    const deltaX = event.clientX - this.columnResizeState.startX;
    const newWidth = Math.max(50, this.columnResizeState.startWidth + deltaX);
    
    const widths = {...this.columnWidths()};
    widths[this.columnResizeState.columnKey] = newWidth;
    this.columnWidths.set(widths);
  };

  private onColumnResizeEnd = (): void => {
    if (this.columnResizeState.resizing) {
      this.columnResize.emit({
        column: this.columnResizeState.columnKey,
        width: this.getColumnWidth(this.columnResizeState.columnKey),
        columnWidths: this.columnWidths()
      });
    }

    this.columnResizeState.resizing = false;
    document.removeEventListener('mousemove', this.onColumnResize);
    document.removeEventListener('mouseup', this.onColumnResizeEnd);
  };

  autoSizeColumn(columnKey: string): void {
    // Simple auto-sizing logic - could be enhanced to measure content
    const column = this.columns.find(c => c.key === columnKey);
    if (column) {
      const defaultWidth = Math.max(column.label.length * 8 + 40, 100);
      const widths = {...this.columnWidths()};
      widths[columnKey] = defaultWidth;
      this.columnWidths.set(widths);
    }
  }

  // Column reordering methods
  startColumnReorder = (event: MouseEvent, columnIndex: number): void => {
    if (!this.visibleColumns()[columnIndex]?.draggable) return;

    event.preventDefault();
    this.columnReorderState = {
      dragging: true,
      draggedIndex: columnIndex,
      draggedColumn: this.visibleColumns()[columnIndex],
      ghostX: event.clientX,
      ghostY: event.clientY
    };

    document.addEventListener('mousemove', this.onColumnReorderMove);
    document.addEventListener('mouseup', this.onColumnReorderEnd);
  };

  private onColumnReorderMove = (event: MouseEvent): void => {
    if (!this.columnReorderState.dragging) return;

    this.columnReorderState.ghostX = event.clientX;
    this.columnReorderState.ghostY = event.clientY;
  };

  private onColumnReorderEnd = (event: MouseEvent): void => {
    if (!this.columnReorderState.dragging) return;

    // Find drop target
    const element = document.elementFromPoint(event.clientX, event.clientY);
    const headerCell = element?.closest('.ui-enhanced-table__header-cell');
    
    if (headerCell) {
      const targetColumn = headerCell.getAttribute('data-column');
      const targetIndex = this.visibleColumns().findIndex(c => c.key === targetColumn);
      
      if (targetIndex >= 0 && targetIndex !== this.columnReorderState.draggedIndex) {
        const newOrder = [...this.columnOrder()];
        const draggedKey = this.columnReorderState.draggedColumn!.key;
        
        // Remove dragged item and insert at new position
        const currentIndex = newOrder.indexOf(draggedKey);
        if (currentIndex >= 0) {
          newOrder.splice(currentIndex, 1);
        }
        newOrder.splice(targetIndex, 0, draggedKey);
        
        this.columnOrder.set(newOrder);
        this.columnReorder.emit({
          fromIndex: this.columnReorderState.draggedIndex,
          toIndex: targetIndex,
          columnOrder: newOrder
        });
      }
    }

    this.columnReorderState.dragging = false;
    document.removeEventListener('mousemove', this.onColumnReorderMove);
    document.removeEventListener('mouseup', this.onColumnReorderEnd);
  };

  // Utility methods
  handleRowClick(row: any, index: number): void {
    if (this.selectable) {
      this.toggleRowSelection(row);
    }
    
    this.rowClick.emit({ row, index });
  }

  toggleRowSelection(row: any): void {
    if (this.selectedRows.has(row)) {
      this.selectedRows.delete(row);
    } else {
      this.selectedRows.add(row);
    }
    
    this.selectionChange.emit(Array.from(this.selectedRows));
  }

  getCellValue(row: any, key: string): any {
    return key.split('.').reduce((obj, prop) => obj?.[prop], row) ?? '';
  }

  getCellTemplate(columnKey: string): TemplateRef<any> | null {
    return this.cellTemplates[columnKey] || null;
  }

  @HostListener('window:resize')
  onWindowResize(): void {
    if (this.virtualScrolling.enabled) {
      setTimeout(() => this.calculateVirtualScrolling(), 0);
    }
  }
}