import 'package:flutter/material.dart';
import 'package:shadcn_ui/shadcn_ui.dart';

class SuperportShadTable<T> extends StatefulWidget {
  final List<T> data;
  final List<ShadTableColumn<T>> columns;
  final Function(T)? onRowTap;
  final Function(T)? onRowDoubleTap;
  final bool showCheckbox;
  final Set<T>? selectedRows;
  final Function(Set<T>)? onSelectionChanged;
  final bool sortable;
  final int rowsPerPage;
  final String? emptyMessage;
  final Widget? header;
  final Widget? footer;
  final bool loading;
  final bool striped;
  final bool hoverable;
  final ScrollController? scrollController;
  
  const SuperportShadTable({
    super.key,
    required this.data,
    required this.columns,
    this.onRowTap,
    this.onRowDoubleTap,
    this.showCheckbox = false,
    this.selectedRows,
    this.onSelectionChanged,
    this.sortable = true,
    this.rowsPerPage = 10,
    this.emptyMessage,
    this.header,
    this.footer,
    this.loading = false,
    this.striped = true,
    this.hoverable = true,
    this.scrollController,
  });
  
  @override
  State<SuperportShadTable<T>> createState() => _SuperportShadTableState<T>();
}

class _SuperportShadTableState<T> extends State<SuperportShadTable<T>> {
  late List<T> _sortedData;
  String? _sortColumn;
  bool _sortAscending = true;
  int _currentPage = 1;
  late Set<T> _selectedRows;
  final ScrollController _defaultScrollController = ScrollController();
  
  ScrollController get _scrollController => 
      widget.scrollController ?? _defaultScrollController;
  
  @override
  void initState() {
    super.initState();
    _sortedData = List.from(widget.data);
    _selectedRows = widget.selectedRows ?? {};
  }
  
  @override
  void didUpdateWidget(SuperportShadTable<T> oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (oldWidget.data != widget.data) {
      _sortedData = List.from(widget.data);
      _applySort();
    }
    if (oldWidget.selectedRows != widget.selectedRows) {
      _selectedRows = widget.selectedRows ?? {};
    }
  }
  
  @override
  void dispose() {
    _defaultScrollController.dispose();
    super.dispose();
  }
  
  void _sort(String columnKey) {
    if (!widget.sortable) return;
    
    setState(() {
      if (_sortColumn == columnKey) {
        _sortAscending = !_sortAscending;
      } else {
        _sortColumn = columnKey;
        _sortAscending = true;
      }
      _applySort();
    });
  }
  
  void _applySort() {
    if (_sortColumn == null) return;
    
    final column = widget.columns.firstWhere(
      (col) => col.key == _sortColumn,
      orElse: () => widget.columns.first,
    );
    
    if (column.sorter != null) {
      _sortedData.sort((a, b) {
        final result = column.sorter!(a, b);
        return _sortAscending ? result : -result;
      });
    }
  }
  
  void _toggleRowSelection(T row) {
    setState(() {
      if (_selectedRows.contains(row)) {
        _selectedRows.remove(row);
      } else {
        _selectedRows.add(row);
      }
      widget.onSelectionChanged?.call(_selectedRows);
    });
  }
  
  void _toggleAllSelection() {
    setState(() {
      if (_selectedRows.length == _pageData.length) {
        _selectedRows.clear();
      } else {
        _selectedRows = Set.from(_pageData);
      }
      widget.onSelectionChanged?.call(_selectedRows);
    });
  }
  
  List<T> get _pageData {
    final startIndex = (_currentPage - 1) * widget.rowsPerPage;
    final endIndex = startIndex + widget.rowsPerPage;
    return _sortedData.sublist(
      startIndex,
      endIndex.clamp(0, _sortedData.length),
    );
  }
  
  int get _totalPages {
    return (_sortedData.length / widget.rowsPerPage).ceil();
  }
  
