import {
  forwardRef,
  useImperativeHandle,
  useRef,
  useEffect,
  useState,
  useCallback,
  useMemo,
  createElement
} from 'react'
import {
  Table,
  Skeleton,
  Row,
  Col,
  Flex,
  Spin,
  Button,
  Input,
  Space,
  Tooltip,
  Form
} from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import PropTypes from 'prop-types'
import { useMediaQuery } from 'react-responsive'
import { useContext } from 'react'
import { ApiServerContext } from '../context/ApiServerContext'
import config from '../../../config'
import loglevel from 'loglevel'
import {
  getModelProperties,
  getModelByName
} from '../../../database/ObjectModels'
import ObjectProperty from './ObjectProperty'
import ObjectCard from './ObjectCard'
import FilterSidebar from './FilterSidebar'
import XMarkIcon from '../../Icons/XMarkIcon'
import CheckIcon from '../../Icons/CheckIcon'
import { useNavigate } from 'react-router-dom'
import QuestionCircleIcon from '../../Icons/QuestionCircleIcon'
import { AuthContext } from '../context/AuthContext'
import { ElectronContext } from '../context/ElectronContext'
import ActionsIcon from '../../Icons/ActionsIcon'
import FilterIcon from '../../Icons/FilterIcon'

const logger = loglevel.getLogger('DasboardTable')
logger.setLevel(config.logLevel)

const RowForm = ({ record, isEditing, onRegister, children }) => {
  const [form] = Form.useForm()
  useEffect(() => {
    if (isEditing && record && !record.isSkeleton) {
      form.setFieldsValue(record)
      onRegister(record._id, form)
    }
    return () => {
      if (record?._id) onRegister(record._id, null)
    }
  }, [isEditing, record, form, onRegister])

  return (
    <Form form={form} component={false}>
      {children}
    </Form>
  )
}

RowForm.propTypes = {
  record: PropTypes.object,
  isEditing: PropTypes.bool,
  onRegister: PropTypes.func,
  children: PropTypes.node
}

const EditableRow = ({ record, isEditing, onRegister, ...props }) => {
  return (
    <RowForm record={record} isEditing={isEditing} onRegister={onRegister}>
      <tr {...props} />
    </RowForm>
  )
}

EditableRow.propTypes = {
  record: PropTypes.object,
  isEditing: PropTypes.bool,
  onRegister: PropTypes.func
}

