<template>
  <div :style="cssVars">
    <div
      slot="table-actions"
      v-if="tableActions"
      class="mb-4 rounded-lg bg-gray-50 p-3"
    >
      <div class="flex items-center justify-between">
        <slot name="customTableFilterActions"></slot>
        <div v-if="searching" class="flex items-center">
          <c-input
            v-model="searchTerm"
            :isValidate="searching"
            :placeholder="searchPlaceholder"
            class="mr-3"
            :class="searchInputClass"
            :inputWrapperClass="inputWrapperClass"
            type="text"
            :id="id + '_input_search'"
          ></c-input>
          <slot name="tableInfo"></slot>
        </div>
        <div class="flex flex-1 justify-end">
          <!-- dropdown icon on top right of table -->
          <slot name="customTableActions"></slot>
          <div
            :class="`relative inline-block text-left ${
              disableColumnsDropdown ? 'pointer-events-none opacity-50' : ''
            }`"
            v-if="enableVisibility"
          >
            <!-- button to show list of columns to show  hide in table -->
            <div v-if="showNewShowHideColumnButton" class="relative">
              <c-tool-tip
                v-if="showShowHideColumnTooltip"
                color="#1f2937"
                classes="text-white absolute -mt-12 whitespace-nowrap top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 font-normal  bg-gray-800 w-auto"
                :isTopAligned="true"
                :tooltip-text="'Column Visibility, Download'"
              ></c-tool-tip>
              <button
                @mouseover="handleToolTipDisplay(true, 'showHideColumn')"
                @mouseleave="handleToolTipDisplay(false, 'showHideColumn')"
                @click="handleToggle"
                class="inline-flex h-9 items-center justify-center rounded-md border border-gray-300 bg-white px-2 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2"
                aria-haspopup="true"
                aria-expanded="true"
              >
                <c-icon
                  name="dots-vertical-solid-v2"
                  type="solid"
                  cursorType="cursor-pointer"
                  class="h-5 w-5 text-gray-400"
                  viewBox="0 0 24 24"
                ></c-icon>
              </button>
            </div>
            <div v-else class="relative">
              <c-tool-tip
                v-if="showShowHideColumnTooltip"
                color="#1f2937"
                classes="text-white absolute -mt-12 whitespace-nowrap top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 font-normal  bg-gray-800 w-auto"
                :isTopAligned="true"
                :tooltip-text="'Column Visibility'"
              ></c-tool-tip>
              <button
                @mouseover="handleToolTipDisplay(true, 'showHideColumn')"
                @mouseleave="handleToolTipDisplay(false, 'showHideColumn')"
                @click="handleToggle"
                class="inline-flex h-9 items-center justify-center rounded-md border border-gray-300 bg-white px-2 py-2 text-sm font-medium text-gray-700 shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2"
                aria-haspopup="true"
                aria-expanded="true"
              >
                <c-icon
                  name="view-board"
                  type="solid"
                  cursorType="cursor-pointer"
                  class="h-5 w-5 text-gray-400"
                ></c-icon>
                <c-icon
                  name="chevron-down"
                  type="solid"
                  cursorType="cursor-pointer"
                  class="ml-1 h-5 w-5 text-gray-400"
                ></c-icon>
              </button>
            </div>
            <!-- dropdown having list of all columns to show hide -->
            <div
              v-if="toggleDropdown"
              @click="handleToggle"
              class="fixed inset-0 z-20"
            ></div>
            <div
              v-if="toggleDropdown"
              class="absolute right-0 z-30 mt-2 -mr-1 max-h-96 w-56 origin-top-right overflow-y-auto rounded-md bg-white shadow-lg ring-1 ring-gray-900 ring-opacity-5"
              tabindex="0"
            >
              <div
                class="pt-1"
                role="menu"
                aria-orientation="vertical"
                aria-labelledby="option-menu"
              >
                <div
                  v-for="(column, index) in showHideColumnList"
                  :key="index"
                  :class="[
                    column.isActionColumn && showNewShowHideColumnButton
                      ? column.customClasses +
                        ' sticky bottom-0 z-10 w-full bg-white'
                      : '',
                  ]"
                >
                  <div
                    v-if="column.isRowHeaderCol && showNewShowHideColumnButton"
                    class="block px-3 py-2 text-sm font-medium text-gray-900"
                  >
                    {{ column.label }}
                  </div>
                  <div
                    v-else-if="
                      column.isActionColumn && showNewShowHideColumnButton
                    "
                    class="block px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
                    @click="$emit('actionColumnClick', column)"
                  >
                    <c-icon
                      v-if="column.showActionIcon"
                      :name="column.icon.name"
                      :type="column.icon.type"
                      :class="column.icon.class"
                      :viewBox="column.icon.viewBox"
                    ></c-icon>
                    <span>{{ column.label }}</span>
                  </div>
                  <a
                    v-else
                    href="#"
                    role="menuitem"
                    class="block px-3 py-2 text-sm text-gray-700 hover:bg-gray-100 hover:text-gray-900"
                  >
                    <c-checkbox
                      :label="column.label"
                      @onChange="showHideColumn($event, column.field)"
                      :value="!column.hidden"
                    ></c-checkbox>
                  </a>
                </div>
              </div>
            </div>
          </div>
          <slot name="customDatePicker"></slot>

          <!-- simple download button -->
          <div
            v-if="enableDownload && !downloadDropdown"
            @click="startDownload"
            class="relative"
            :id="id + '_button_download'"
          >
            <c-tool-tip
              v-if="showDownloadTooltip"
              color="#1f2937"
              classes="text-white absolute -mt-12 ml-1.5 whitespace-nowrap top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 font-normal  bg-gray-800 w-auto"
              :isTopAligned="true"
              :tooltip-text="'Download'"
            ></c-tool-tip>
            <c-button-icon
              @mouseover.native="handleToolTipDisplay(true, 'download')"
              @mouseleave.native="handleToolTipDisplay(false, 'download')"
              type="white"
              :icon="
                downloadLoader
                  ? null
                  : {
                      name: 'arrow-down-tray-solid-v2',
                      type: 'solid',
                      class: 'h-5 w-5  text-gray-400',
                      viewBox: '0 0 24 24',
                    }
              "
              class="ml-3"
              loaderClasses="ml-2"
              :isLoading="downloadLoader"
              :disabled="disableDownloadButton"
            ></c-button-icon>
          </div>
          <!-- no download buttons -->
          <div v-if="!enableDownload && !downloadDropdown"></div>
          <!-- download button with download options -->
          <div v-if="enableDownload && downloadDropdown" class="relative ml-3">
            <div>
              <button
                @click="handleDownloadToggle"
                class="inline-flex w-full justify-center rounded-md border border-gray-200 bg-white px-2 py-2 text-sm font-medium shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2"
                aria-haspopup="true"
                aria-expanded="true"
                :id="id + '_button_toggle_download'"
              >
                <c-icon
                  v-if="downloadOptionLoader"
                  cursorType="cursor-pointer"
                  class="mr-2 h-5 w-5 text-gray-400"
                  name="loader"
                ></c-icon>
                <c-icon
                  v-else
                  name="download-solid"
                  type="solid"
                  class="h-5 w-5 text-gray-400"
                  cursorType="cursor-pointer"
                ></c-icon>
                <c-icon
                  name="chevron-down"
                  type="solid"
                  class="ml-1 h-5 w-5 text-gray-400"
                  cursorType="cursor-pointer"
                ></c-icon>
              </button>
            </div>
            <!-- download options dropdown -->
            <div
              v-if="toggleDownloadDropdown"
              @click="handleDownloadToggle"
              class="fixed inset-0 z-20"
            ></div>
            <div
              v-if="toggleDownloadDropdown"
              class="absolute right-0 z-30 mt-2 -mr-1 max-h-96 w-64 origin-top-right overflow-y-auto rounded-md bg-white shadow-lg ring-1 ring-gray-900 ring-opacity-5"
              tabindex="0"
            >
              <div
                class="py-1"
                role="menu"
                aria-orientation="vertical"
                aria-labelledby="option-menu"
              >
                <div
                  v-for="(item, index) in showDownloadDropdownList"
                  :key="index"
                  class="cursor-pointer px-3 py-2 text-sm text-gray-900 hover:bg-gray-100 hover:text-gray-900"
                  role="menuitem"
                  @click="downloadFromOption(item.value)"
                  :id="getActionIDFn(item.title)"
                >
                  <p>{{ item.title }}</p>
                  <p class="text-sm text-gray-400">{{ item.description }}</p>
                </div>
              </div>
            </div>
          </div>
          <slot name="customTableExtraActions"></slot>
        </div>
      </div>
    </div>

    <vue-good-table
      :class="`rounded-lg ${
        hideBorder ? ' border-none' : 'border-2 border-solid border-gray-100'
      }`"
      mode="remote"
      ref="my-table"
      :styleClass="
        isLoading ? 'vgt-table opacity-50 pointer-events-none' : 'vgt-table'
      "
      :row-style-class="rowStyleClassFn"
      min-height="400px"
      :globalSearch="true"
      :totalRows="totalRecords"
      :columns="colsWithHeaderClasses"
      :rows="rows"
      :search-options="{
        enabled: searching,
        externalQuery: searchTerm,
        placeholder: searchPlaceholder,
        trigger: 'enter',
      }"
      :select-options="{
        enabled: enableSelection,
        selectOnCheckboxOnly: selectOnCheckBoxClickOnly, // only select when checkbox is clicked instead of the row
        selectionInfoClass: 'custom-class',
        selectionText: 'rows selected',
        clearSelectionText: 'clear',
        disableSelectInfo: true, // disable the select info panel on top
        selectAllByGroup: true, // when used in combination with a grouped table, add a checkbox in the header row to check/uncheck the entire group
      }"
      :sort-options="{
        enabled: sorting,
        initialSortBy: initialSortField,
      }"
      :pagination-options="{ enabled: pagination }"
      :fixed-header="fixedHeader"
      :group-options="{
        enabled: enableGrouping,
        collapsable: enableGrouping,
        maintainExpanded: enableGrouping,
      }"
      :id="id"
      @on-selected-rows-change="selectionChanged"
      @on-sort-change="sortChange"
      @on-search="onSearching"
      @on-row-click="onRowClick"
      @on-row-mouseenter="onRowMouseover"
      @on-row-mouseleave="onRowMouseleave"
    >
      <template slot="table-column" slot-scope="props">
        <span :id="`${id}_header_${props.column.field}`">
          <!-- custom sorting icon -->
          <span v-if="props.column.sortable || sorting" class="flex">
            <div>
              {{ props.column.label }}
            </div>
            <!-- render if there is no sorting order, appears on hover -->
            <c-icon
              v-if="props.column.direction == null"
              name="sort-ascending-solid"
              class="sortingIcon invisible ml-3 h-5 w-5"
              type="solid"
            ></c-icon>
            <!-- renders when direction is asc -->
            <c-icon
              v-else-if="props.column.direction == 'asc'"
              name="sort-ascending-solid"
              class="ml-3 h-5 w-5"
              type="solid"
            ></c-icon>
            <!-- renders when direction is desc -->
            <c-icon
              v-else-if="props.column.direction == 'desc'"
              name="sort-descending-solid"
              class="ml-3 h-5 w-5"
              type="solid"
            ></c-icon>
          </span>
          <span class="font-medium text-gray-500" v-else-if="fontHeader">
            {{ props.column.label }}
          </span>
          <span v-else-if="props.column.hasIcon" class="flex">
            {{ props.column.label }}
            <c-icon
              name="information-circle"
              type="solid"
              class="mr-2 h-5 w-5 shrink-0 text-gray-400 hover:text-gray-500"
              cursorType="cursor-pointer"
              @mouseover.native="props.column.showToolTipText = true"
              @mouseleave.native="props.column.showToolTipText = false"
            ></c-icon>

            <div
              :class="['absolute', `${props.column.toolTipBoxClass}`]"
              v-if="props.column.showToolTipText"
            >
              <c-tool-tip
                color="#1f2937"
                classes="text-white whitespace-nowrap font-normal sticky bg-gray-800 w-auto"
                :tooltip-text="props.column.tooltipText"
              ></c-tool-tip>
            </div>
          </span>
          <span v-else> {{ props.column.label }}</span>
        </span>
      </template>
      <div slot="emptystate">
        <template v-if="isLoading">
          <div class="flex flex-col gap-3 py-[1.5px]">
            <div class="flex flex-col gap-3" v-for="idx in 10" :key="idx">
              <div class="flex w-full items-center justify-between gap-2">
                <div class="flex items-center gap-2" v-if="addAvatarLoader">
                  <vue-skeleton-loader
                    type="table-tbody: table-row-divider@6"
                    animation="fade"
                    :width="32"
                    :rounded="true"
                    :height="32"
                    :radius="200"
                  ></vue-skeleton-loader>
                  <vue-skeleton-loader
                    type="table-tbody: table-row-divider@6"
                    animation="fade"
                    :width="100"
                    :rounded="true"
                    :height="32"
                  ></vue-skeleton-loader>
                </div>
                <vue-skeleton-loader
                  type="table-tbody: table-row-divider@6"
                  animation="fade"
                  class="!w-full"
                  :rounded="true"
                  :height="32"
                ></vue-skeleton-loader>
              </div>
            </div>
          </div>
        </template>
        <template v-else>
          <p class="vgt-center-align vgt-text-disabled">
            {{ emptyStatePlaceholderText }}
          </p>
        </template>
      </div>
      <template slot="table-row" slot-scope="props">
        <!-- renders if drag and drop is present in table -->
        <span v-if="props.column.field == 'drag'">
          <c-icon
            name="draggable"
            type="solid"
            :class="`handle h-5 w-5 ${
              props.row.status && props.row.status === 2
                ? 'pointer-events-none cursor-default opacity-50'
                : 'text-gray-500'
            }`"
            :cursorType="'cursor-grab'"
          ></c-icon>
        </span>
        <!-- if customization or adding another form element is required -->
        <span v-else-if="props.column.customizeColumn">
          <slot
            :records="props"
            :isHovered="enableRowHover && isRowHovered(props)"
          >
          </slot>
        </span>
        <span v-else-if="props.column.field === '__hoverText'">
          <span
            v-if="isRowHovered(props)"
            class="text-sm text-gray-500 whitespace-nowrap"
          >
            {{ rowHoverText }}
          </span>
        </span>
        <!-- renders records as per column name -->
        <span v-else>
          {{ props.formattedRow[props.column.field] }}
        </span>
      </template>
      <!-- Custom pagination component -->
      <template v-if="pagination" slot="pagination-bottom">
        <c-pagination
          v-if="paginationRecords.totalRecords > 0"
          :setPaginationRecords="paginationRecords"
          :totalRecordsOnPage="recordsToDisplay"
          :showEntryPicker="showEntryPicker"
          :id="id"
          @setCurrentPage="setCurrentPageRecords"
          @setPreviousPage="setPreviousPageRecords"
          @setNextPage="setNextPageRecords"
          @handle-Row-Count-Change="handleChangeRowCount"
        ></c-pagination>
      </template>
    </vue-good-table>

    <!-- Floating Action Bar -->
    <transition name="floating-action-bar">
      <div
        v-if="shouldShowFloatingActionBar"
        ref="floatingActionBar"
        :style="floatingActionBarStyle"
        class="fixed bottom-8 left-1/2 z-10 -translate-x-1/2"
      >
        <div
          class="flex shrink-0 items-center justify-center rounded-xl bg-gray-900 p-3 shadow-lg"
          :style="floatingActionBarGapStyle"
        >
          <!-- Close button and selection count -->
          <div class="flex items-center gap-1">
            <c-button-icon
              :id="id + '_button_close_action_bar'"
              type="dark-blue"
              :icon="{
                name: 'x-mark-solid-v2',
                type: 'solid',
                class: 'h-5 w-5 text-gray-300 group-hover:text-white',
                viewBox: '0 0 24 24',
              }"
              title="Close selection"
              aria-label="Close selection"
              customButtonClasses="group"
              @action="handleClearSelectedRows"
            ></c-button-icon>
            <slot name="floatingActionBarActionsInfo"></slot>
          </div>

          <!-- Custom action buttons slot -->
          <div class="flex items-center gap-1">
            <slot
              name="floatingActionBarActions"
              :clearSelection="handleClearSelectedRows"
            ></slot>
          </div>
        </div>
      </div>
    </transition>
  </div>
</template>
<script>
import CIcon from "../CIcon/CIcon.vue";
import CCheckbox from "../CCheckbox/CCheckbox.vue";
import CPagination from "../CPagination/CPagination.vue";
import CButtonIcon from "../CButtonIcon/CButtonIcon.vue";
import CToolTip from "../CToolTip/CToolTip.vue";
import "vue-good-table/dist/vue-good-table.css";
import { VueGoodTable } from "vue-good-table";
import Sortable from "@shopify/draggable/lib/es5/sortable.js";
import CInput from "../CInput/CInput.vue";
import { debounce, isEqual } from "lodash-es";
import VueSkeletonLoader from "skeleton-loader-vue";
import { getActionID } from "../../helper";

const RESIZE_DEBOUNCE_DELAY = 150;

export default {
  name: "CTable",
  components: {
    CCheckbox,
    CIcon,
    VueGoodTable,
    CPagination,
    CButtonIcon,
    CInput,
    VueSkeletonLoader,
    CToolTip,
  },
  props: {
    fontHeader: {
      type: Boolean,
      default: false,
    },
    // To show or hide pagination section
    pagination: {
      type: Boolean,
    },
    // To enable or disable sorting
    sorting: {
      type: Boolean,
    },
    // To show or hide search input
    searching: {
      type: Boolean,
    },
    // To add checkbox to select rows
    enableSelection: {
      type: Boolean,
    },
    enableVisibility: {
      type: Boolean,
      default: true,
    },
    disableColumnsDropdown: {
      type: Boolean,
      default: false,
    },
    enableDownload: {
      type: Boolean,
      default: true,
    },
    // All the buttons displayed on top right side of table
    tableActions: {
      type: Boolean,
    },
    // Placeholder text for search
    searchPlaceholder: {
      type: String,
    },
    // Existing text for search
    searchQuery: {
      type: String,
    },
    isLoading: {
      type: Boolean,
    },
    // ID
    totalRecords: {
      type: String,
    },
    // Total number of rows in a table to calculate page numbers
    id: {
      type: String,
    },
    // Shows current selected page and records on per page
    paginationData: {
      type: Object,
    },
    // Pass a column  on which initial sorting will be applied
    initialSortField: {
      type: Object,
    },
    // all columns of the table
    cols: {
      type: Array,
      required: true,
    },
    // row records of the table
    rows: {
      type: Array,
      required: true,
    },
    // List of columns to show hide
    showHideColumnList: {
      type: Array,
    },
    // List of items to show download options
    showDownloadDropdownList: {
      type: Array,
    },
    // Function on changing page number
    onPageChange: {
      type: Function,
    },
    // Function on changing sorting on column
    onSortChange: {
      type: Function,
    },
    // Function to fetch results on search query
    onSearch: {
      type: Function,
    },
    // Emit action on clicking the row
    onRowClickAction: {
      type: Function,
    },
    // Start the loader
    downloadLoader: {
      type: Boolean,
    },
    // Start the loader
    downloadOptionLoader: {
      type: Boolean,
    },
    downloadDropdown: {
      type: Boolean,
    },
    rowStyleClassFn: {
      type: Function,
      default: () => "",
    },
    fixedHeader: {
      type: Boolean,
      default: false,
    },
    hideBorder: {
      type: Boolean,
      default: false,
    },
    showEntryPicker: {
      type: Boolean,
      default: false,
    },
    enableGrouping: {
      type: Boolean,
      default: false,
    },
    //enables user to select rows by clicking on the row
    selectOnCheckBoxClickOnly: {
      type: Boolean,
      default: true,
    },
    //shows new show hide column button
    showNewShowHideColumnButton: {
      type: Boolean,
      default: false,
    },
    disableDownloadButton: {
      type: Boolean,
      default: false,
    },
    searchInputClass: {
      type: String,
      default: "w-auto sm:w-56",
    },
    showTableActionsTooltip: {
      type: Boolean,
      default: false,
    },
    emptyStatePlaceholderText: {
      type: String,
      default: "No data for table",
    },
    inputWrapperClass: {
      type: String,
      default: "",
    },
    addAvatarLoader: {
      type: Boolean,
      default: false,
    },
    // Enable row hover effects (color change and hover text)
    enableRowHover: {
      type: Boolean,
      default: false,
    },
    // Text to show at the end of row on hover
    rowHoverText: {
      type: String,
      default: "",
    },
    showFloatingActionBar: {
      type: Boolean,
      default: false,
    },
    // Selector for the container element used for floating action bar positioning
    // Defaults to '.content-container > div' for backward compatibility which is the main layout of the page
    containerSelector: {
      type: String,
      default: ".content-container > div",
    },
  },
  computed: {
    cssVars() {
      return {
        "--vgt-bottom-radius": this.pagination ? "0" : "8px",
      };
    },
    colsWithHeaderClasses() {
      const cols = this.cols.map((col) => ({
        ...col,
        thClass: `${this.id}_header_${col.field}`,
      }));

      // Add hover text column at the end if enabled
      if (this.enableRowHover && this.rowHoverText) {
        cols.push({
          label: "",
          field: "__hoverText",
          hidden: false,
          sortable: false,
          thClass: `${this.id}_header___hoverText`,
          tdClass: "hover-text-column",
        });
      }

      return cols;
    },
    shouldShowFloatingActionBar() {
      return this.showFloatingActionBar && this.enableSelection;
    },
    floatingActionBarGapStyle() {
      if (!this.shouldShowFloatingActionBar) return {};

      /*
        Responsive gap using clamp(min, preferred, max)
        - Minimum: 12px  → gap will never go below 12px
        - Preferred: 4vw → scales fluidly with viewport width i.e., 4% of viewport width
        - Maximum: 80px → gap will never exceed 80px
      */
      return {
        gap: "clamp(12px, 4vw, 80px)",
      };
    },
  },
  mounted() {
    //  to add drag and drop in table
    this.reorderedArray = this.rows;
    let sortable = new Sortable(document.querySelectorAll("tbody"), {
      draggable: "tr",
      handle: ".handle",
      classes: {
        mirror: ["bg-white"],
      },
      mirror: {
        constrainDimensions: true,
      },
    });
    sortable.on("sortable:stop", (e) => this.rearrange(e.oldIndex, e.newIndex));
    document.addEventListener("keydown", this.handleControlClick, true);
    document.addEventListener("keyup", this.handleControlRelease, true);

    // Setup floating action bar positioning
    if (this.shouldShowFloatingActionBar) {
      this.$nextTick(() => {
        this.updateFloatingActionBarPosition();
        this.setupResizeObserver();
      })
    }
  },
  destroyed() {
    //to remove the event listener
    document.removeEventListener("keydown", this.handleControlClick, true);
    document.removeEventListener("keyup", this.handleControlRelease, true);

    this.cleanupResizeObserver();
  },
  data() {
    return {
      toggleDropdown: false,
      toggleDownloadDropdown: false,
      searchTerm: this.searchQuery ? this.searchQuery : "",
      paginationRecords: this.paginationData,
      reorderedArray: [],
      controlClick: false,
      attrs: {
        boilerplate: true,
        elevation: 2,
      },
      recordsToDisplay: {
        option: 10,
        value: 10,
      },
      showShowHideColumnTooltip: false,
      showDownloadTooltip: false,
      hoveredRowId: null,
      floatingActionBarStyle: {},
    };
  },
  methods: {
    getActionIDFn(name) {
      return getActionID(name, this.id);
    },
    handleChangeRowCount(value) {
      this.recordsToDisplay = value;
      this.$emit("change-row-count", value.value);
    },
    handleToolTipDisplay(value, type) {
      if (!this.showTableActionsTooltip) {
        return;
      }
      if (type === "showHideColumn") {
        this.showShowHideColumnTooltip = value;
      } else if (type === "download") {
        this.showDownloadTooltip = value;
      }
    },
    handleControlClick(event) {
      if (event.keyCode === 17 || event.keyCode === 91) {
        event.preventDefault();
        this.controlClick = true;
      }
    },
    handleControlRelease(event) {
      if (event.keyCode === 17 || event.keyCode === 91) {
        event.preventDefault();
        this.controlClick = false;
      }
    },
    handleToggle() {
      this.toggleDropdown = !this.toggleDropdown;
    },
    handleDownloadToggle() {
      this.toggleDownloadDropdown = !this.toggleDownloadDropdown;
    },
    showHideColumn(value, name) {
      this.$emit("hideCols", value, name);
    },
    handleClearSelectedRows() {
      if (this.$refs["my-table"]) {
        this.$refs["my-table"].unselectAllInternal();
      }
      this.$emit("closeSelection");
    },
    // Function to get selected rows on checking the checkbox
    selectionChanged() {
      this.$emit(
        "selectRows",
        this.$refs["my-table"].selectedRows,
        this.$refs["my-table"].allSelected
      );
    },
    // array of rows after drag and drop
    rearrange(oldIndex, newIndex) {
      const movedItem = this.reorderedArray.find(
        (item, index) => index === oldIndex
      );
      const remainingItems = this.reorderedArray.filter(
        (item, index) => index !== oldIndex
      );
      const reorderedItems = [
        ...remainingItems.slice(0, newIndex),
        movedItem,
        ...remainingItems.slice(newIndex),
      ];
      this.reorderedArray = [...reorderedItems];
      this.$emit(
        "reordered",
        this.reorderedArray,
        movedItem,
        oldIndex,
        newIndex
      );
    },
    // listing functions
    sortChange(params) {
      if (params[0].type == "none") {
        params[0].type = "asc";
      }
      this.$emit("onSortChange", params);
    },
    onSearching: debounce(function (params) {
      this.$emit("onSearch", params);
    }, 500),
    setCurrentPageRecords(page) {
      this.paginationRecords.currentPage = page;
      this.$emit("pageChange", page);
    },
    setPreviousPageRecords(page) {
      this.paginationRecords.currentPage = page;
      this.$emit("pageChange", page);
    },
    setNextPageRecords(page) {
      this.paginationRecords.currentPage = page;
      this.$emit("pageChange", page);
    },
    onRowClick(params) {
      if (!this.selectOnCheckBoxClickOnly) {
        return;
      }
      if (params.event.target.type === undefined) {
        if (this.controlClick) {
          this.$emit("onRowControlClickAction", params);
        } else {
          this.$emit("onRowClickAction", params);
        }
      } else {
        return false;
      }
    },
    startDownload() {
      this.$emit("handleDownloadButton");
    },
    downloadFromOption(value) {
      this.toggleDownloadDropdown = false;
      this.$emit("handleDownloadOptionButton", value);
    },

    handleRowExpand() {
      this.$refs["my-table"].expandAll();
    },
    onRowMouseover(params) {
      if (this.enableRowHover) {
        this.hoveredRowId = params.row.id;
      }
    },
    onRowMouseleave() {
      if (this.enableRowHover) {
        this.hoveredRowId = null;
      }
    },
    isRowHovered(props) {
      if (!this.enableRowHover || !this.hoveredRowId) {
        return false;
      }
      return props.row.id === this.hoveredRowId;
    },
    updateFloatingActionBarPosition() {
      if (!this.shouldShowFloatingActionBar) {
        this.floatingActionBarStyle = {};
        return;
      }

      let contentContainer = document.querySelector(this.containerSelector);
      if (!contentContainer && this.$el) {
        contentContainer = this.$el.closest(".content");
      }
      if (!contentContainer) {
        this.floatingActionBarStyle = {
          maxWidth: "100%",
        };
        return;
      }

      const rect = contentContainer.getBoundingClientRect();
      const containerCenter = rect.left + rect.width / 2;

      this.floatingActionBarStyle = {
        left: `${containerCenter}px`,
        width: "max-content",
        maxWidth: "100%",
      };
    },
    cleanupResizeObserver() {
      if (this._resizeHandler) {
        window.removeEventListener("resize", this._resizeHandler);
        this._resizeHandler = null;
      }
    },
    setupResizeObserver() {
      // Remove existing listener if any
      if (this._resizeHandler) {
        window.removeEventListener("resize", this._resizeHandler);
      }

      // Create debounced resize handler
      this._resizeHandler = debounce(() => {
        if (this.shouldShowFloatingActionBar) {
          this.updateFloatingActionBarPosition();
        }
      }, RESIZE_DEBOUNCE_DELAY);

      window.addEventListener("resize", this._resizeHandler);
    },
  },
  watch: {
    paginationData(newValue, oldValue) {
      if (!isEqual(newValue, oldValue)) {
        this.paginationRecords = newValue;
      }
    },
    rows(newValue, oldValue) {
      if (!isEqual(newValue, oldValue)) {
        this.reorderedArray = newValue;
      }
    },
    shouldShowFloatingActionBar(newValue) {
      if (newValue) {
        this.$nextTick(() => {
          this.updateFloatingActionBarPosition();
          this.setupResizeObserver();
        });
      } else {
        this.floatingActionBarStyle = {};
        this.cleanupResizeObserver();
      }
    },
  },
};
</script>
<style>
.vgt-table {
  border-spacing: 0;
  border: none !important;
  font-family: "Inter";
  font-size: 14px !important;
}
table.vgt-table td {
  vertical-align: middle;
}
.vgt-table thead th {
  background: linear-gradient(#fff, #fff);
}
.vgt-table th.vgt-checkbox-col {
  border-right: 0;
  border-bottom: 1px solid #dcdfe6;
  background: linear-gradient(#fff, #fff);
}
table.vgt-table tr.clickable:hover {
  background-color: #f9fafb;
  border-bottom: 1px solid #dcdfe6 !important;
}
.vgt-table th.sortable button::before,
.vgt-table th.sortable button::after {
  border-right: 0;
  border-left: 0;
}
[type="checkbox"],
[type="checkbox"]:focus {
  border-radius: 4px;
  border-color: #d1d5db;
  cursor: pointer;
  color: #0284c7;
  --tw-ring-color: #0284c7;
}

/* tbody > tr > th.vgt-checkbox-col {
  background: linear-gradient(#fff, #fff);
  border-bottom: 1px solid #dcdfe6;
} */
.vgt-global-search {
  background: none;
  border: none;
  padding: 0 0 12px 0;
}
.vgt-global-search__input {
  padding-left: 0;
}
.input__icon {
  display: none;
}
.vgt-global-search__input .vgt-input {
  height: 38px;
  width: 250px;
}
.vgt-inner-wrap {
  box-shadow: none;
}
.vgt-inner-wrap.is-loading {
  opacity: 1;
  pointer-events: auto;
}
.vgt-table th.sortable:hover .sortingIcon {
  visibility: visible;
}
.vgt-responsive {
  position: static;
  border-top-left-radius: 8px;
  border-top-right-radius: 8px;
  border-bottom-left-radius: var(--vgt-bottom-radius, 0);
  border-bottom-right-radius: var(--vgt-bottom-radius, 0);
}
.vgt-wrap {
  position: static;
}
.hover-text-column {
  text-align: right;
  padding-right: 1rem;
  width: 180px;
  min-width: 180px;
}
.floating-action-bar-enter-active,
.floating-action-bar-leave-active {
  transition: opacity 300ms ease, transform 300ms ease;
}

.floating-action-bar-enter,
.floating-action-bar-leave-to {
  opacity: 0;
  transform: translate(-50%, 100%);
}

.floating-action-bar-enter-to,
.floating-action-bar-leave {
  opacity: 1;
  transform: translate(-50%, 0);
}
</style>
