<template>
  <div class="list-wrapper-container">
    <div class="list-wrapper-scrollbar-top" ref="scrollbarTopRef">
      <div class="scrollbar-content"></div>
    </div>
    <div class="list-wrapper" ref="listWrapperRef" @scroll="onScroll">
      <table class="table-border table-colored table-list">
      <thead>
        <tr>
          <th class="table-head-row-number" v-if="rowNumber">
            <div class="table-head-content">Sıra No</div>
          </th>
          <template v-for="(headCell, h) in tableHeader">
            <th :style="[headCell.style || '']">
              <div
                :class="[
                  'table-head-content',
                  headCell.sort !== undefined && headCell.sort ? 'clickable' : ''
                ]"
                @click="SortColumn(headCell)">
                <span>{{ headCell.title }}</span>
                <template
                  v-if="
                    headCell.sort !== undefined && headCell.sort && tableData.length > 1
                  ">
                  <i
                    class="ico-c ico-sort"
                    v-if="
                      localSort?.sortOrder === '' ||
                      headCell.name !== localSort?.sortColumn
                    ">
                    <svg>
                      <use href="@/assets/images/icons.svg#arrowsortable" />
                    </svg>
                  </i>
                  <i
                    :class="[
                      'ico-c',
                      'ico-sort',
                      localSort?.sortOrder === 'asc' ? 'order-asc' : ''
                    ]"
                    v-if="
                      headCell.name === localSort?.sortColumn &&
                      localSort?.sortOrder !== ''
                    ">
                    <svg>
                      <use href="@/assets/images/icons.svg#arrowline" />
                    </svg>
                  </i>
                </template>
              </div>
            </th>
          </template>
          <th
            :style="[rowActionStyle || '']"
            v-if="rowActions !== undefined && rowActions.length > 0">
            <div class="table-head-content">İşlemler</div>
          </th>
        </tr>
      </thead>
      <tbody>
        <tr v-if="tableData.length === 0 && !isPreview">
          <td :colspan="ColSpan">Veri bulunamadı</td>
        </tr>
        <tr
          v-else
          v-for="(dataRow, i) in tableData"
          @click="LocalRowAction(dataRow)"
          :class="[rowAction !== undefined && rowAction !== '' ? 'clickable' : '']">
          <td v-if="rowNumber">
            {{
              showPagination && localPagination.pageNumber !== undefined
                ? (Number(localPagination.pageNumber) - 1) *
                    Number(localPagination.pageSize) +
                  i +
                  1
                : i + 1
            }}
          </td>
          <slot :name="'dataRow' + i" :rowData="dataRow" :rowIndex="i">
            <template v-for="(dataCell, j) in tableHeader">
              <td v-if="dataCell.computeHtml === undefined">
                <slot
                  :name="'dataCell' + j"
                  :cellData="CellData(dataRow, dataCell.name)"
                  :cellIndex="j">
                  <div class="table-inner-content">
                    {{
                      dataCell.compute !== undefined
                        ? dataCell.compute(dataRow)
                        : dataRow[dataCell.name]
                    }}
                  </div>
                </slot>
              </td>
              <td v-else v-html="dataCell.computeHtml(dataRow)"></td>
            </template>
          </slot>
          <td
            v-if="rowActions !== undefined && rowActions.length > 0"
            :class="[actionFixed ? 'action-fixed' : '']">
            <template v-for="(action, ai) in rowActions">
              <button
                :class="[
                  'button-c button-icon button-export',
                  action.class !== undefined ? 'back-grad back-grad-' + action.class : ''
                ]"
                @click="LocalRowDataAction($event, action.action, dataRow, i)">
                <i class="ico-c" v-if="action.icon !== undefined">
                  <svg>
                    <use :href="icourl + '#' + action.icon"></use>
                  </svg>
                </i>
                <span class="panel-date">{{ action.text }}</span>
              </button>
            </template>
          </td>
        </tr>
        <template
          v-if="
            localTotalValues !== undefined &&
            Object.keys(localTotalValues).length > 0 &&
            tableData.length > 0
          ">
          <tr>
            <td :colspan="totalValuesSpanLength" class="table-cell-align-right">
              <strong>TOPLAM:</strong>
            </td>
            <template v-for="(val, i) in tableHeader">
              <td v-if="localTotalValues[val.name] !== undefined">
                {{
                  val.price
                    ? globalStore.toTrLocale(localTotalValues[val.name])
                    : localTotalValues[val.name]
                }}
              </td>
            </template>
          </tr>
        </template>
      </tbody>
    </table>
    </div>
  </div>
  <data-table-pagination
    v-if="pagination !== undefined && showPagination && !isPreview"
    v-model:pagination="localPagination"
    :isUseRoute="isUseRoute" />