const ObjectTable = forwardRef(
  (
    {
      type,
      pageSize = 25,
      scrollHeight = 'calc(var(--unit-100vh) - 260px)',
      onDataChange,
      initialPage = 1,
      cards = false,
      visibleColumns = {},
      masterFilter = {},
      size = 'middle',
      onStateChange,
      showFilterSidebar = false
    },
    ref
  ) => {
    const { token } = useContext(AuthContext)
    const { isElectron } = useContext(ElectronContext)
    const onStateChangeRef = useRef(onStateChange)
    const { userProfile } = useContext(AuthContext)
    useEffect(() => {
      onStateChangeRef.current = onStateChange
    }, [onStateChange])
    const {
      fetchObjects,
      connected,
      subscribeToObjectUpdates,
      subscribeToObjectTypeUpdates,
      updateMultipleObjects,
      lockObject,
      unlockObject
    } = useContext(ApiServerContext)
    const isMobile = useMediaQuery({ maxWidth: 768 })
    const navigate = useNavigate()
    var adjustedScrollHeight = scrollHeight
    if (isMobile) {
      adjustedScrollHeight = 'calc(var(--unit-100vh) - 316px)'
    }
    if (cards) {
      adjustedScrollHeight = 'calc(var(--unit-100vh) - 210px)'
    }
    if (isElectron) {
      adjustedScrollHeight = 'calc(var(--unit-100vh) - 244px)'
    }
    if (isMobile && isElectron) {
      adjustedScrollHeight = 'calc(var(--unit-100vh) - 282px)'
    }
    if (cards && isElectron) {
      adjustedScrollHeight = 'calc(var(--unit-100vh) - 260px)'
    }
    const tableRef = useRef(null)
    const model = getModelByName(type)
    const activeFilterRef = useRef({})
    const tableSorterRef = useRef({})
    const [sidebarFilter, setSidebarFilter] = useState({})
    const [initialized, setInitialized] = useState(false)

    // Table state
    const [pages, setPages] = useState([])
    const pagesRef = useRef(pages)
    const [hasMore, setHasMore] = useState(true)
    const [loading, setLoading] = useState(true)
    const [lazyLoading, setLazyLoading] = useState(false)
    const [tableData, setTableData] = useState([])

    const [isEditing, setIsEditing] = useState(false)
    const [editLoading, setEditLoading] = useState(false)
    const rowFormsRef = useRef({})
    const registerForm = useCallback((id, form) => {
      if (form) {
        rowFormsRef.current[id] = form
      } else {
        delete rowFormsRef.current[id]
      }
    }, [])

    useEffect(() => {
      onStateChangeRef.current?.({ isEditing, editLoading })
    }, [isEditing, editLoading])

    const subscribedIdsRef = useRef([])
    // const [typeSubscribed, setTypeSubscribed] = useState(false)
    const unsubscribesRef = useRef([])
    const updateEventHandlerRef = useRef()
    const subscribeToObjectTypeUpdatesRef = useRef(null)
    const prevValuesRef = useRef({ type, masterFilter })

    const rowActions =
      model.actions?.filter((action) => action.row == true) || []

    const createSkeletonData = useCallback(() => {
      return Array(pageSize)
        .fill(null)
        .map(() => ({
          _id: `skeleton-${Math.random().toString(36).substring(2, 15)}`,
          isSkeleton: true
        }))
    }, [pageSize])

    const renderActions = (objectData) => {
      return (
        <Flex gap='small' align='center' justify='center'>
          {rowActions.map((action, index) => {
            var disabled = false
            if (action.disabled) {
              if (typeof action.disabled === 'function') {
                disabled = action.disabled({
                  ...objectData,
                  _user: userProfile
                })
              } else {
                disabled = action.disabled
              }
            }
            return (
              <Tooltip key={index} title={action.label} arrow={false}>
                <Button
                  icon={
                    action.icon ? (
                      createElement(action.icon)
                    ) : (
                      <QuestionCircleIcon />
                    )
                  }
                  disabled={disabled}
                  type={'text'}
                  size={'small'}
                  onClick={() => {
                    if (action.url) {
                      navigate(action.url(objectData._id))
                    }
                  }}
                />
              </Tooltip>
            )
          })}
        </Flex>
      )
    }

    const fetchData = useCallback(
      async (pageNum = 1, filter = null, sorter = null) => {
        if (filter == null) {
          filter = activeFilterRef.current
        } else {
          activeFilterRef.current = filter
        }
        if (sorter == null) {
          sorter = tableSorterRef.current
        } else {
          tableSorterRef.current = {
            field: sorter.field,
            order: sorter.order
          }
        }
        try {
          const result = await fetchObjects(type, {
            page: pageNum,
            limit: pageSize,
            filter: { ...filter, ...masterFilter },
            sorter,
            onDataChange
          })

          setHasMore(result.hasMore)

          setPages((prev) => {
            const existingPageIndex = prev.findIndex(
              (p) => p.pageNum === pageNum
            )
            if (existingPageIndex !== -1) {
              // Update existing page
              const newPages = [...prev]
              newPages[existingPageIndex] = { pageNum, items: result.data }
              return newPages
            }
            // If page doesn't exist, return unchanged
            return prev
          })

          setLoading(false)
          setLazyLoading(false)
          return result.data || []
        } catch (error) {
          setPages((prev) =>
            prev.map((page) => ({
              ...page,
              items: page.items.filter((item) => !item.isSkeleton)
            }))
          )
          setLoading(false)
          setLazyLoading(false)
          throw error
        }
      },
      [type, masterFilter, pageSize, onDataChange, fetchObjects]
    )

    const loadNextPage = useCallback(() => {
      const highestPage = Math.max(...pages.map((p) => p.pageNum))
      const nextPage = highestPage + 1
      if (hasMore && lazyLoading == false) {
        setPages((prev) => {
          const filteredPages = prev.map((page) => ({
            ...page,
            items: page.items.filter((item) => !item.isSkeleton)
          }))
          const minPage = Math.min(...filteredPages.map((p) => p.pageNum))
          const relevantPages = filteredPages.filter(
            (p) => p.pageNum !== minPage
          )
          return [
            ...relevantPages,
            { pageNum: nextPage, items: createSkeletonData() }
          ]
        })
        fetchData(nextPage)
      }
    }, [pages, createSkeletonData, fetchData, hasMore, lazyLoading])

    const loadPreviousPage = useCallback(() => {
      const lowestPage = Math.min(...pages.map((p) => p.pageNum))
      const prevPage = lowestPage - 1

      if (prevPage > 0 && lazyLoading == false) {
        setPages((prev) => {
          const filteredPages = prev.map((page) => ({
            ...page,
            items: page.items.filter((item) => !item.isSkeleton)
          }))
          const maxPage = Math.max(...filteredPages.map((p) => p.pageNum))
          const relevantPages = filteredPages.filter(
            (p) => p.pageNum !== maxPage
          )
          return [
            { pageNum: prevPage, items: createSkeletonData() },
            ...relevantPages
          ]
        })
        fetchData(prevPage)
      }
    }, [pages, createSkeletonData, fetchData, lazyLoading])

    const handleScroll = useCallback(
      (e) => {
        const { target } = e
        const scrollHeight = target.scrollHeight
        const scrollTop = target.scrollTop
        const clientHeight = target.clientHeight
        const lowestPage = Math.min(...pages.map((p) => p.pageNum))
        const prevPage = lowestPage - 1

        // Load more data when scrolling down
        if (scrollHeight - scrollTop - clientHeight < 100 && hasMore) {
          setTimeout(() => {
            target.scrollTop = scrollHeight / 2
          }, 0)
          setLazyLoading(true)
          logger.debug('Loading next page...')
          loadNextPage()
        }

        // Load previous data when scrolling up
        if (scrollTop < 100 && prevPage > 0) {
          setTimeout(() => {
            target.scrollTop = scrollHeight / 2
          }, 0)
          setLazyLoading(true)
          logger.debug('Loading previous page...')
          loadPreviousPage()
        }
      },
      [loadNextPage, loadPreviousPage, hasMore, pages]
    )

    const reload = useCallback(async () => {
      setLazyLoading(true)
      for (let i = 0; i < pagesRef.current.length; i++) {
        const page = pagesRef.current[i]
        await fetchData(page.pageNum)
      }
    }, [fetchData])

    const startEditing = useCallback(() => {
      setIsEditing(true)
      tableData.forEach((item) => {
        if (!item.isSkeleton) {
          lockObject(item._id, type)
        }
      })
    }, [tableData, lockObject, type])

    const cancelEditing = useCallback(() => {
      setIsEditing(false)
      tableData.forEach((item) => {
        if (!item.isSkeleton) {
          unlockObject(item._id, type)
        }
      })
    }, [tableData, unlockObject, type])

    const handleUpdate = useCallback(async () => {
      setEditLoading(true)
      try {
        const updates = await Promise.all(
          Object.entries(rowFormsRef.current).map(async ([id, form]) => {
            const values = await form.validateFields()
            return { _id: id, ...values }
          })
        )
        await updateMultipleObjects(type, updates)
        setIsEditing(false)
        reload()
        tableData.forEach((item) => {
          if (!item.isSkeleton) {
            unlockObject(item._id, type)
          }
        })
      } catch (err) {
        logger.error('Error updating objects:', err)
      } finally {
        setEditLoading(false)
      }
    }, [type, updateMultipleObjects, reload, tableData, unlockObject])

    // Update event handler for real-time updates
    const updateEventHandler = useCallback((id, updatedData) => {
      setPages((prevPages) =>
        prevPages.map((page) => {
          const updatedItems = page.items.map((item) => {
            if (item._id === id) {
              return { ...item, ...updatedData }
            }
            return item
          })
          return {
            ...page,
            items: updatedItems
          }
        })
      )

      if (rowFormsRef.current[id]) {
        rowFormsRef.current[id].setFieldsValue(updatedData)
      }
    }, [])

    // Store the latest updateEventHandler in a ref
    updateEventHandlerRef.current = updateEventHandler

    const newEventHandler = useCallback(() => {
      reload()
    }, [reload])

    // Subscribe to real-time updates for all items
    useEffect(() => {
      if (pages.length > 0 && connected == true) {
        // Get all non-skeleton item IDs from all pages
        const allItemIds = pages
          .flatMap((page) => page.items || [])
          .filter((item) => !item.isSkeleton)
          .map((item) => item._id)
          .filter(Boolean)

        // Find new items that need subscription
        const newItemIds = allItemIds.filter(
          (id) => !subscribedIdsRef.current.includes(id)
        )

        // Subscribe to new items only
        newItemIds.forEach((itemId) => {
          const unsubscribe = subscribeToObjectUpdates(
            itemId,
            type,
            (updateData) => {
              updateEventHandlerRef.current(itemId, updateData)
            }
          )
          subscribedIdsRef.current.push(itemId)
          if (unsubscribe) {
            unsubscribesRef.current.push(unsubscribe)
          }
        })

        // Clean up subscriptions for items that are no longer in the pages
        const currentSubscribedIds = subscribedIdsRef.current
        const itemsToUnsubscribe = currentSubscribedIds.filter(
          (id) => !allItemIds.includes(id)
        )

        itemsToUnsubscribe.forEach((itemId) => {
          const index = subscribedIdsRef.current.indexOf(itemId)
          if (index > -1) {
            subscribedIdsRef.current.splice(index, 1)
            const unsubscribe = unsubscribesRef.current[index]
            if (unsubscribe) {
              unsubscribe()
            }
            unsubscribesRef.current.splice(index, 1)
          }
        })
      }
    }, [pages, type, subscribeToObjectUpdates, connected])

    // Cleanup effect for component unmount
    useEffect(() => {
      return () => {
        if (connected == true && unsubscribesRef.current) {
          // Clean up all subscriptions when component unmounts
          unsubscribesRef.current.forEach((unsubscribe) => {
            if (unsubscribe) unsubscribe()
          })
          unsubscribesRef.current = []
          subscribedIdsRef.current = []

          // Clean up type subscription
        }
        if (connected == true && subscribeToObjectTypeUpdatesRef.current) {
          subscribeToObjectTypeUpdatesRef.current()
          subscribeToObjectTypeUpdatesRef.current = null
        }
      }
    }, [connected])

    useEffect(() => {
      if (
        connected == true &&
        subscribeToObjectTypeUpdatesRef.current == null
      ) {
        subscribeToObjectTypeUpdatesRef.current = subscribeToObjectTypeUpdates(
          type,
          newEventHandler
        )
      }
    }, [type, subscribeToObjectTypeUpdates, connected, newEventHandler])

    const updateData = useCallback(
      (id, updatedData) => {
        updateEventHandler(id, updatedData)
      },
      [updateEventHandler]
    )

    const loadPage = useCallback(
      async (pageNum, filter = null, sorter = null) => {
        // Create initial page with skeletons
        setPages([{ pageNum: pageNum, items: createSkeletonData() }])

        const items = await fetchData(pageNum, filter, sorter)

        if (items.length >= 25) {
          setPages((prev) => {
            // Remove any existing page with the same pageNum
            const filtered = prev.filter((p) => p.pageNum !== pageNum + 1)
            return [
              ...filtered,
              { pageNum: pageNum + 1, items: createSkeletonData() }
            ]
          })
          await fetchData(pageNum + 1, filter, sorter)
        }
      },
      [createSkeletonData, fetchData]
    )

    const loadInitialPage = useCallback(async () => {
      loadPage(initialPage)
    }, [initialPage, loadPage])

    useImperativeHandle(ref, () => ({
      reload,
      setData: (newData) => {
        setPages([{ pageNum: 1, items: newData }])
      },
      updateData,
      startEditing,
      cancelEditing,
      handleUpdate,
      isEditing,
      editLoading
    }))

    useEffect(() => {
      if (
        connected == true &&
        token != null &&
        !pages.includes(initialPage) &&
        !initialized
      ) {
        loadInitialPage()
        setInitialized(true)
      }
    }, [token, loadInitialPage, initialPage, pages, initialized, connected])

    // Watch for changes in type and masterFilter, reset component state when they change
    useEffect(() => {
      const prevValues = prevValuesRef.current

      // Deep comparison for objects, simple comparison for primitives
      const hasChanged =
        prevValues.type !== type ||
        JSON.stringify(prevValues.masterFilter) !== JSON.stringify(masterFilter)

      if (hasChanged) {
        setPages([])
        activeFilterRef.current = {}
        tableSorterRef.current = {}
        setSidebarFilter({})
        setInitialized(false)
        setLoading(true)
        setLazyLoading(false)
        setHasMore(true)
        prevValuesRef.current = { type, masterFilter }
      }
    }, [type, masterFilter])

    const getFilterDropdown = ({
      setSelectedKeys,
      selectedKeys,
      confirm,
      clearFilters,
      propertyName
    }) => {
      return (
        <div style={{ padding: 8 }}>
          <Space.Compact>
            <Input
              placeholder={'Search ' + propertyName}
              value={selectedKeys[0]}
              onChange={(e) =>
                setSelectedKeys(e.target.value ? [e.target.value] : [])
              }
              onPressEnter={() => confirm()}
              style={{ width: 200, display: 'block' }}
            />
            <Button
              onClick={() => {
                clearFilters()
                confirm()
              }}
              icon={<XMarkIcon />}
            />
            <Button
              type='primary'
              onClick={() => confirm()}
              icon={<CheckIcon />}
            />
          </Space.Compact>
        </div>
      )
    }

    const getActiveFilter = useCallback((filterState) => {
      const active = {}
      Object.entries(filterState).forEach(([k, v]) => {
        if (v !== '' && v !== undefined) active[k] = v
      })
      return active
    }, [])

    const handleTableChange = (pagination, filters, sorter) => {
      const next = { ...sidebarFilter }

      Object.entries(filters).forEach(([key, value]) => {
        if (value && value.length > 0) {
          next[key] = value[0]
        } else {
          delete next[key]
        }
      })

      setSidebarFilter(next)
      setPages([])
      setLoading(true)
      loadPage(initialPage, getActiveFilter(next), {
        field: sorter.field,
        order: sorter.order
      })
    }

    const handleSidebarFilterChange = useCallback(
      (newSidebarFilter) => {
        setSidebarFilter(newSidebarFilter)
        setPages([])
        setLoading(true)
        loadPage(initialPage, getActiveFilter(newSidebarFilter))
      },
      [initialPage, loadPage, getActiveFilter]
    )

    const modelProperties = getModelProperties(type)
    // Table columns from model properties
    const columnsWithSkeleton = [
      {
        title: lazyLoading ? <LoadingOutlined /> : cards ? model.icon : null,
        key: 'icon',
        width: 45,
        fixed: 'left',
        render: () => {
          return <Flex justify='center'>{createElement(model.icon)}</Flex>
        }
      }
    ]

    useEffect(() => {
      pagesRef.current = pages
    }, [pages])

    // Flatten pages array for table display
    useEffect(() => {
      setTableData(pages.flatMap((page) => page.items))
    }, [pages])

    // Add columns in the order specified by model.columns
    model.columns.forEach((colName) => {
      const prop = modelProperties.find((p) => p.name === colName)
      if (prop) {
        // Check if column should be visible based on visibleColumns prop
        if (
          Object.keys(visibleColumns).length > 0 &&
          visibleColumns[prop.name] === false
        ) {
          return // Skip this column if it's not visible
        }

        var fixed = prop.columnFixed || undefined
        var width = 200

        switch (prop.type) {
          case 'text':
            width = 200
            break
          case 'number':
            width = 100
            break
          case 'dateTime':
            width = 200
            break
          case 'state':
            width = 200
            break
          case 'id':
            width = 180
            break
          default:
            break
        }
        // Check if this property should be filterable based on model.filters
        const isFilterable = model.filters && model.filters.includes(prop.name)

        // Check if this property should be sortable based on model.sorters
        const isSortable = model.sorters && model.sorters.includes(prop.name)

        const columnConfig = {
          sorter: isSortable ? { multiple: 1 } : undefined,
          title: prop.label,
          width: prop.columnWidth || width,
          fixed: isMobile ? undefined : fixed,
          key: prop.name,
          filterIcon: () => {
            return <FilterIcon />
          },
          render: (text, record) => {
            if (record?.isSkeleton) {
              return (
                <Skeleton.Input active size='small' style={{ width: '100%' }} />
              )
            }
            return (
              <ObjectProperty
                {...prop}
                longId={false}
                objectData={record}
                isEditing={isEditing}
              />
            )
          }
        }

        if (isFilterable && !Object.keys(masterFilter).includes(prop.name)) {
          columnConfig.filterDropdown = ({
            setSelectedKeys,
            selectedKeys,
            confirm,
            clearFilters
          }) =>
            getFilterDropdown({
              setSelectedKeys,
              selectedKeys,
              confirm,
              clearFilters,
              propertyName: prop.label
            })
          const sidebarVal = sidebarFilter[prop.name]
          columnConfig.filteredValue =
            sidebarVal !== undefined && sidebarVal !== '' ? [sidebarVal] : null
        }

        columnsWithSkeleton.push(columnConfig)
      }
    })

    if (rowActions.length > 0 && tableData.some((item) => !item?.isSkeleton)) {
      columnsWithSkeleton.push({
        title: (
          <Flex gap='small' align='center' justify='center'>
            <ActionsIcon />
          </Flex>
        ),
        key: 'actions',
        fixed: 'right',
        width: 20 + rowActions.length * 30, // Adjust width based on number of actions
        render: (record) => {
          return renderActions(record)
        }
      })
    }

    // Card view rendering
    const cardsContainerRef = useRef(null)

    // Card view scroll handler
    useEffect(() => {
      if (!cards) return
      const container = cardsContainerRef.current
      if (!container) return

      const handleCardsScroll = (e) => {
        const { scrollTop, scrollHeight, clientHeight } = e.target
        const lowestPage = Math.min(...pages.map((p) => p.pageNum))
        const prevPage = lowestPage - 1

        // Load more data when scrolling down
        if (
          scrollHeight - scrollTop - clientHeight < 100 &&
          hasMore &&
          !lazyLoading
        ) {
          setTimeout(() => {
            e.target.scrollTop = scrollHeight / 2
          }, 0)
          setLazyLoading(true)
          loadNextPage()
        }

        // Load previous data when scrolling up
        if (scrollTop < 100 && prevPage > 0 && !lazyLoading) {
          setTimeout(() => {
            e.target.scrollTop = scrollHeight / 2
          }, 0)
          setLazyLoading(true)
          loadPreviousPage()
        }
      }

      container.addEventListener('scroll', handleCardsScroll)
      return () => container.removeEventListener('scroll', handleCardsScroll)
    }, [cards, pages, hasMore, lazyLoading, loadNextPage, loadPreviousPage])

    const renderCards = () => {
      return (
        <Row
          gutter={[16, 16]}
          style={{ overflowY: 'auto', maxHeight: adjustedScrollHeight }}
          ref={cardsContainerRef}
        >
          {tableData.map((record) => (
            <Col xs={24} sm={12} md={12} lg={8} xl={6} xxl={6} key={record._id}>
              <div style={{ width: '100%', overflow: 'hidden' }}>
                <RowForm
                  record={record}
                  isEditing={isEditing}
                  onRegister={registerForm}
                >
                  <Flex align={'center'} vertical gap={'middle'}>
                    <ObjectCard
                      model={model}
                      modelProperties={modelProperties}
                      visibleColumns={visibleColumns}
                      record={record}
                      isEditing={isEditing}
                      rowActions={rowActions}
                      renderActions={renderActions}
                    />
                  </Flex>
                </RowForm>
              </div>
            </Col>
          ))}
        </Row>
      )
    }

    const components = useMemo(
      () => ({
        body: {
          row: EditableRow
        }
      }),
      []
    )

    const onRow = useCallback(
      (record) => ({
        record,
        isEditing,
        onRegister: registerForm
      }),
      [isEditing, registerForm]
    )

    const tableContent = (
      <Flex gap={'middle'} vertical style={{ flex: 1, minWidth: 0 }}>
        {cards ? (
          <Spin indicator={<LoadingOutlined />} spinning={loading}>
            {renderCards()}
          </Spin>
        ) : (
          <Table
            ref={tableRef}
            dataSource={tableData}
            columns={columnsWithSkeleton}
            className='dashboard-table'
            pagination={false}
            scroll={{ y: adjustedScrollHeight }}
            rowKey='_id'
            loading={{ spinning: loading, indicator: <LoadingOutlined spin /> }}
            onScroll={handleScroll}
            onChange={handleTableChange}
            showSorterTooltip={false}
            style={{ height: '100%' }}
            size={size}
            components={components}
            onRow={onRow}
          />
        )}
      </Flex>
    )

    if (showFilterSidebar) {
      return (
        <Flex
          gap='middle'
          align='flex-start'
          style={{ width: '100%', height: '100%' }}
        >
          {tableContent}
          <FilterSidebar
            type={type}
            filter={sidebarFilter}
            onFilterChange={handleSidebarFilterChange}
            masterFilter={masterFilter}
          />
        </Flex>
      )
    }

    return tableContent
  }
)

ObjectTable.displayName = 'ObjectTable'

ObjectTable.propTypes = {
  type: PropTypes.string.isRequired,
  pageSize: PropTypes.number,
  scrollHeight: PropTypes.string,
  onDataChange: PropTypes.func,
  initialPage: PropTypes.number,
  cards: PropTypes.bool,
  cardRenderer: PropTypes.func,
  visibleColumns: PropTypes.object,
  masterFilter: PropTypes.object,
  size: PropTypes.string,
  onStateChange: PropTypes.func,
  showFilterSidebar: PropTypes.bool
}

export default ObjectTable
