<script setup>
import { computed, ref, watch, onMounted } from 'vue';
import { useDesignSystem } from '~/composables/useDesignSystem';
import { useTouchInteractions } from '~/composables/useTouchInteractions';
import LoadingStates from './LoadingStates.vue';
import RsButton from '~/components/RsButton.vue';

const props = defineProps({
  // Data
  data: {
    type: Array,
    default: () => []
  },
  
  // Column definitions
  columns: {
    type: Array,
    required: true
  },
  
  // Loading state
  loading: {
    type: Boolean,
    default: false
  },
  
  // Pagination
  pagination: {
    type: Object,
    default: () => ({
      page: 1,
      pageSize: 10,
      total: 0,
      showSizeChanger: true,
      pageSizes: [10, 25, 50, 100]
    })
  },
  
  // Selection
  selectable: {
    type: Boolean,
    default: false
  },
  
  // Sorting
  sortable: {
    type: Boolean,
    default: true
  },
  
  // Filtering
  filterable: {
    type: Boolean,
    default: true
  },
  
  // Responsive behavior
  responsive: {
    type: Boolean,
    default: true
  },
  
  // Row actions
  actions: {
    type: Array,
    default: () => []
  },
  
  // Empty state
  emptyText: {
    type: String,
    default: 'No data available'
  },
  
  // Table size
  size: {
    type: String,
    default: 'md',
    validator: (value) => ['sm', 'md', 'lg'].includes(value)
  }
});

const emit = defineEmits([
  'sort-change', 'filter-change', 'page-change', 'selection-change',
  'row-click', 'row-double-click', 'action-click'
]);

// Design system
const { tokens, utils, layouts } = useDesignSystem();

// Table state
const selectedRows = ref(new Set());
const sortConfig = ref({ key: null, direction: 'asc' });
const filters = ref({});
const currentPage = ref(props.pagination.page);
const pageSize = ref(props.pagination.pageSize);
const expandedRows = ref(new Set());

// Mobile state
const isMobile = ref(false);
const showMobileFilters = ref(false);

// Column management
const visibleColumns = ref([]);
const columnWidths = ref({});

// Filter processed data
const processedData = computed(() => {
  let result = [...props.data];
  
  // Apply filters
  Object.entries(filters.value).forEach(([key, value]) => {
    if (value && value.trim()) {
      result = result.filter(row => {
        const cellValue = row[key];
        if (cellValue === null || cellValue === undefined) return false;
        return cellValue.toString().toLowerCase().includes(value.toLowerCase());
      });
    }
  });
  
  // Apply sorting
  if (sortConfig.value.key) {
    result.sort((a, b) => {
      const aVal = a[sortConfig.value.key];
      const bVal = b[sortConfig.value.key];
      
      if (aVal === null || aVal === undefined) return 1;
      if (bVal === null || bVal === undefined) return -1;
      
      const comparison = aVal < bVal ? -1 : aVal > bVal ? 1 : 0;
      return sortConfig.value.direction === 'desc' ? -comparison : comparison;
    });
  }
  
  return result;
});

// Paginated data
const paginatedData = computed(() => {
  const start = (currentPage.value - 1) * pageSize.value;
  const end = start + pageSize.value;
  return processedData.value.slice(start, end);
});

// Table classes
const tableClasses = computed(() => {
  const sizeMap = {
    sm: 'text-sm',
    md: 'text-sm',
    lg: 'text-base'
  };
  
  return utils.composeClasses(
    'w-full border-collapse',
    sizeMap[props.size],
    props.responsive ? 'table-responsive' : ''
  );
});

// Handle sorting
const handleSort = (column) => {
  if (!column.sortable && !props.sortable) return;
  
  if (sortConfig.value.key === column.key) {
    sortConfig.value.direction = sortConfig.value.direction === 'asc' ? 'desc' : 'asc';
  } else {
    sortConfig.value = { key: column.key, direction: 'asc' };
  }
  
  emit('sort-change', sortConfig.value);
};

// Handle filtering
const handleFilter = (column, value) => {
  filters.value[column.key] = value;
  currentPage.value = 1; // Reset to first page
  emit('filter-change', filters.value);
};

// Handle selection
const handleRowSelection = (row, selected) => {
  if (selected) {
    selectedRows.value.add(row.id);
  } else {
    selectedRows.value.delete(row.id);
  }
  
  emit('selection-change', Array.from(selectedRows.value));
};

