/* eslint-disable @typescript-eslint/no-explicit-any */

import { get } from '@/rtk/helpers/apiService'
import {
  Box,
  Button,
  Checkbox,
  CloseButton,
  Container,
  Group,
  MultiSelect,
  Pagination,
  RadioGroup,
  Select,
  Skeleton,
  Table,
  Text,
  TextInput,
  Tooltip,
  rem,
} from '@mantine/core'
import { DateInput, DateTimePicker } from '@mantine/dates'
import {
  IconArrowBadgeLeftFilled,
  IconArrowBadgeRightFilled,
  IconArrowsSort,
  IconFilterExclamation,
  IconFilterSearch,
  IconSortAscendingLetters,
  IconSortDescendingLetters,
  IconX,
} from '@tabler/icons-react'
import { ReactNode, useEffect, useState } from 'react'
import { useLocation, useNavigate } from 'react-router-dom'
import classes from './DataTable.module.css'
import { history } from '@/rtk/helpers/history'

export enum TypeFilter {
  text = 'text',
  boolean = 'boolean',
  datetime = 'datetime',
  date = 'date',
  select = 'select',
  MultiSelect = 'MultiSelect',
}

type Column = {
  name: string
  size: string
  header: string
  render?: (row: any, data?: any[]) => ReactNode
}

const sortByProperty = (property: string, type: string) => {
  switch (type) {
    case 'asc':
      return (a: any, b: any) => {
        if (a[property] < b[property]) {
          return -1
        } else if (a[property] > b[property]) {
          return 1
        } else {
          return 0
        }
      }
    case 'desc':
      return (a: any, b: any) => {
        if (a[property] > b[property]) {
          return -1
        } else if (a[property] < b[property]) {
          return 1
        } else {
          return 0
        }
      }
  }
}

