<template>
  <view class="table-container" :class="containerClass">
    <!-- 表格头部 -->
    <view v-if="showHeader" class="table-header">
      <slot name="header">
        <view class="table-title" v-if="title">{{ title }}</view>
        <view class="table-actions" v-if="$slots.actions">
          <slot name="actions"></slot>
        </view>
      </slot>
    </view>
    
    <!-- 表格主体 -->
    <scroll-view 
      class="table-scroll" 
      :scroll-x="true" 
      :scroll-y="height !== 'auto'"
      :style="scrollStyle"
      @scroll="handleScroll"
    >
      <view class="table" :class="tableClass">
        <!-- 表头 -->
        <view v-if="showTableHeader" class="table-thead">
          <view class="table-tr table-header-row">
            <!-- 选择列 -->
            <view v-if="selectable" class="table-th table-selection-column">
              <checkbox 
                :checked="isAllSelected" 
                :indeterminate="isIndeterminate"
                @change="handleSelectAll"
              />
            </view>
            
            <!-- 序号列 -->
            <view v-if="showIndex" class="table-th table-index-column">
              {{ indexLabel }}
            </view>
            
            <!-- 数据列 -->
            <view 
              v-for="column in columns" 
              :key="column.prop || column.key"
              class="table-th"
              :class="getColumnClass(column)"
              :style="getColumnStyle(column)"
              @click="handleSort(column)"
            >
              <view class="table-th-content">
                <text class="column-title">{{ column.label }}</text>
                
                <!-- 排序图标 -->
                <view v-if="column.sortable" class="sort-icons">
                  <text 
                    class="sort-icon sort-asc"
                    :class="{ active: sortColumn === column.prop && sortOrder === 'asc' }"
                  >↑</text>
                  <text 
                    class="sort-icon sort-desc"
                    :class="{ active: sortColumn === column.prop && sortOrder === 'desc' }"
                  >↓</text>
                </view>
              </view>
            </view>
            
            <!-- 操作列 -->
            <view v-if="$slots.actions || actionColumn" class="table-th table-action-column">
              {{ actionColumn?.label || '操作' }}
            </view>
          </view>
        </view>
        
        <!-- 表体 -->
        <view class="table-tbody">
          <!-- 数据行 -->
          <view 
            v-for="(row, rowIndex) in displayData" 
            :key="getRowKey(row, rowIndex)"
            class="table-tr table-body-row"
            :class="getRowClass(row, rowIndex)"
            @click="handleRowClick(row, rowIndex)"
          >
            <!-- 选择列 -->
            <view v-if="selectable" class="table-td table-selection-column">
              <checkbox 
                :checked="isRowSelected(row)" 
                @change="handleRowSelect(row, $event)"
              />
            </view>
            
            <!-- 序号列 -->
            <view v-if="showIndex" class="table-td table-index-column">
              {{ getRowIndex(rowIndex) }}
            </view>
            
            <!-- 数据列 -->
            <view 
              v-for="column in columns" 
              :key="column.prop || column.key"
              class="table-td"
              :class="getColumnClass(column)"
              :style="getColumnStyle(column)"
            >
              <view class="table-td-content">
                <!-- 自定义渲染 -->
                <slot 
                  v-if="column.slot" 
                  :name="column.slot" 
                  :row="row" 
                  :column="column" 
                  :index="rowIndex"
                  :value="getCellValue(row, column)"
                >
                </slot>
                
                <!-- 默认渲染 -->
                <template v-else>
                  {{ formatCellValue(getCellValue(row, column), column) }}
                </template>
              </view>
            </view>
            
            <!-- 操作列 -->
            <view v-if="$slots.actions || actionColumn" class="table-td table-action-column">
              <slot name="actions" :row="row" :index="rowIndex">
                <view class="action-buttons">
                  <button 
                    v-for="action in actionColumn?.actions || []"
                    :key="action.key"
                    class="action-btn"
                    :class="action.class"
                    :disabled="action.disabled && action.disabled(row)"
                    @click.stop="handleAction(action, row, rowIndex)"
                  >
                    {{ action.label }}
                  </button>
                </view>
              </slot>
            </view>
          </view>
          
          <!-- 空数据 -->
          <view v-if="displayData.length === 0" class="table-empty">
            <slot name="empty">
              <view class="empty-content">
                <image class="empty-icon" :src="emptyIcon" mode="aspectFit"></image>
                <text class="empty-text">{{ emptyText }}</text>
              </view>
            </slot>
          </view>
        </view>
      </view>
    </scroll-view>
    
    <!-- 分页 -->
    <view v-if="pagination && data.length > 0" class="table-pagination">
      <slot name="pagination" :pagination="paginationData">
        <view class="pagination-info">
          共 {{ total }} 条记录，第 {{ currentPage }} / {{ totalPages }} 页
        </view>
        <view class="pagination-controls">
          <button 
            class="pagination-btn" 
            :disabled="currentPage <= 1"
            @click="handlePageChange(currentPage - 1)"
          >
            上一页
          </button>
          <button 
            class="pagination-btn" 
            :disabled="currentPage >= totalPages"
            @click="handlePageChange(currentPage + 1)"
          >
            下一页
          </button>
        </view>
      </slot>
    </view>
    
    <!-- 加载状态 -->
    <view v-if="loading" class="table-loading">
      <uni-loading :size="24"></uni-loading>
      <text class="loading-text">{{ loadingText }}</text>
    </view>
  </view>