const handleSelectAll = (selected) => {
  if (selected) {
    processedData.value.forEach(row => selectedRows.value.add(row.id));
  } else {
    selectedRows.value.clear();
  }
  
  emit('selection-change', Array.from(selectedRows.value));
};

// Handle pagination
const handlePageChange = (page) => {
  currentPage.value = page;
  emit('page-change', { page, pageSize: pageSize.value });
};

const handlePageSizeChange = (size) => {
  pageSize.value = size;
  currentPage.value = 1;
  emit('page-change', { page: 1, pageSize: size });
};

// Mobile responsive
const checkMobile = () => {
  isMobile.value = window.innerWidth < 768;
};

// Initialize
onMounted(() => {
  visibleColumns.value = props.columns.filter(col => !col.hidden);
  checkMobile();
  window.addEventListener('resize', checkMobile);
});

// Touch interactions for mobile
const { setupTouchInteractions } = useTouchInteractions();

// Utility functions
const formatFileSize = (bytes) => {
  if (!bytes || bytes === 0) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i];
};
</script>

<template>
  <div class="advanced-data-table h-full flex flex-col">
    <!-- Mobile Filters Toggle -->
    <div v-if="isMobile && filterable" class="mobile-filter-toggle mb-4 flex-shrink-0">
      <RsButton
        variant="secondary-outline"
        size="sm"
        @click="showMobileFilters = !showMobileFilters"
        class="w-full"
      >
        <Icon name="mdi:filter" class="w-4 h-4 mr-2" />
        {{ showMobileFilters ? 'Hide' : 'Show' }} Filters
      </RsButton>
    </div>

    <!-- Filters Row (Desktop) / Modal (Mobile) -->
    <div
      v-if="filterable && (!isMobile || showMobileFilters)"
      :class="[
        'filters-container mb-4 flex-shrink-0',
        isMobile ? 'mobile-filters' : 'desktop-filters'
      ]"
    >
      <div class="grid gap-4" :class="isMobile ? 'grid-cols-1' : 'grid-cols-2 md:grid-cols-3 lg:grid-cols-4'">
        <div
          v-for="column in visibleColumns.filter(col => col.filterable !== false)"
          :key="`filter-${column.key}`"
          class="filter-item"
        >
          <label class="block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1">
            {{ column.title }}
          </label>
          <input
            v-model="filters[column.key]"
            @input="handleFilter(column, $event.target.value)"
            type="text"
            :placeholder="`Filter ${column.title.toLowerCase()}...`"
            class="w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-md 
                   bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100
                   focus:ring-2 focus:ring-primary focus:border-transparent"
          />
        </div>
      </div>
    </div>

    <!-- Table Container - Scrollable -->
    <div class="table-container flex-1 overflow-auto min-h-0 border border-gray-200 dark:border-gray-600 rounded-lg">
      <!-- Loading State -->
      <LoadingStates
        v-if="loading"
        type="skeleton-table"
        :count="pageSize"
        class="p-4"
      />
      
      <!-- Table -->
      <table v-else :class="tableClasses" class="min-w-full">
        <!-- Header -->
        <thead class="bg-gray-50 dark:bg-gray-800 sticky top-0 z-10">
          <tr>
            <!-- Selection Column -->
            <th v-if="selectable" class="table-cell-checkbox">
              <input
                type="checkbox"
                :checked="selectedRows.size === processedData.length && processedData.length > 0"
                :indeterminate="selectedRows.size > 0 && selectedRows.size < processedData.length"
                @change="handleSelectAll($event.target.checked)"
                class="rounded border-gray-300 dark:border-gray-600"
              />
            </th>
            
            <!-- Data Columns -->
            <th
              v-for="column in visibleColumns"
              :key="`header-${column.key}`"
              :class="[
                'table-header-cell',
                column.sortable !== false && sortable ? 'cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-700' : '',
                column.align === 'center' ? 'text-center' : column.align === 'right' ? 'text-right' : 'text-left'
              ]"
              :style="{ width: column.width }"
              @click="handleSort(column)"
            >
              <div class="flex items-center space-x-2">
                <span>{{ column.title }}</span>
                <div v-if="column.sortable !== false && sortable" class="sort-indicators">
                  <Icon
                    name="mdi:chevron-up"
                    :class="[
                      'w-4 h-4 transition-colors',
                      sortConfig.key === column.key && sortConfig.direction === 'asc'
                        ? 'text-primary'
                        : 'text-gray-400'
                    ]"
                  />
                  <Icon
                    name="mdi:chevron-down"
                    :class="[
                      'w-4 h-4 transition-colors -mt-1',
                      sortConfig.key === column.key && sortConfig.direction === 'desc'
                        ? 'text-primary'
                        : 'text-gray-400'
                    ]"
                  />
                </div>
              </div>
            </th>
            
            <!-- Actions Column -->
            <th v-if="actions.length > 0" class="table-header-cell text-center">
              Actions
            </th>
          </tr>
        </thead>
        
        <!-- Body -->
        <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-600">
          <!-- Empty State -->
          <tr v-if="paginatedData.length === 0">
            <td :colspan="visibleColumns.length + (selectable ? 1 : 0) + (actions.length > 0 ? 1 : 0)" 
                class="table-cell-empty">
              <div class="flex flex-col items-center justify-center py-12">
                <Icon name="mdi:database-off" class="w-12 h-12 text-gray-400 mb-4" />
                <p class="text-gray-500 dark:text-gray-400">{{ emptyText }}</p>
              </div>
            </td>
          </tr>
          
          <!-- Data Rows -->
          <tr
            v-for="(row, index) in paginatedData"
            :key="`row-${row.id || index}`"
            :class="[
              'table-row hover:bg-gray-50 dark:hover:bg-gray-700/50 transition-colors cursor-pointer',
              selectedRows.has(row.id) ? 'bg-primary/5 dark:bg-primary/10' : ''
            ]"
            @click="emit('row-click', row)"
            @dblclick="emit('row-double-click', row)"
          >
            <!-- Selection Cell -->
            <td v-if="selectable" class="table-cell-checkbox">
              <input
                type="checkbox"
                :checked="selectedRows.has(row.id)"
                @change="handleRowSelection(row, $event.target.checked)"
                @click.stop
                class="rounded border-gray-300 dark:border-gray-600"
              />
            </td>
            
            <!-- Data Cells -->
            <td
              v-for="column in visibleColumns"
              :key="`cell-${row.id || index}-${column.key}`"
              :class="[
                'table-data-cell',
                column.align === 'center' ? 'text-center' : column.align === 'right' ? 'text-right' : 'text-left'
              ]"
            >
              <!-- Custom Slot -->
              <slot
                v-if="column.slot"
                :name="`column-${column.key}`"
                :row="row"
                :value="row[column.key]"
                :column="column"
              >
                {{ row[column.key] }}
              </slot>
              
              <!-- Default Cell Content -->
              <template v-else>
                <!-- Status Badge -->
                <span
                  v-if="column.type === 'status'"
                  :class="[
                    'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium',
                    row[column.key] === 'active' ? 'bg-green-100 text-green-800 dark:bg-green-900/20 dark:text-green-400' :
                    row[column.key] === 'inactive' ? 'bg-red-100 text-red-800 dark:bg-red-900/20 dark:text-red-400' :
                    'bg-gray-100 text-gray-800 dark:bg-gray-800 dark:text-gray-300'
                  ]"
                >
                  {{ row[column.key] }}
                </span>
                
                <!-- Date -->
                <span v-else-if="column.type === 'date'" class="text-gray-900 dark:text-gray-100">
                  {{ row[column.key] ? new Date(row[column.key]).toLocaleDateString() : '-' }}
                </span>
                
                <!-- File Size -->
                <span v-else-if="column.type === 'filesize'" class="text-gray-900 dark:text-gray-100">
                  {{ row[column.key] ? formatFileSize(row[column.key]) : '-' }}
                </span>
                
                <!-- Default Text -->
                <span v-else class="text-gray-900 dark:text-gray-100">
                  {{ row[column.key] || '-' }}
                </span>
              </template>
            </td>
            
            <!-- Actions Cell -->
            <td v-if="actions.length > 0" class="table-cell-actions">
              <div class="flex items-center justify-center space-x-2">
                <RsButton
                  v-for="action in actions"
                  :key="action.key"
                  :variant="action.variant || 'secondary-outline'"
                  size="sm"
                  @click.stop="emit('action-click', action.key, row)"
                  :title="action.title"
                >
                  <Icon :name="action.icon" class="w-4 h-4" />
                </RsButton>
              </div>
            </td>
          </tr>
        </tbody>
      </table>
    </div>

    <!-- Pagination -->
    <div
      v-if="pagination && processedData.length > 0"
      class="pagination-container mt-4 flex-shrink-0 flex flex-col sm:flex-row items-center justify-between space-y-4 sm:space-y-0"
    >
      <!-- Page Size Selector -->
      <div v-if="pagination.showSizeChanger" class="flex items-center space-x-2">
        <span class="text-sm text-gray-700 dark:text-gray-300">Show:</span>
        <select
          v-model="pageSize"
          @change="handlePageSizeChange($event.target.value)"
          class="px-3 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded-md 
                 bg-white dark:bg-gray-700 text-gray-900 dark:text-gray-100"
        >
          <option v-for="size in pagination.pageSizes" :key="size" :value="size">
            {{ size }}
          </option>
        </select>
        <span class="text-sm text-gray-700 dark:text-gray-300">entries</span>
      </div>

      <!-- Page Info -->
      <div class="text-sm text-gray-700 dark:text-gray-300">
        Showing {{ ((currentPage - 1) * pageSize) + 1 }} to 
        {{ Math.min(currentPage * pageSize, processedData.length) }} of 
        {{ processedData.length }} entries
      </div>

      <!-- Page Navigation -->
      <div class="flex items-center space-x-2">
        <RsButton
          variant="secondary-outline"
          size="sm"
          :disabled="currentPage === 1"
          @click="handlePageChange(currentPage - 1)"
        >
          <Icon name="mdi:chevron-left" class="w-4 h-4" />
        </RsButton>
        
        <div class="flex items-center space-x-1">
          <RsButton
            v-for="page in Math.min(Math.ceil(processedData.length / pageSize), 7)"
            :key="page"
            :variant="page === currentPage ? 'primary' : 'secondary-outline'"
            size="sm"
            @click="handlePageChange(page)"
            class="min-w-[2rem]"
          >
            {{ page }}
          </RsButton>
        </div>
        
        <RsButton
          variant="secondary-outline"
          size="sm"
          :disabled="currentPage >= Math.ceil(processedData.length / pageSize)"
          @click="handlePageChange(currentPage + 1)"
        >
          <Icon name="mdi:chevron-right" class="w-4 h-4" />
        </RsButton>
      </div>
    </div>
  </div>