export const DataTableAll = ({
  data,
  columns,
  pagination,
  searchInput,
  checkBox,
  size,
}: {
  data: any[]
  columns: Column[]
  pagination?: boolean
  searchInput?: boolean
  checkBox?: boolean
  size: string
}) => {
  const [Tdata, setTData] = useState<any[]>(data)
  // const [tempData, setTempData] = useState<any[]>([])
  const [search, setSearch] = useState('')
  const [statusSort, setStatusSort] = useState({
    name: '',
    status: 'clear',
  })
  const [perPage, setPerPage] = useState(10)
  const [page, setPage] = useState(1)
  const [selectedRows, setSelectedRows] = useState<any[]>([])
  const headers = columns.map((col) => (
    <Table.Th w={col.size} key={col.header}>
      <Box className={classes.boxTh}>
        {col.header}{' '}
        <Tooltip
          label={
            <Text className={classes.labelTooltip} fz={'0.7rem'}>
              Desc
            </Text>
          }
          color="gray"
        >
          <IconArrowsSort
            display={statusSort.status === 'clear' ? 'block' : 'none'}
            onClick={() => {
              setStatusSort({ name: col.name, status: 'desc' })
              // localStorage.setItem('package__table_sort', JSON.stringify({ name: col.name, status: 'desc' }))
              // setTData(data.slice().sort(sortByProperty(col.name, 'desc')))
            }}
            className={classes.iconSort}
          />
        </Tooltip>
        <Tooltip
          label={
            <Text className={classes.labelTooltip} fz={'0.7rem'}>
              Asc
            </Text>
          }
          color="gray"
        >
          <IconSortDescendingLetters
            display={
              statusSort.name === col.name && statusSort.status === 'desc'
                ? 'block'
                : 'none'
            }
            onClick={() => {
              setStatusSort({ name: col.name, status: 'asc' })
              // localStorage.setItem('package__table_sort', JSON.stringify({ name: col.name, status: 'asc' }))
              // setTData(data.slice().sort(sortByProperty(col.name, 'asc')))
            }}
            className={classes.iconSort}
          />
        </Tooltip>
        <Tooltip
          label={
            <Text className={classes.labelTooltip} fz={'0.7rem'}>
              Clear
            </Text>
          }
          color="gray"
        >
          <IconSortAscendingLetters
            display={
              statusSort.name === col.name && statusSort.status === 'asc'
                ? 'block'
                : 'none'
            }
            onClick={() => {
              setStatusSort({ name: col.name, status: 'clear' })
            }}
            className={classes.iconSort}
          />
        </Tooltip>
      </Box>
    </Table.Th>
  ))

  const rows = Tdata.map((element, index) => {
    const row = columns.map((col) => {
      if (col.render) {
        return (
          <Table.Td key={col.header}>{col.render(element, Tdata)}</Table.Td>
        )
      } else {
        if (element[col.name]) {
          return (
            <Table.Td key={col.header}>
              <span>{element[col.name].toString()}</span>
            </Table.Td>
          )
        } else {
          return (
            <Table.Td key={col.header}>
              <i>null</i>
            </Table.Td>
          )
        }
      }
    })

    return (
      <Table.Tr
        key={index}
        bg={
          selectedRows.some((obj) =>
            Object.keys(obj).every((key) => obj[key] === element[key]),
          )
            ? 'var(--mantine-color-blue-light)'
            : undefined
        }
      >
        <Table.Td display={checkBox ? 'block' : 'none'}>
          <Checkbox
            aria-label="Select row"
            checked={selectedRows.some((obj) =>
              Object.keys(obj).every((key) => obj[key] === element[key]),
            )}
            onChange={(event) =>
              setSelectedRows(
                event.currentTarget.checked
                  ? [...selectedRows, element]
                  : selectedRows.filter((position) => position !== element),
              )
            }
          />
        </Table.Td>
        {row}
      </Table.Tr>
    )
  })

  const [debounceTimer, setDebounceTimer] = useState<any>()

  const handleInput = (e: any) => {
    clearTimeout(debounceTimer)
    setDebounceTimer(
      setTimeout(() => {
        searchInArray(e)
      }, 500),
    )
  }

  const searchInArray = (query: string) => {
    if (query !== '') {
      setTData(
        data.filter((obj) =>
          Object.values(obj).some(
            (value: any) =>
              value !== null &&
              value.toString().toLowerCase().includes(query.toLowerCase()),
          ),
        ),
      )
    } else {
      if (pagination) {
        const temp = data.slice(perPage * (page - 1), perPage * page)
        setTData(temp)
      } else {
        setTData(data)
      }
    }
  }

  const areObjectsEqual = (obj1: any, obj2: any) => {
    return Object.keys(obj1).every((key) => obj1[key] === obj2[key])
  }

  const checkSubArray = (arr1: any[], arr2: any[]) => {
    return arr1.some((obj1: any) =>
      arr2.some((obj2: any) => areObjectsEqual(obj1, obj2)),
    )
  }
  useEffect(() => {
    if (pagination) {
      setTData(data.slice(perPage * (page - 1), perPage * page))
    } else {
      if (statusSort.status !== 'clear') {
        setTData(
          data.slice().sort(sortByProperty(statusSort.name, statusSort.status)),
        )
      } else {
        setTData(data)
      }
    }
  }, [data, statusSort])

  useEffect(() => {
    if (pagination) {
      const temp = data.slice(perPage * (page - 1), perPage * page)
      setTData(temp)
    }
  }, [page, perPage])

  return (
    <Container className={classes.container} size={size}>
      <Box className={classes.menuBox}>
        <Box className={classes.boxSearch}>
          <TextInput
            className={classes.searchInput}
            size="xs"
            value={search}
            display={searchInput ? 'block' : 'none'}
            rightSection={
              <CloseButton
                aria-label="Clear input"
                size={'sm'}
                onClick={() => {
                  setSearch('')
                  handleInput('')
                }}
                style={{ display: search ? undefined : 'none' }}
              />
            }
            placeholder="🔍 Search"
            onChange={(e) => {
              handleInput(e.target.value)
              setSearch(e.target.value)
            }}
          />

          {search !== '' ? (
            <Text c={'#b6bec5'} fz={'sm'} ta={'right'} fs={'italic'}>
              Found {Tdata.length} matches out of {data.length} entries
            </Text>
          ) : (
            <Text c={'#b6bec5'} fz={'sm'} ta={'right'} fs={'italic'}>
              Show {perPage * (page - 1) + 1} to {data.length} of {data.length}{' '}
              entries
            </Text>
          )}
        </Box>

        <Box
          className={classes.paginationBox}
          display={pagination ? 'flex' : 'none'}
        >
          <Pagination
            size={'xs'}
            color="#a5a2a3"
            total={
              data.length % perPage !== 0
                ? data.length / perPage + 1
                : data.length / perPage
            }
            siblings={1}
            value={page}
            disabled={search !== ''}
            onChange={(e) => setPage(e)}
          />
          <Select
            size="xs"
            w={'30%'}
            min={10}
            max={500}
            lh={2}
            variant="filled"
            ml={'sm'}
            label="Per page"
            data={['10', '20', '50', '100', '200', '500']}
            value={perPage.toString()}
            searchable
            disabled={search !== ''}
            onChange={(e: any) => {
              setPerPage(parseInt(e))
            }}
          />
        </Box>
      </Box>
      <Box className={classes.box}>
        <Table
          stickyHeader
          stickyHeaderOffset={-1}
          striped
          highlightOnHover
          withTableBorder
          withColumnBorders
        >
          <Table.Thead className={classes.headers}>
            <Table.Tr>
              <Table.Th display={checkBox ? 'block' : 'none'}>
                <Checkbox
                  aria-label="Select row"
                  checked={
                    checkSubArray(Tdata, selectedRows) &&
                    Tdata.length === selectedRows.length
                  }
                  onChange={(event) =>
                    setSelectedRows(
                      event.currentTarget.checked
                        ? (pre) => [...pre, ...Tdata]
                        : selectedRows.filter(
                            (item) =>
                              !Tdata.some((removeItem) =>
                                areObjectsEqual(item, removeItem),
                              ),
                          ),
                    )
                  }
                />
              </Table.Th>
              {headers}
            </Table.Tr>
          </Table.Thead>
          <Table.Tbody>{rows}</Table.Tbody>
        </Table>
      </Box>
    </Container>
  )
}

