<template>
  <div id="tableContainer">
    <table :id="tableId" class="display">
      <thead>
        <tr>
          <th v-for="(header, i) in computedHeaders" :key="i">{{ header }}</th>
        </tr>
      </thead>
      <tbody>
        <tr
          v-for="(row, rowIdx) in filteredData"
          :key="rowIdx"
          @click="$emit('row-click', row, rowIdx)"
          class="searchable-row"
        >
          <td v-for="(header, colIdx) in computedHeaders" :key="colIdx">
            {{ isObjectData ? (row[header] ?? '') : (row[colIdx] ?? '') }}
          </td>
        </tr>
      </tbody>
    </table>

    <!-- Simple pagination -->
    <div v-if="totalPages > 1" class="table-pagination mt-3 d-flex justify-content-between align-items-center">
      <button class="btn btn-sm btn-default" :disabled="currentPage <= 1" @click="currentPage--">
        Previous
      </button>
      <span>Page {{ currentPage }} of {{ totalPages }}</span>
      <button class="btn btn-sm btn-default" :disabled="currentPage >= totalPages" @click="currentPage++">
        Next
      </button>
    </div>
  </div>
</template>

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

const props = defineProps({
  /**
   * Array of objects or array of arrays
   */
  data:         { type: Array, required: true },
  headers:      { type: Array, default: () => [] },
  tableId:      { type: String, default: 'dynamicTable' },
  pageLength:   { type: Number, default: 10 },
  defaultSort:  { type: Object, default: () => ({ column: 0, direction: 'asc' }) },
  defaultSearch: { type: String, default: '' },
})

defineEmits(['row-click'])

const currentPage = ref(1)
const searchTerm  = ref(props.defaultSearch)

const isObjectData = computed(() =>
  props.data.length > 0 &&
  props.data[0] !== null &&
  typeof props.data[0] === 'object' &&
  !Array.isArray(props.data[0])
)

const computedHeaders = computed(() => {
  if (props.headers.length > 0) return props.headers
  if (isObjectData.value) return Object.keys(props.data[0])
  return []
})

const sortedData = computed(() => {
  const dataCopy = [...props.data]
  const { column, direction } = props.defaultSort

  dataCopy.sort((a, b) => {
    const valA = isObjectData.value ? a[computedHeaders.value[column]] : a[column]
    const valB = isObjectData.value ? b[computedHeaders.value[column]] : b[column]

    if (valA < valB) return direction === 'asc' ? -1 : 1
    if (valA > valB) return direction === 'asc' ? 1 : -1
    return 0
  })

  return dataCopy
})

const filteredData = computed(() => {
  let result = sortedData.value

  if (searchTerm.value) {
    const q = searchTerm.value.toLowerCase()
    result = result.filter(row => {
      const text = isObjectData.value
        ? Object.values(row).join(' ')
        : row.join(' ')
      return text.toLowerCase().includes(q)
    })
  }

  // Pagination
  const start = (currentPage.value - 1) * props.pageLength
  return result.slice(start, start + props.pageLength)
})

const totalPages = computed(() => {
  const total = sortedData.value.length
  return Math.max(1, Math.ceil(total / props.pageLength))
})
</script>

<style scoped>
.searchable-row {
  cursor: pointer;
}
.searchable-row:hover {
  background-color: rgba(0, 0, 0, 0.05);
}
</style>