  @override
  Widget build(BuildContext context) {
    final theme = ShadTheme.of(context);
    
    if (widget.loading) {
      return const Center(
        child: CircularProgressIndicator(),
      );
    }
    
    if (_sortedData.isEmpty) {
      return Center(
        child: Padding(
          padding: const EdgeInsets.all(32),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              Icon(
                Icons.inbox_outlined,
                size: 64,
                color: theme.colorScheme.mutedForeground,
              ),
              const SizedBox(height: 16),
              Text(
                widget.emptyMessage ?? '데이터가 없습니다',
                style: theme.textTheme.muted,
              ),
            ],
          ),
        ),
      );
    }
    
    return Column(
      crossAxisAlignment: CrossAxisAlignment.stretch,
      children: [
        if (widget.header != null) ...[
          widget.header!,
          const SizedBox(height: 16),
        ],
        ShadCard(
          padding: EdgeInsets.zero,
          child: Column(
            children: [
              // 테이블이 가용 너비를 최소한으로 채우되, 컬럼이 더 넓으면 수평 스크롤 허용
              LayoutBuilder(
                builder: (context, constraints) {
                  return SingleChildScrollView(
                    controller: _scrollController,
                    scrollDirection: Axis.horizontal,
                    child: ConstrainedBox(
                      constraints: BoxConstraints(
                        // viewport(=부모)의 가로폭만큼은 항상 채움
                        minWidth: constraints.maxWidth,
                      ),
                      child: DataTable(
                  columns: [
                    if (widget.showCheckbox)
                      DataColumn(
                        label: Checkbox(
                          value: _selectedRows.length == _pageData.length &&
                              _pageData.isNotEmpty,
                          onChanged: (_) => _toggleAllSelection(),
                        ),
                      ),
                    ...widget.columns.map((column) {
                      return DataColumn(
                        label: InkWell(
                          onTap: column.sorter != null && widget.sortable
                              ? () => _sort(column.key)
                              : null,
                          child: Row(
                            children: [
                              Text(
                                column.label,
                                style: theme.textTheme.small.copyWith(
                                  fontWeight: FontWeight.w600,
                                ),
                              ),
                              if (column.sorter != null && widget.sortable) ...[
                                const SizedBox(width: 4),
                                if (_sortColumn == column.key)
                                  Icon(
                                    _sortAscending
                                        ? Icons.arrow_upward
                                        : Icons.arrow_downward,
                                    size: 16,
                                  )
                                else
                                  const Icon(
                                    Icons.unfold_more,
                                    size: 16,
                                  ),
                              ],
                            ],
                          ),
                        ),
                      );
                    }),
                  ],
                  rows: _pageData.asMap().entries.map((entry) {
                    final index = entry.key;
                    final row = entry.value;
                    final isSelected = _selectedRows.contains(row);
                    final isStriped = widget.striped && index.isOdd;
                    
                    return DataRow(
                      selected: isSelected,
                      color: WidgetStateProperty.resolveWith((states) {
                        if (states.contains(WidgetState.selected)) {
                          return theme.colorScheme.accent.withValues(alpha: 0.1);
                        }
                        if (widget.hoverable && 
                            states.contains(WidgetState.hovered)) {
                          return theme.colorScheme.muted.withValues(alpha: 0.5);
                        }
                        if (isStriped) {
                          return theme.colorScheme.muted.withValues(alpha: 0.3);
                        }
                        return null;
                      }),
                      onSelectChanged: widget.showCheckbox
                          ? (_) => _toggleRowSelection(row)
                          : null,
                      cells: [
                        if (widget.showCheckbox)
                          DataCell(
                            Checkbox(
                              value: isSelected,
                              onChanged: (_) => _toggleRowSelection(row),
                            ),
                          ),
                        ...widget.columns.map((column) {
                          final cellValue = column.accessor(row);
                          Widget cellWidget;
                          
                          if (column.render != null) {
                            cellWidget = column.render!(row, cellValue);
                          } else if (cellValue is DateTime) {
                            cellWidget = Text(
                              DateFormat('yyyy-MM-dd HH:mm').format(cellValue),
                              style: theme.textTheme.small,
                            );
                          } else if (cellValue is num) {
                            cellWidget = Text(
                              NumberFormat('#,###').format(cellValue),
                              style: theme.textTheme.small,
                            );
                          } else {
                            cellWidget = Text(
                              cellValue?.toString() ?? '-',
                              style: theme.textTheme.small,
                            );
                          }
                          
                          return DataCell(
                            cellWidget,
                            onTap: widget.onRowTap != null
                                ? () => widget.onRowTap!(row)
                                : null,
                            onDoubleTap: widget.onRowDoubleTap != null
                                ? () => widget.onRowDoubleTap!(row)
                                : null,
                          );
                        }),
                      ],
                    );
                  }).toList(),
                      ),
                    ),
                  );
                },
              ),
              if (_totalPages > 1) ...[
                const Divider(height: 1),
                Padding(
                  padding: const EdgeInsets.all(16),
                  child: Row(
                    mainAxisAlignment: MainAxisAlignment.spaceBetween,
                    children: [
                      Text(
                        '총 ${_sortedData.length}개 중 '
                        '${((_currentPage - 1) * widget.rowsPerPage) + 1}-'
                        '${((_currentPage - 1) * widget.rowsPerPage) + _pageData.length}',
                        style: theme.textTheme.muted,
                      ),
                      Row(
                        children: [
                          ShadButton.outline(
                            size: ShadButtonSize.sm,
                            enabled: _currentPage > 1,
                            onPressed: () {
                              setState(() {
                                _currentPage--;
                              });
                            },
                            child: const Icon(Icons.chevron_left, size: 16),
                          ),
                          const SizedBox(width: 8),
                          Text(
                            '$_currentPage / $_totalPages',
                            style: theme.textTheme.small,
                          ),
                          const SizedBox(width: 8),
                          ShadButton.outline(
                            size: ShadButtonSize.sm,
                            enabled: _currentPage < _totalPages,
                            onPressed: () {
                              setState(() {
                                _currentPage++;
                              });
                            },
                            child: const Icon(Icons.chevron_right, size: 16),
                          ),
                        ],
                      ),
                    ],
                  ),
                ),
              ],
            ],
          ),
        ),
        if (widget.footer != null) ...[
          const SizedBox(height: 16),
          widget.footer!,
        ],
      ],
    );
  }
}

class ShadTableColumn<T> {
  final String key;
  final String label;
  final dynamic Function(T) accessor;
  final Widget Function(T, dynamic)? render;
  final int Function(T, T)? sorter;
  final double? width;
  final bool sortable;
  
  const ShadTableColumn({
    required this.key,
    required this.label,
    required this.accessor,
    this.render,
    this.sorter,
    this.width,
    this.sortable = true,
  });
}