export const DataTablePagination = ({
  data,
  columns,
  filterInfo,
  searchInput,
  checkBox,
  size,
}: {
  data: any
  columns: Column[]
  filterInfo: any[]
  searchInput?: boolean
  checkBox?: boolean
  size: string
}) => {
  const [flag, setFlag] = useState(false)
  const [Tdata, setTData] = useState<any[]>(data.data)
  const [baseData, setBaseData] = useState<any>(data)
  const [clearState, setClearState] = useState<any>(0)
  const initialFilterState = Object.fromEntries(
    filterInfo.map((item) => {
      const key = item.key
      const value = item.value || ''
      return [key, value]
    }),
  )
  const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
  const [skeleton, setSkeletion] = useState(false)
  const [search, setSearch] = useState('')
  const [openedFilter, setOpenedFilter] = useState(false)
  const [dataFilter, setDataFilter] = useState<any>(initialFilterState)
  const [perPage, setPerPage] = useState(data.per_page)
  const [page, setPage] = useState(data.current_page)
  const location = useLocation()
  const [statusSort, setStatusSort] = useState({
    name: '',
    status: 'clear',
  })
  const [selectedRows, setSelectedRows] = useState<any[]>([])
  const navigate = useNavigate()
  const urlParams = new URLSearchParams(location.search)

  // Render headers
  const headers = columns.map((col) => (
    <Table.Th w={col.size} key={col.header}>
      <Box className={classes.boxTh}>
        {col.header} {/* Icon sort */}
        <Tooltip
          label={
            <Text className={classes.labelTooltip} fz={'0.7rem'}>
              Desc
            </Text>
          }
          color="gray"
        >
          <IconArrowsSort
            display={
              col.name !== '#' && statusSort.status === 'clear'
                ? 'block'
                : 'none'
            }
            onClick={() => {
              setStatusSort({ name: col.name, status: 'desc' })
            }}
            className={classes.iconSort}
          />
        </Tooltip>
        <Tooltip
          label={
            <Text className={classes.labelTooltip} fz={'0.7rem'}>
              Asc
            </Text>
          }
          color="gray"
        >
          <IconSortDescendingLetters
            display={
              col.name !== '#' &&
              statusSort.name === col.name &&
              statusSort.status === 'desc'
                ? 'block'
                : 'none'
            }
            onClick={() => {
              setStatusSort({ name: col.name, status: 'asc' })
            }}
            className={classes.iconSort}
          />
        </Tooltip>
        <Tooltip
          label={
            <Text className={classes.labelTooltip} fz={'0.7rem'}>
              Clear
            </Text>
          }
          color="gray"
        >
          <IconSortAscendingLetters
            display={
              col.name !== '#' &&
              statusSort.name === col.name &&
              statusSort.status === 'asc'
                ? 'block'
                : 'none'
            }
            onClick={() => {
              setStatusSort({ name: col.name, status: 'clear' })
            }}
            className={classes.iconSort}
          />
        </Tooltip>
      </Box>
    </Table.Th>
  ))

  // Render rows

  const rows =
    Tdata.length > 0 &&
    Tdata.map((element, index) => {
      const row = columns.map((col) => {
        // Check 'render' option in config header
        if (col.render) {
          return (
            <Table.Td key={col.header}>{col.render(element, Tdata)}</Table.Td>
          )
        } else {
          // Check data
          if (typeof element[col.name] !== 'undefined') {
            return <Table.Td key={col.header}>{element[col.name]}</Table.Td>
          } else {
            return (
              <Table.Td key={col.header}>
                <i>unknown</i>
              </Table.Td>
            )
          }
        }
      })

      return (
        <Table.Tr
          key={index}
          bg={
            selectedRows.some((obj) =>
              Object.keys(obj).every((key) => obj[key] === element[key]),
            )
              ? 'var(--mantine-color-blue-light)'
              : undefined
          }
        >
          <Table.Td display={checkBox ? 'block' : 'none'}>
            <Checkbox
              aria-label="Select row"
              checked={selectedRows.some((obj) =>
                Object.keys(obj).every((key) => obj[key] === element[key]),
              )}
              onChange={(event) =>
                setSelectedRows(
                  event.currentTarget.checked
                    ? [...selectedRows, element]
                    : selectedRows.filter((position) => position !== element),
                )
              }
            />
          </Table.Td>
          {row}
        </Table.Tr>
      )
    })

  const removeParam = (name:string) => {
    // Create a URL object
    let url = new URL(window.location.href)

    // Get the search parameters object
    let params = url.searchParams

    // Remove specific parameters
    params.delete(name)

    // Update the URL without reloading the page
    window.history.replaceState({}, document.title, url.toString())
  }
  // Refresh data when useEffect start
  const fetchData = async (url: string) => {
    try {
      setSkeletion(true)
      const params = {
        search: search,
        per_page: perPage,
        page: page,
        timezone: timeZone,
      }
      // console.log(statusSort.name)
      // Add 'order_by_[field_name] to 'params'
      if (statusSort.status !== 'clear') {
        Object.assign(params, {
          [`order_by_${statusSort.name}`]: statusSort.status,
        })
      }

      // Add all attributes in dataFilter to 'params'
      Object.keys(dataFilter).map((key: any) => {
        if (dataFilter[key] !== '' && dataFilter[key] !== null) {
          Object.assign(params, {
            [key]:
              typeof dataFilter[key] === 'string' ||
              typeof dataFilter[key] === 'number' ||
              Array.isArray(dataFilter[key])
                ? dataFilter[key]
                : key === 'to_date'
                ? Math.floor(dataFilter[key].getTime() / 1000) +
                  (60 * 60 * 23 + 60 * 59 + 59)
                : Math.floor(dataFilter[key].getTime() / 1000),
          })
        }
      })

      if (
        dataFilter.date_used &&
        dataFilter.date_used !== null &&
        dataFilter.date_used !== ''
      ) {
        const appendSecond = 60 * 60 * 23 + 60 * 59 + 59
        let date_used = dataFilter.date_used

        if (typeof date_used === 'string') {
          // unix timestamp
          if (date_used.length === 10) {
            date_used = Math.floor(parseInt(date_used) + appendSecond)
          } else if (date_used.length === 13) {
            // browser timestamp to unix timestamp
            date_used = Math.floor(parseInt(date_used) / 1000 + appendSecond)
          }
        } else {
          date_used = Math.floor(date_used.getTime() / 1000 + appendSecond)
        }

        // FIXME: append to parameters query to filter
        Object.assign(params, {
          date_used_to: date_used,
        })
      }

      // Add all attributes in 'params' to URL params
      Object.entries(params).forEach((param) => urlParams.set(...param))
      Object.entries(dataFilter).forEach(([key, value]) => {
        const typeFilter = filterInfo.find((o) => o.key === key).type
        const hasType = {
          MultiSelect: typeFilter === TypeFilter.MultiSelect,
          Date:
            typeFilter === TypeFilter.date ||
            typeFilter === TypeFilter.datetime,
        }

        if (hasType.MultiSelect) {
          value = Array(value).length ? Array(value).join(',') : []
        }

        if (hasType.Date) {
          value = value ? Date.parse(String(value)) / 1000 : '' // to unix timestamp
        }

        String(value).length
          ? urlParams.set(key, String(value))
          : urlParams.delete(key)
      })

      // Request to get data API
      const res = await get(url, Object.fromEntries(urlParams.entries()))
      if (res.status) {
        setBaseData(res)
        setTData(res.data)
        setSkeletion(false)
        navigate({
          pathname: location.pathname,
          search: urlParams.toString(),
        })
      }
      statusSort.status === 'clear' && removeParam(`order_by_${statusSort.name}`)
    } catch (error) {
      console.warn(error)
    }
  }
  const [debounceTimer, setDebounceTimer] = useState<any>()

  const handleData = (time: number, setPage?: any) => {
    if (search !== '') {
      clearTimeout(debounceTimer)
      setDebounceTimer(
        setTimeout(() => {
          fetchData(baseData.path)
        }, time),
      )
    } else {
      fetchData(baseData.path)
    }
    setPage && setPage(1)
  }

  const clearFilterData = () => {
    setDataFilter(initialFilterState)
    setClearState(clearState + 1)
  }

  const areObjectsEqual = (obj1: any, obj2: any) => {
    return Object.keys(obj1).every((key) => obj1[key] === obj2[key])
  }

  const checkSubArray = (arr1: any[], arr2: any[]) => {
    return arr1.some((obj1: any) =>
      arr2.some((obj2: any) => areObjectsEqual(obj1, obj2)),
    )
  }

  useEffect(() => {
    setBaseData(data)
    setTData(data.data)
    const updatedDataFilter = { ...dataFilter }
    const order_by_ = location.search
      .split('&')
      .filter((i) => i.includes('order_by_'))[0]
    Object.keys(dataFilter).forEach((key) => {
      const paramValue = urlParams.get(key)
      if (paramValue !== null) {
        const typeFilter = filterInfo.find((o: any) => o.key === key).type
        // multiple select
        if (typeFilter == TypeFilter.MultiSelect) {
          updatedDataFilter[key] = String(paramValue).split(',')
        } else if (
          [TypeFilter.date, TypeFilter.datetime].includes(typeFilter)
        ) {
          const isTimestamp = new Date(parseInt(paramValue)).getTime() > 0
          isTimestamp
            ? (updatedDataFilter[key] = paramValue)
            : (updatedDataFilter[key] = null)
        } else {
          updatedDataFilter[key] = paramValue
        }
      }
    })
    urlParams.get('search') !== null && setSearch(urlParams.get('search')!)

    setDataFilter(updatedDataFilter)

    if (order_by_) {
      const sortParam = {
        name: order_by_.split('=')[0].split('_')[2],
        status: order_by_.split('=')[1],
      }
      if (JSON.stringify(sortParam) !== JSON.stringify(statusSort)) {
        setStatusSort(sortParam)
      }
    }
  }, [data])

  useEffect(() => {
    if (flag) {
      handleData(500)
    } else {
      setFlag(true)
    }
  }, [page, perPage, statusSort, clearState])

  useEffect(() => {
    if (flag && search === '') {
      handleData(500, setPage)
    } else {
      setFlag(true)
    }
  }, [search])

  return (
    <Container className={classes.container} size={size}>
      <Box
        display={openedFilter ? 'block' : 'none'}
        style={{ border: 'solid 1px rgb(206, 206, 206)', borderRadius: '5px' }}
      >
        <Box display={'flex'} className={classes.boxFilter} w={'100%'}>
          <IconX
            style={{
              position: 'absolute',
              top: '10%',
              right: '1%',
              cursor: 'pointer',
            }}
            size="20"
            onClick={() => {
              setOpenedFilter(false)
            }}
          />
          {filterInfo.map((item) => {
            switch (item.type) {
              case TypeFilter.text:
                return (
                  <TextInput
                    size="xs"
                    key={item.key}
                    value={dataFilter ? dataFilter[item.key] : ''}
                    className={classes.menuItem}
                    label={item.name}
                    onChange={(e) => {
                      setDataFilter({
                        ...dataFilter,
                        [item.key]: e.target.value,
                      })
                    }}
                  />
                )

              case TypeFilter.boolean:
                return (
                  <RadioGroup
                    size="xs"
                    key={item.key}
                    className={classes.menuItem}
                    value={dataFilter ? dataFilter[item.key] : ''}
                    label={item.name}
                    onDoubleClick={() => {
                      setDataFilter({ ...dataFilter, [item.key]: '' })
                    }}
                    onChange={(e) => {
                      setDataFilter({ ...dataFilter, [item.key]: e })
                    }}
                  >
                    {item.data}
                  </RadioGroup>
                )
              case TypeFilter.datetime:
                return (
                  <DateTimePicker
                    size="xs"
                    value={
                      dataFilter
                        ? dataFilter[item.key] !== null &&
                          dataFilter[item.key].length === 10
                          ? new Date(dataFilter[item.key] * 1000)
                          : dataFilter[item.key]
                        : ''
                    }
                    clearable
                    key={item.key}
                    className={classes.menuItem}
                    label={item.name}
                    onChange={(e) => {
                      setDataFilter({ ...dataFilter, [item.key]: e })
                    }}
                  />
                )
              case TypeFilter.date:
                return (
                  <DateInput
                    size="xs"
                    value={
                      dataFilter
                        ? dataFilter[item.key] !== null &&
                          dataFilter[item.key].length === 10
                          ? new Date(dataFilter[item.key] * 1000)
                          : dataFilter[item.key]
                        : ''
                    }
                    clearable
                    valueFormat="YYYY/MM/DD"
                    key={item.key}
                    className={classes.menuItem}
                    label={item.name}
                    onChange={(e) => {
                      setDataFilter({ ...dataFilter, [item.key]: e })
                    }}
                  />
                )
              case TypeFilter.select:
                return (
                  <Select
                    size="xs"
                    key={item.key}
                    value={
                      dataFilter.discount_type_id !== ''
                        ? dataFilter[item.key]
                        : null
                    }
                    className={classes.menuItem}
                    label={item.name}
                    onChange={(e) => {
                      setDataFilter({ ...dataFilter, [item.key]: e })
                    }}
                    data={item.data}
                  />
                )
              case TypeFilter.MultiSelect:
                return (
                  <MultiSelect
                    size="xs"
                    key={item.key}
                    label={item.name}
                    placeholder={item.placeholder ?? undefined}
                    data={item.data}
                    value={dataFilter[item.key]}
                    onChange={(values) => {
                      urlParams.set(item.key, values.join(','))
                      history.push({
                        pathName: location.pathname,
                        search: urlParams.toString(),
                      })
                      setDataFilter({
                        ...dataFilter,
                        [item.key]: values,
                      })
                    }}
                    searchable
                  />
                )
            }
          })}
        </Box>

        <Group className={classes.groupBtn}>
          <Button
            size="xs"
            onClick={() => {
              handleData(1000)
              setPage(1)
            }}
          >
            Filter
          </Button>
          <Button
            size="xs"
            onClick={() => {
              clearFilterData()
            }}
          >
            Clear
          </Button>
        </Group>
      </Box>
      <Box className={classes.menuBox}>
        <Box className={classes.boxSearch}>
          <Box
            style={{
              cursor: 'pointer',
              display: filterInfo.length > 0 ? 'flex' : 'none',
            }}
            onClick={() => setOpenedFilter(!openedFilter)}
          >
            {Object.values(dataFilter).filter(
              (value) => value === '' || value === null,
            ).length === Object.keys(dataFilter).length ? (
              <IconFilterSearch style={{ marginBottom: '1vh' }} size={20} />
            ) : (
              <IconFilterExclamation
                color="red"
                style={{ marginBottom: '1vh' }}
                size={20}
              />
            )}
            <Text
              ml={rem('5px')}
              fw={600}
              fz={'1rem'}
              c={
                Object.values(dataFilter).filter(
                  (value) => value === '' || value === null,
                ).length !== Object.values(dataFilter).length
                  ? 'red'
                  : ''
              }
            >
              Filter
            </Text>
          </Box>
          <TextInput
            className={classes.searchInput}
            size="xs"
            value={search}
            display={searchInput ? 'block' : 'none'}
            rightSection={
              <CloseButton
                aria-label="Clear input"
                size={'sm'}
                onClick={() => {
                  setSearch('')
                }}
                style={{ display: search ? undefined : 'none' }}
              />
            }
            placeholder="🔍 Search"
            onChange={(e) => {
              setSearch(e.target.value)
            }}
            onKeyUp={() => {
              handleData(1500, setPage)
            }}
          />

          <Text className={classes.textSearch}>
            Show {baseData.from} to {baseData.to} of {baseData.total} entries
          </Text>
        </Box>

        <Box className={classes.paginationBox}>
          {baseData.links.map((element: any, index: number) => {
            switch (element.label) {
              case '&laquo; Previous':
                return (
                  <button
                    key={index}
                    className={classes.btnPagination}
                    onClick={() => {
                      page > 1 && setPage(page - 1)
                    }}
                    style={{
                      backgroundColor: element.active && '#739aaf',
                      color: element.active && 'white',
                    }}
                  >
                    <IconArrowBadgeLeftFilled size={15} />
                  </button>
                )
              case 'Next &raquo;':
                return (
                  <button
                    key={index}
                    className={classes.btnPagination}
                    onClick={() => {
                      page < baseData.last_page && setPage(page + 1)
                    }}
                    style={{
                      backgroundColor: element.active && '#739aaf',
                      color: element.active && 'white',
                    }}
                  >
                    <IconArrowBadgeRightFilled size={15} />
                  </button>
                )
              case '...':
                return (
                  <span key={index}>
                    {' '}
                    <b> ... </b>{' '}
                  </span>
                )
              default:
                return (
                  <button
                    key={index}
                    className={classes.btnPagination}
                    disabled={element.active}
                    onClick={() => {
                      setPage(element.label)
                    }}
                    style={{
                      backgroundColor: element.active && '#739aaf',
                      color: element.active && 'white',
                    }}
                  >
                    {element.label.toString()}
                  </button>
                )
            }
          })}

          <Select
            size="xs"
            w={'10%'}
            min={10}
            max={500}
            lh={2}
            variant="filled"
            ml={'sm'}
            label="Per page"
            data={['10', '15', '20', '50', '80', '100']}
            value={perPage}
            onChange={async (e: any) => {
              setPage(1)
              setPerPage(parseInt(e))
            }}
          />
        </Box>
      </Box>
      <Skeleton visible={skeleton}>
        <Box className={classes.box}>
          <Table
            stickyHeader
            stickyHeaderOffset={-1}
            striped
            highlightOnHover
            withTableBorder
            withColumnBorders
          >
            <Table.Thead className={classes.headers}>
              <Table.Tr>
                <Table.Th display={checkBox ? 'block' : 'none'}>
                  <Checkbox
                    aria-label="Select row"
                    checked={
                      checkSubArray(Tdata, selectedRows) &&
                      Tdata.length === selectedRows.length
                    }
                    onChange={(event) =>
                      setSelectedRows(
                        event.currentTarget.checked
                          ? (pre) => [...pre, ...Tdata]
                          : selectedRows.filter((item) =>
                              Tdata.some(
                                (removeItem) =>
                                  !areObjectsEqual(item, removeItem),
                              ),
                            ),
                      )
                    }
                  />
                </Table.Th>
                {headers}
              </Table.Tr>
            </Table.Thead>
            {Tdata.length > 0 ? (
              <Table.Tbody>{rows}</Table.Tbody>
            ) : (
              <Text
                w={'300px'}
                p={'lg'}
                c={'#dbdee3'}
                fw={600}
                fz={'1.5rem'}
                fs={'italic'}
              >
                Data Empty
              </Text>
            )}
          </Table>
        </Box>
      </Skeleton>
    </Container>
  )
}
export default DataTableAll