</template>

<style scoped>
.advanced-data-table {
  @apply h-full min-h-0;
}

.table-header-cell {
  @apply px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider;
}

.table-data-cell {
  @apply px-6 py-4 whitespace-nowrap;
}

.table-cell-checkbox {
  @apply px-6 py-4 text-center;
}

.table-cell-actions {
  @apply px-6 py-4 text-center;
}

.table-cell-empty {
  @apply px-6 py-4 text-center;
}

.sort-indicators {
  @apply flex flex-col;
}

.mobile-filters {
  @apply p-4 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-600;
}

.desktop-filters {
  @apply p-4 bg-gray-50 dark:bg-gray-800 rounded-lg;
}

/* Responsive table */
@media (max-width: 768px) {
  .table-responsive {
    @apply text-xs;
  }
  
  .table-header-cell,
  .table-data-cell {
    @apply px-3 py-2;
  }
}

/* Enhanced scrollbar for table container */
.table-container::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

.table-container::-webkit-scrollbar-track {
  background: #f1f5f9;
  border-radius: 4px;
}

.table-container::-webkit-scrollbar-thumb {
  background: #cbd5e1;
  border-radius: 4px;
  border: 2px solid #f1f5f9;
}

.table-container::-webkit-scrollbar-thumb:hover {
  background: #94a3b8;
}

.table-container::-webkit-scrollbar-corner {
  background: #f1f5f9;
}

/* Dark mode scrollbar */
.dark .table-container::-webkit-scrollbar-track {
  background: #374151;
}

.dark .table-container::-webkit-scrollbar-thumb {
  background: #6b7280;
  border-color: #374151;
}

.dark .table-container::-webkit-scrollbar-thumb:hover {
  background: #9ca3af;
}

.dark .table-container::-webkit-scrollbar-corner {
  background: #374151;
}

/* Sticky header enhancement */
thead th {
  position: sticky;
  top: 0;
  background: inherit;
  backdrop-filter: blur(8px);
}
</style> 