// src/contexts/PrintServerContext.js
import React, {
  createContext,
  useEffect,
  useState,
  useContext,
  useRef
} from 'react'
import io from 'socket.io-client'
import { message, notification } from 'antd'
import PropTypes from 'prop-types'
import { AuthContext } from './AuthContext'
import config from '../../../config'
import loglevel from 'loglevel'
const log = loglevel.getLogger('Print Server')
log.setLevel(config.logLevel)

const PrintServerContext = createContext()

const PrintServerProvider = ({ children }) => {
  const { token } = useContext(AuthContext)
  const socketRef = useRef(null)
  const [connecting, setConnecting] = useState(false)
  const [error, setError] = useState(null)
  const [messageApi, contextHolder] = message.useMessage()
  const [notificationApi] = notification.useNotification()

  useEffect(() => {
    if (token) {
      log.debug('Token is available, connecting to print server...')

      const newSocket = io(config.printServerUrl, {
        reconnectionAttempts: 3,
        timeout: 3000,
        auth: { token: token }
      })

      setConnecting(true)

      newSocket.on('connect', () => {
        log.debug('Print server connected')
        setConnecting(false)
        setError(null)
      })

      newSocket.on('disconnect', () => {
        log.debug('Print server disconnected')
        setError('Print server disconnected')
      })

      newSocket.on('connect_error', (err) => {
        log.error('Print server connection error:', err)
        messageApi.error('Print server connection error: ' + err.message)
        setError('Print server connection error')
      })

      newSocket.on('bridge.notification', (data) => {
        notificationApi[data.type]({
          title: data.title,
          message: data.message
        })
      })

      newSocket.on('error', (err) => {
        log.error('Print server error:', err)
        setError('Print server error')
      })

      socketRef.current = newSocket

      // Clean up function
      return () => {
        if (socketRef.current) {
          log.debug('Cleaning up socket connection...')
          socketRef.current.disconnect()
          socketRef.current = null
        }
      }
    } else if (!token && socketRef.current) {
      log.debug('Token not available, disconnecting socket...')
      socketRef.current.disconnect()
      socketRef.current = null
    }
  }, [token, messageApi])

  return (
    <PrintServerContext.Provider
      value={{ printServer: socketRef.current, error, connecting }}
    >
      {contextHolder}
      {children}
    </PrintServerContext.Provider>
  )
}

PrintServerProvider.propTypes = {
  children: PropTypes.node.isRequired
}

export { PrintServerContext, PrintServerProvider }
