import { useContext, useState, useEffect } from 'react'
import { Typography, Spin, Flex, Space, Slider, Descriptions, Tag } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import { PrintServerContext } from '../context/PrintServerContext'
import PropTypes from 'prop-types'

const { Text } = Typography

const PrinterMiscPanel = ({
  printerId,
  showControls = true,
  shouldUnsubscribe = true
}) => {
  const [miscData, setMiscData] = useState({
    fan: {
      speed: 0,
      target: 0
    },
    ledBacklight: {
      // eslint-disable-line camelcase
      brightness: 0
    },
    beeper: {
      value: 0
    },
    filamentSensor: {
      enabled: false,
      filamentDetected: false
    },
    heaterFan: {
      speed: 0
    }
  })

  const [initialized, setInitialized] = useState(false)
  const { printServer } = useContext(PrintServerContext)
  const [fanSpeed, setFanSpeed] = useState(0)
  const [ledBrightness, setLedBrightness] = useState(0)
  const [beeperValue, setBeeperValue] = useState(0)
  useEffect(() => {
    const params = {
      printerId,
      objects: {
        fan: null,
        'filament_switch_sensor fsensor': null,
        'output_pin BEEPER_pin': null,
        'output_pin LCD_backlight_pin': null,
        'heater_fan nozzle_cooling_fan': null
      }
    }

    const notifyMiscStatusUpdate = (statusUpdate) => {
      if (statusUpdate?.fan) {
        setMiscData((prevData) => ({
          ...prevData,
          fan: statusUpdate.fan
        }))
        setFanSpeed(statusUpdate.fan.speed)
      }
      if (statusUpdate?.['heater_fan nozzle_cooling_fan']) {
        setMiscData((prevData) => ({
          ...prevData,
          heaterFan: statusUpdate['heater_fan nozzle_cooling_fan']
        }))
      }
      if (statusUpdate?.['output_pin LCD_backlight_pin']) {
        setMiscData((prevData) => ({
          ...prevData,
          ledBacklight: statusUpdate['output_pin LCD_backlight_pin'].value
        }))
        setLedBrightness(statusUpdate['output_pin LCD_backlight_pin'].value)
      }
      if (statusUpdate?.['output_pin BEEPER_pin']) {
        setMiscData((prevData) => ({
          ...prevData,
          beeper: statusUpdate['output_pin BEEPER_pin']
        }))
        setBeeperValue(statusUpdate['output_pin BEEPER_pin'].value)
      }
      if (statusUpdate?.['filament_switch_sensor fsensor']) {
        setMiscData((prevData) => ({
          ...prevData,
          filamentSensor: {
            enabled: statusUpdate['filament_switch_sensor fsensor'].enabled,
            filamentDetected:
              statusUpdate['filament_switch_sensor fsensor'].filament_detected
          }
        }))
      }
    }

    if (!initialized && printServer.connected) {
      setInitialized(true)

      printServer.on('connect', () => {
        printServer.emit('printer.objects.subscribe', params)
        printServer.emit('printer.objects.query', params)
      })

      printServer.emit('printer.objects.subscribe', params)
      printServer.emit('printer.objects.query', params)
      printServer.on('notify_status_update', notifyMiscStatusUpdate)
    }

    return () => {
      if (printServer.connected && initialized && shouldUnsubscribe) {
        printServer.off('notify_status_update', notifyMiscStatusUpdate)
        printServer.emit('printer.objects.unsubscribe', params)
      }
    }
  }, [printServer, initialized, printerId, shouldUnsubscribe])

  const handleSetFanSpeed = (value) => {
    if (printServer) {
      printServer.emit('printer.gcode.script', {
        printerId,
        script: `M106 S${Math.round(value * 255)}`
      })
    }
  }

  const handleSetLedBrightness = (value) => {
    if (printServer) {
      printServer.emit('printer.gcode.script', {
        printerId,
        script: `SET_LED LED=led_backlight BRIGHTNESS=${value}`
      })
    }
  }

  const handleSetBeeperValue = (value) => {
    if (printServer) {
      printServer.emit('printer.gcode.script', {
        printerId,
        script: `M300 S440 P200 V${Math.round(value * 100)}`
      })
    }
  }

  return (
    <div style={{ minWidth: 190 }}>
      {miscData ? (
        <Flex vertical gap='middle'>
          <Flex vertical gap={'middle'}>
            {showControls && (
              <>
                <Space direction='vertical' style={{ width: '100%' }}>
                  <Text>Fan Speed: {Math.round(fanSpeed * 100)}%</Text>
                  <Slider
                    value={fanSpeed}
                    min={0}
                    max={1}
                    step={0.01}
                    onChange={setFanSpeed}
                    onAfterChange={handleSetFanSpeed}
                    tooltip={{ open: false }}
                  />

                  <Text>LED Backlight: {Math.round(ledBrightness * 100)}%</Text>
                  <Slider
                    value={ledBrightness}
                    min={0}
                    max={1}
                    step={0.01}
                    onChange={setLedBrightness}
                    onAfterChange={handleSetLedBrightness}
                    tooltip={{ open: false }}
                  />

                  <Text>Beeper Pitch: {Math.round(beeperValue * 100)}%</Text>
                  <Slider
                    value={beeperValue}
                    min={0}
                    max={1}
                    step={0.01}
                    onChange={setBeeperValue}
                    onAfterChange={handleSetBeeperValue}
                    tooltip={{ open: false }}
                  />
                </Space>
              </>
            )}

            <Descriptions column={1} size='small' bordered>
              <Descriptions.Item label='Filament Sensor'>
                {miscData.filamentSensor.enabled ? (
                  miscData.filamentSensor.filamentDetected ? (
                    <Tag color='green'>Detected</Tag>
                  ) : (
                    <Tag color='red'>Open</Tag>
                  )
                ) : (
                  <Tag color='default'>Disabled</Tag>
                )}
              </Descriptions.Item>
              <Descriptions.Item label='Part Cooling Fan'>
                {miscData.fan.speed > 0 ? (
                  <Text>Running ({Math.round(miscData.fan.speed * 100)}%)</Text>
                ) : (
                  <Text>Off</Text>
                )}
              </Descriptions.Item>
              <Descriptions.Item label='Nozzle Cooling Fan'>
                {miscData.heaterFan.speed > 0 ? (
                  <Text>
                    Running ({Math.round(miscData.heaterFan.speed * 100)}%)
                  </Text>
                ) : (
                  <Text>Off</Text>
                )}
              </Descriptions.Item>
            </Descriptions>
          </Flex>
        </Flex>
      ) : (
        <Flex justify='centre'>
          <Spin indicator={<LoadingOutlined spin />} size='large' />
        </Flex>
      )}
    </div>
  )
}

PrinterMiscPanel.propTypes = {
  printerId: PropTypes.string.isRequired,
  showControls: PropTypes.bool,
  shouldUnsubscribe: PropTypes.bool
}

export default PrinterMiscPanel