</template>

<script>
import { ref, computed, watch } from 'vue'

export default {
  name: 'Table',
  props: {
    // 表格数据
    data: {
      type: Array,
      default: () => []
    },
    
    // 表格列配置
    columns: {
      type: Array,
      default: () => []
    },
    
    // 表格标题
    title: {
      type: String,
      default: ''
    },
    
    // 表格高度
    height: {
      type: [String, Number],
      default: 'auto'
    },
    
    // 是否显示表头
    showHeader: {
      type: Boolean,
      default: true
    },
    
    // 是否显示表格头部
    showTableHeader: {
      type: Boolean,
      default: true
    },
    
    // 是否显示序号列
    showIndex: {
      type: Boolean,
      default: false
    },
    
    // 序号列标题
    indexLabel: {
      type: String,
      default: '#'
    },
    
    // 是否可选择
    selectable: {
      type: Boolean,
      default: false
    },
    
    // 选中的行
    selectedRows: {
      type: Array,
      default: () => []
    },
    
    // 行唯一标识字段
    rowKey: {
      type: String,
      default: 'id'
    },
    
    // 是否斑马纹
    stripe: {
      type: Boolean,
      default: false
    },
    
    // 是否显示边框
    border: {
      type: Boolean,
      default: true
    },
    
    // 表格尺寸
    size: {
      type: String,
      default: 'medium',
      validator: (value) => ['small', 'medium', 'large'].includes(value)
    },
    
    // 空数据文本
    emptyText: {
      type: String,
      default: '暂无数据'
    },
    
    // 空数据图标
    emptyIcon: {
      type: String,
      default: '/static/images/empty.png'
    },
    
    // 加载状态
    loading: {
      type: Boolean,
      default: false
    },
    
    // 加载文本
    loadingText: {
      type: String,
      default: '加载中...'
    },
    
    // 分页配置
    pagination: {
      type: [Boolean, Object],
      default: false
    },
    
    // 操作列配置
    actionColumn: {
      type: Object,
      default: null
    },
    
    // 排序配置
    defaultSort: {
      type: Object,
      default: () => ({})
    }
  },
  
  emits: [
    'row-click', 
    'row-select', 
    'select-all', 
    'sort-change', 
    'page-change',
    'action-click'
  ],
  
  setup(props, { emit }) {
    // 响应式数据
    const selectedRowKeys = ref([...props.selectedRows])
    const sortColumn = ref(props.defaultSort.prop || '')
    const sortOrder = ref(props.defaultSort.order || '')
    const currentPage = ref(1)
    const pageSize = ref(10)
    
    // 计算属性
    const containerClass = computed(() => {
      const classes = []
      
      classes.push(`table-${props.size}`)
      
      if (props.border) {
        classes.push('table-border')
      }
      
      if (props.stripe) {
        classes.push('table-stripe')
      }
      
      if (props.loading) {
        classes.push('table-loading-state')
      }
      
      return classes
    })
    
    const tableClass = computed(() => {
      const classes = ['table-main']
      
      if (props.selectable) {
        classes.push('has-selection')
      }
      
      if (props.showIndex) {
        classes.push('has-index')
      }
      
      return classes
    })
    
    const scrollStyle = computed(() => {
      const style = {}
      
      if (props.height !== 'auto') {
        style.height = typeof props.height === 'number' ? `${props.height}px` : props.height
      }
      
      return style
    })
    
    // 分页数据
    const paginationData = computed(() => {
      if (!props.pagination) return null
      
      const config = typeof props.pagination === 'object' ? props.pagination : {}
      
      return {
        current: currentPage.value,
        pageSize: pageSize.value,
        total: total.value,
        showSizeChanger: config.showSizeChanger || false,
        showQuickJumper: config.showQuickJumper || false,
        ...config
      }
    })
    
    const total = computed(() => props.data.length)
    const totalPages = computed(() => Math.ceil(total.value / pageSize.value))
    
    // 显示的数据
    const displayData = computed(() => {
      let result = [...props.data]
      
      // 排序
      if (sortColumn.value && sortOrder.value) {
        const column = props.columns.find(col => col.prop === sortColumn.value)
        if (column) {
          result.sort((a, b) => {
            const aVal = getCellValue(a, column)
            const bVal = getCellValue(b, column)
            
            let comparison = 0
            if (aVal > bVal) comparison = 1
            if (aVal < bVal) comparison = -1
            
            return sortOrder.value === 'asc' ? comparison : -comparison
          })
        }
      }
      
      // 分页
      if (props.pagination) {
        const start = (currentPage.value - 1) * pageSize.value
        const end = start + pageSize.value
        result = result.slice(start, end)
      }
      
      return result
    })
    
    // 选择相关计算属性
    const isAllSelected = computed(() => {
      return displayData.value.length > 0 && 
             displayData.value.every(row => isRowSelected(row))
    })
    
    const isIndeterminate = computed(() => {
      const selectedCount = displayData.value.filter(row => isRowSelected(row)).length
      return selectedCount > 0 && selectedCount < displayData.value.length
    })
    
    // 方法
    const getRowKey = (row, index) => {
      return row[props.rowKey] || index
    }
    
    const getRowIndex = (index) => {
      if (props.pagination) {
        return (currentPage.value - 1) * pageSize.value + index + 1
      }
      return index + 1
    }
    
    const getRowClass = (row, index) => {
      const classes = []
      
      if (isRowSelected(row)) {
        classes.push('selected')
      }
      
      if (props.stripe && index % 2 === 1) {
        classes.push('stripe')
      }
      
      return classes
    }
    
    const getColumnClass = (column) => {
      const classes = []
      
      if (column.align) {
        classes.push(`text-${column.align}`)
      }
      
      if (column.className) {
        classes.push(column.className)
      }
      
      if (column.sortable) {
        classes.push('sortable')
      }
      
      return classes
    }
    
    const getColumnStyle = (column) => {
      const style = {}
      
      if (column.width) {
        style.width = typeof column.width === 'number' ? `${column.width}px` : column.width
        style.minWidth = style.width
      }
      
      if (column.minWidth) {
        style.minWidth = typeof column.minWidth === 'number' ? `${column.minWidth}px` : column.minWidth
      }
      
      return style
    }
    
    const getCellValue = (row, column) => {
      if (column.prop) {
        return row[column.prop]
      }
      return ''
    }
    
    const formatCellValue = (value, column) => {
      if (column.formatter && typeof column.formatter === 'function') {
        return column.formatter(value, column)
      }
      
      if (value === null || value === undefined) {
        return ''
      }
      
      return String(value)
    }
    
    const isRowSelected = (row) => {
      const key = getRowKey(row)
      return selectedRowKeys.value.includes(key)
    }
    
    // 事件处理
    const handleRowClick = (row, index) => {
      emit('row-click', row, index)
    }
    
    const handleRowSelect = (row, event) => {
      const key = getRowKey(row)
      const checked = event.detail.value.length > 0
      
      if (checked) {
        if (!selectedRowKeys.value.includes(key)) {
          selectedRowKeys.value.push(key)
        }
      } else {
        const index = selectedRowKeys.value.indexOf(key)
        if (index > -1) {
          selectedRowKeys.value.splice(index, 1)
        }
      }
      
      emit('row-select', row, checked, selectedRowKeys.value)
    }
    
    const handleSelectAll = (event) => {
      const checked = event.detail.value.length > 0
      
      if (checked) {
        displayData.value.forEach(row => {
          const key = getRowKey(row)
          if (!selectedRowKeys.value.includes(key)) {
            selectedRowKeys.value.push(key)
          }
        })
      } else {
        displayData.value.forEach(row => {
          const key = getRowKey(row)
          const index = selectedRowKeys.value.indexOf(key)
          if (index > -1) {
            selectedRowKeys.value.splice(index, 1)
          }
        })
      }
      
      emit('select-all', checked, selectedRowKeys.value)
    }
    
    const handleSort = (column) => {
      if (!column.sortable) return
      
      if (sortColumn.value === column.prop) {
        // 切换排序方向
        if (sortOrder.value === 'asc') {
          sortOrder.value = 'desc'
        } else if (sortOrder.value === 'desc') {
          sortOrder.value = ''
          sortColumn.value = ''
        } else {
          sortOrder.value = 'asc'
        }
      } else {
        // 新的排序列
        sortColumn.value = column.prop
        sortOrder.value = 'asc'
      }
      
      emit('sort-change', {
        column: sortColumn.value,
        order: sortOrder.value,
        prop: sortColumn.value
      })
    }
    
    const handlePageChange = (page) => {
      if (page < 1 || page > totalPages.value) return
      
      currentPage.value = page
      emit('page-change', {
        current: page,
        pageSize: pageSize.value,
        total: total.value
      })
    }
    
    const handleAction = (action, row, index) => {
      if (action.handler && typeof action.handler === 'function') {
        action.handler(row, index)
      }
      
      emit('action-click', action, row, index)
    }
    
    const handleScroll = (event) => {
      // 处理滚动事件
    }
    
    // 监听选中行变化
    watch(() => props.selectedRows, (newVal) => {
      selectedRowKeys.value = [...newVal]
    })
    
    return {
      selectedRowKeys,
      sortColumn,
      sortOrder,
      currentPage,
      pageSize,
      containerClass,
      tableClass,
      scrollStyle,
      paginationData,
      total,
      totalPages,
      displayData,
      isAllSelected,
      isIndeterminate,
      getRowKey,
      getRowIndex,
      getRowClass,
      getColumnClass,
      getColumnStyle,
      getCellValue,
      formatCellValue,
      isRowSelected,
      handleRowClick,
      handleRowSelect,
      handleSelectAll,
      handleSort,
      handlePageChange,
      handleAction,
      handleScroll
    }
  }
}
</script>