</template>
<script setup lang="ts">
  import { ref, reactive, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
  import type { Ref } from 'vue'
  import { useGlobalStore } from '@/stores/globalStore'
  import icourl from '@/assets/images/icons.svg'
  const globalStore = useGlobalStore()
  import { useRouter, useRoute } from 'vue-router'
  const router = useRouter()
  const route = useRoute()

  interface ITableHead {
    [key: string]: any
    title: string
    name: string
    compute?: Function
    sort?: boolean
    computeHtml?: Function
  }
  interface IPagination {
    [key: string]: any
    pageNumber?: number
    pageSize: number
    totalRecords: number
  }
  interface ISort {
    [key: string]: any
    sortColumn?: string
    sortOrder?: string
  }
  export interface Props {
    tableHeader: ITableHead[]
    tableData: Record<string, any>[]
    rowAction?: Function | string
    pagination?: IPagination
    sortData?: ISort
    rowNumber?: boolean
    totalValues?: Record<string, any>
    isPreview?: boolean
    rowActions?: Record<string, any>[]
    actionFixed?: boolean
    rowActionStyle?: string
    isUseRoute?: boolean
  }
  const props = withDefaults(defineProps<Props>(), {
    tableData: () => [],
    rowNumber: false,
    isPreview: false,
    actionFixed: false,
    isUseRoute: false
  })

  const emit = defineEmits(['update:sortData', 'update:pagination'])

  const localSort: Ref<ISort> = ref(props.sortData as ISort)
  const localPagination: Ref<IPagination> = ref(props.pagination as IPagination)
  const localTotalValues = reactive<Record<string, any>>(
    props.totalValues as Record<string, any>
  )

  const totalValuesSpanLength = ref<number>(0)

  if (localTotalValues !== undefined) {
    let totalValuesLength = Object.keys(localTotalValues).length
    let headerLength: number =
      props.rowNumber !== undefined
        ? props.tableHeader.length + 1
        : props.tableHeader.length
    totalValuesSpanLength.value = headerLength - totalValuesLength
  }

  const showPagination = computed<boolean>(() => {
    if (props.pagination !== undefined) {
      if (Math.ceil(localPagination.value.totalRecords / globalStore.perPage) > 1)
        return true
      else return false
    } else {
      return false
    }
  })

  const ColSpan = computed<number>(() => {
    var span = props.tableHeader.length
    if (props.rowNumber) span++
    if (props.rowActions) span++
    return span
  })
  const LocalRowAction = (d: Record<string, any>) => {
    if (props.rowAction !== undefined) {
      ;(props.rowAction! as Function)(d)
    }
  }

  const LocalRowDataAction = (
    e: Event,
    action: Function | undefined,
    dataRow: Record<string, any>,
    i: number | string
  ) => {
    if (action !== undefined) {
      e.stopImmediatePropagation()
      action(dataRow, i)
    }
  }

  const SortColumn = (d: Record<string, any>) => {
    if (d.sort && props.tableData.length > 1) {
      let order = ''
      if (localSort.value.sortColumn === d.name) {
        if (localSort.value.sortOrder === '') order = 'desc'
        if (localSort.value.sortOrder === 'desc') order = 'asc'
        if (localSort.value.sortOrder === 'asc') {
          order = ''
          delete localSort.value.sortColumn
        }
        localSort.value.sortOrder = order
      } else {
        localSort.value.sortColumn = d.name
        localSort.value.sortOrder = 'desc'
      }
      if (props.isUseRoute) {
        router.push({
          query: {
            ...route.query,
            sortColumn: localSort.value.sortColumn,
            sortOrder: localSort.value.sortOrder
          }
        })
      }
      emit('update:sortData', localSort.value)
    }
  }
  
  const CellData = (d: Record<string, any>, key: string): any => {
    if (d[key] === null) return d
    else return d[key]
  }

  watch(
    () => localPagination,
    () => {
      emit('update:pagination', localPagination.value)
    },
    { deep: true }
  )

  watch(
    () => props.tableData,
    () => {
      // Tablo verisi değiştiğinde scrollbar'ı güncelle
      setTimeout(() => {
        syncScrollbars()
      }, 100)
    },
    { deep: true }
  )

  const listWrapperRef = ref<HTMLElement | null>(null)
  const scrollbarTopRef = ref<HTMLElement | null>(null)

  const onScroll = (e: Event) => {
    const target = e.target as HTMLElement
    if (scrollbarTopRef.value) {
      scrollbarTopRef.value.scrollLeft = target.scrollLeft
    }
  }

  const syncScrollbars = () => {
    if (listWrapperRef.value && scrollbarTopRef.value) {
      const table = listWrapperRef.value.querySelector('table')
      if (table) {
        const tableWidth = table.scrollWidth
        const wrapperWidth = listWrapperRef.value.clientWidth
        
        if (tableWidth > wrapperWidth) {
          scrollbarTopRef.value.style.display = 'block'
          scrollbarTopRef.value.scrollLeft = listWrapperRef.value.scrollLeft
          // Scrollbar wrapper'ın içeriğinin genişliğini tablo genişliğine eşitle
          const scrollbarContent = scrollbarTopRef.value.querySelector('.scrollbar-content') as HTMLElement | null
          if (scrollbarContent) {
            scrollbarContent.style.width = tableWidth + 'px'
            scrollbarContent.style.height = '1px'
          }
        } else {
          scrollbarTopRef.value.style.display = 'none'
        }
      }
    }
  }

  const onTopScroll = (e: Event) => {
    const target = e.target as HTMLElement
    if (listWrapperRef.value) {
      listWrapperRef.value.scrollLeft = target.scrollLeft
    }
  }

  onMounted(async () => {
    await nextTick()
    
    if (scrollbarTopRef.value) {
      scrollbarTopRef.value.addEventListener('scroll', onTopScroll)
    }
    
    // İlk scrollbar senkronizasyonu
    setTimeout(() => {
      syncScrollbars()
    }, 100)
    
    const resizeObserver = new ResizeObserver(() => {
      syncScrollbars()
    })
    
    if (listWrapperRef.value) {
      resizeObserver.observe(listWrapperRef.value)
    }
    
    const tableObserver = new MutationObserver(() => {
      syncScrollbars()
    })
    
    if (listWrapperRef.value) {
      const table = listWrapperRef.value.querySelector('table')
      if (table) {
        tableObserver.observe(table, { childList: true, subtree: true, attributes: true })
      }
    }
  })

  onUnmounted(() => {
    if (scrollbarTopRef.value) {
      scrollbarTopRef.value.removeEventListener('scroll', onTopScroll)
    }
  })
</script>
<style scoped>
  .action-fixed {
    position: absolute;
    z-index: 9;
    top: 0;
    right: 0;
  }
  .table-inner-content {
    max-height: 400px;
    overflow: hidden;
    text-overflow: ellipsis;
    -webkit-line-clamp: 20;
    line-clamp: 20;
    -webkit-box-orient: vertical;
    display: -webkit-box;
  }
</style>
