import PropTypes from 'prop-types'
import { Typography, Flex, Badge } from 'antd'
import { useState, useEffect, useContext, useCallback } from 'react'
import { getModelByName } from '../../../database/ObjectModels'
import { ApiServerContext } from '../context/ApiServerContext'
import { AuthContext } from '../context/AuthContext'
import merge from 'lodash/merge'
import IdDisplay from './IdDisplay'

const { Text } = Typography

const ObjectDisplay = ({ object, objectType }) => {
  const [objectData, setObjectData] = useState(object)
  const { subscribeToObjectUpdates, connected } = useContext(ApiServerContext)
  const { token } = useContext(AuthContext)

  // Update event handler
  const updateObjectEventHandler = useCallback((value) => {
    setObjectData((prev) => merge({}, prev, value))
  }, [])

  // Subscribe to object updates when component mounts
  useEffect(() => {
    if (object?._id && objectType && connected && token) {
      const objectUpdatesUnsubscribe = subscribeToObjectUpdates(
        object._id,
        objectType,
        updateObjectEventHandler
      )

      return () => {
        if (objectUpdatesUnsubscribe) objectUpdatesUnsubscribe()
      }
    }
  }, [
    object?._id,
    objectType,
    subscribeToObjectUpdates,
    connected,
    token,
    updateObjectEventHandler
  ])

  // Update local state when object prop changes
  useEffect(() => {
    setObjectData(object)
  }, [object])

  if (!objectData) {
    return <Text type='secondary'>n/a</Text>
  }

  const model = getModelByName(objectType)
  const Icon = model.icon
  return (
    <Flex gap={'small'} align='center'>
      <Icon />
      {objectData?.color ? <Badge color={objectData?.color} /> : null}
      {objectData?.name ? <Text ellipsis>{objectData.name}</Text> : null}
      {objectData?._id && !objectData?.name ? (
        <IdDisplay
          id={objectData?._id}
          type={objectType}
          longId={false}
          showCopy={false}
        />
      ) : null}
    </Flex>
  )
}

ObjectDisplay.propTypes = {
  object: PropTypes.object,
  objectType: PropTypes.string,
  style: PropTypes.object
}

export default ObjectDisplay