<style lang="scss" scoped>
.table-container {
  position: relative;
  background: #fff;
  border-radius: 4px;
  
  &.table-border {
    border: 1px solid #ebeef5;
  }
  
  &.table-loading-state {
    pointer-events: none;
  }
}

.table-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  border-bottom: 1px solid #ebeef5;
  
  .table-title {
    font-size: 16px;
    font-weight: 500;
    color: #303133;
  }
}

.table-scroll {
  overflow: auto;
}

.table {
  width: 100%;
  min-width: 100%;
  border-collapse: collapse;
  
  .table-tr {
    display: flex;
    border-bottom: 1px solid #ebeef5;
    
    &:last-child {
      border-bottom: none;
    }
  }
  
  .table-th,
  .table-td {
    flex: 1;
    padding: 12px;
    text-align: left;
    border-right: 1px solid #ebeef5;
    
    &:last-child {
      border-right: none;
    }
    
    &.text-center {
      text-align: center;
    }
    
    &.text-right {
      text-align: right;
    }
  }
  
  .table-th {
    background: #fafafa;
    font-weight: 500;
    color: #909399;
    
    &.sortable {
      cursor: pointer;
      user-select: none;
      
      &:hover {
        background: #f0f0f0;
      }
    }
    
    .table-th-content {
      display: flex;
      align-items: center;
      justify-content: space-between;
    }
    
    .sort-icons {
      display: flex;
      flex-direction: column;
      margin-left: 4px;
      
      .sort-icon {
        font-size: 12px;
        color: #c0c4cc;
        line-height: 1;
        
        &.active {
          color: #409eff;
        }
        
        &.sort-asc {
          margin-bottom: 2px;
        }
      }
    }
  }
  
  .table-td {
    color: #606266;
    
    .table-td-content {
      word-break: break-all;
    }
  }
  
  .table-selection-column,
  .table-index-column {
    flex: 0 0 60px;
    text-align: center;
  }
  
  .table-action-column {
    flex: 0 0 120px;
    
    .action-buttons {
      display: flex;
      gap: 8px;
      
      .action-btn {
        padding: 4px 8px;
        font-size: 12px;
        border: 1px solid #dcdfe6;
        border-radius: 3px;
        background: #fff;
        color: #606266;
        
        &:hover {
          color: #409eff;
          border-color: #c6e2ff;
          background: #ecf5ff;
        }
        
        &:disabled {
          color: #c0c4cc;
          cursor: not-allowed;
          background: #fff;
          border-color: #ebeef5;
        }
      }
    }
  }
}

.table-body-row {
  &:hover {
    background: #f5f7fa;
  }
  
  &.selected {
    background: #ecf5ff;
  }
  
  &.stripe {
    background: #fafafa;
    
    &:hover {
      background: #f0f0f0;
    }
    
    &.selected {
      background: #ecf5ff;
    }
  }
}

.table-empty {
  padding: 40px 0;
  text-align: center;
  
  .empty-content {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    
    .empty-icon {
      width: 60px;
      height: 60px;
      opacity: 0.5;
    }
    
    .empty-text {
      font-size: 14px;
      color: #909399;
    }
  }
}

.table-pagination {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px;
  border-top: 1px solid #ebeef5;
  
  .pagination-info {
    font-size: 14px;
    color: #606266;
  }
  
  .pagination-controls {
    display: flex;
    gap: 8px;
    
    .pagination-btn {
      padding: 6px 12px;
      font-size: 14px;
      border: 1px solid #dcdfe6;
      border-radius: 3px;
      background: #fff;
      color: #606266;
      
      &:hover {
        color: #409eff;
        border-color: #c6e2ff;
        background: #ecf5ff;
      }
      
      &:disabled {
        color: #c0c4cc;
        cursor: not-allowed;
        background: #fff;
        border-color: #ebeef5;
      }
    }
  }
}

.table-loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  background: rgba(255, 255, 255, 0.9);
  padding: 20px;
  border-radius: 4px;
  
  .loading-text {
    font-size: 14px;
    color: #666;
  }
}

// 尺寸变体
.table-small {
  .table-th,
  .table-td {
    padding: 8px;
    font-size: 12px;
  }
}

.table-large {
  .table-th,
  .table-td {
    padding: 16px;
    font-size: 16px;
  }
}
</style>