// PrinterTemperaturePanel.js
import React, { useContext, useState, useEffect, useCallback } from 'react'
import {
  Progress,
  Typography,
  Spin,
  Flex,
  Space,
  Collapse,
  InputNumber,
  Button
} from 'antd'
import { LoadingOutlined, CaretLeftOutlined } from '@ant-design/icons'
import { PrintServerContext } from '../context/PrintServerContext'
import styled from 'styled-components'
import PropTypes from 'prop-types'

const { Text } = Typography
const { Panel } = Collapse

const CustomCollapse = styled(Collapse)`
  .ant-collapse-header {
    padding: 0 !important;
  }
  .ant-collapse-content-box {
    padding-left: 0 !important;
    padding-right: 0 !important;
    padding-bottom: 0 !important;
  }
`

const PrinterTemperaturePanel = ({
  printerId,
  showHotEndControls = true,
  showHeatedBedControls = true,
  showHotEnd = true,
  showHeatedBed = true,
  showMoreInfo = true,
  shouldUnsubscribe = true
}) => {
  const [temperatureData, setTemperatureData] = useState({
    hotEnd: {},
    heatedBed: {}
  })

  // const [loading, setLoading] = React.useState(false)
  const [hotEndTemperature, setHotEndTemperature] = useState(
    temperatureData?.hotEnd?.target || 0
  )
  const [heatedBedTemperature, setHeatedBedTemperature] = useState(
    temperatureData?.heatedBed?.target || 0
  )
  const { printServer } = useContext(PrintServerContext)

  const notifyTemperatureStatusUpdate = useCallback((statusUpdate) => {
    setTemperatureData((prev) => {
      const temperatureObject = {
        ...prev
      }
      if (statusUpdate?.extruder?.temperature !== undefined) {
        temperatureObject.hotEnd.current = statusUpdate?.extruder?.temperature
      }

      if (statusUpdate?.heater_bed?.temperature !== undefined) {
        temperatureObject.heatedBed.current =
          statusUpdate?.heater_bed?.temperature
      }

      if (statusUpdate?.extruder?.target !== undefined) {
        temperatureObject.hotEnd.target = statusUpdate?.extruder?.target
        setHotEndTemperature(statusUpdate?.extruder?.target)
      }

      if (statusUpdate?.heater_bed?.target !== undefined) {
        temperatureObject.heatedBed.target = statusUpdate?.heater_bed?.target
        setHeatedBedTemperature(statusUpdate?.heater_bed?.target)
      }

      if (statusUpdate?.extruder?.power !== undefined) {
        temperatureObject.hotEnd.power = statusUpdate?.extruder?.power
      }

      if (statusUpdate?.heater_bed?.power !== undefined) {
        temperatureObject.heatedBed.power = statusUpdate?.heater_bed?.power
      }

      return temperatureObject
    })
  }, [])

  useEffect(() => {
    const params = {
      printerId,
      objects: {
        extruder: null,
        heater_bed: null // eslint-disable-line
      }
    }
    if (printServer?.connected == true) {
      printServer.emit('printer.objects.subscribe', params)
      printServer.emit('printer.objects.query', params)
      printServer.on('notify_status_update', notifyTemperatureStatusUpdate)
    }
    return () => {
      if (printServer && shouldUnsubscribe == true) {
        printServer.off('notify_status_update', notifyTemperatureStatusUpdate)
        printServer.emit('printer.objects.unsubscribe', params)
      }
    }
  }, [printServer, printerId, notifyTemperatureStatusUpdate, shouldUnsubscribe])

  const handleSetTemperatureClick = (target, value) => {
    if (printServer) {
      printServer.emit('printer.gcode.script', {
        printerId,
        script: `SET_HEATER_TEMPERATURE HEATER=${target} TARGET=${value}`
      })
    }
  }

  const moreInfoItems = [
    {
      key: '1',
      label: 'More Temperature Data',
      children: (
        <>
          <Flex vertical gap={0}>
            <Text>
              Hot End Power:{' '}
              {Math.round((temperatureData.hotEnd.power || 0) * 100)}%
            </Text>
            <Progress
              percent={(temperatureData.hotEnd.power || 0) * 100}
              showInfo={false}
            />
          </Flex>
          <Flex vertical gap={0}>
            <Text>
              Bed Power:{' '}
              {Math.round((temperatureData.heatedBed.power || 0) * 100)}%
            </Text>
            <Progress
              percent={(temperatureData.heatedBed.power || 0) * 100}
              showInfo={false}
            />
          </Flex>
          <Panel>
            {typeof temperatureData.pindaTemp !== 'undefined' && (
              <Flex vertical gap={0}>
                <Text>Pinda Temp: {temperatureData.pindaTemp}°C</Text>
              </Flex>
            )}

            {typeof temperatureData.ambiantActual !== 'undefined' && (
              <Flex vertical gap={0}>
                <Text>Ambient Actual: {temperatureData.ambiantActual}°C</Text>
              </Flex>
            )}
          </Panel>
        </>
      )
    }
  ]

  return (
    <div style={{ minWidth: 190 }}>
      {temperatureData ? (
        <Flex vertical gap='middle'>
          {temperatureData.hotEnd && showHotEnd && (
            <Flex vertical gap={0}>
              <Text>
                Hot End: {temperatureData.hotEnd.current}°C /{' '}
                {temperatureData.hotEnd.target}°C
              </Text>
              <Progress
                percent={(temperatureData.hotEnd.target / 300) * 100}
                strokeColor='#FF392F1D'
                success={{
                  percent: (temperatureData.hotEnd.current / 300) * 100,
                  strokeColor: '#FF3B2F'
                }}
                showInfo={false}
              />
              {showHotEndControls && (
                <Space direction='horizontal' style={{ marginTop: 5 }}>
                  <Space.Compact block size='small'>
                    <InputNumber
                      value={hotEndTemperature}
                      min={0}
                      max={300}
                      style={{ width: '120px' }}
                      addonAfter='°C'
                      onChange={(value) => setHotEndTemperature(value)}
                      onPressEnter={() =>
                        handleSetTemperatureClick('extruder', hotEndTemperature)
                      }
                    />
                    <Button
                      type='default'
                      style={{ width: 40 }}
                      onClick={() =>
                        handleSetTemperatureClick('extruder', hotEndTemperature)
                      }
                    >
                      Set
                    </Button>
                  </Space.Compact>
                  <Button
                    type='default'
                    size='small'
                    style={{ width: 40 }}
                    onClick={() => handleSetTemperatureClick('extruder', 0)}
                  >
                    Off
                  </Button>
                </Space>
              )}
            </Flex>
          )}

          {temperatureData.heatedBed && showHeatedBed && (
            <Flex vertical gap={0}>
              <Text>
                Heated Bed: {temperatureData.heatedBed.current}°C /{' '}
                {temperatureData.heatedBed.target}°C
              </Text>
              <Progress
                percent={(temperatureData.heatedBed.target / 300) * 100}
                strokeColor='#FF392F1D'
                success={{
                  percent: (temperatureData.heatedBed.current / 300) * 100,
                  strokeColor: '#FF3B2F'
                }}
                showInfo={false}
              />
              {showHeatedBedControls && (
                <Space
                  direction='horizontal'
                  style={{ marginTop: 5, height: '21px' }}
                >
                  <Space.Compact block size='small'>
                    <InputNumber
                      value={heatedBedTemperature}
                      min={0}
                      max={300}
                      style={{ width: '120px' }}
                      addonAfter='°C'
                      onChange={(value) => setHeatedBedTemperature(value)}
                      onPressEnter={() =>
                        handleSetTemperatureClick(
                          'heater_bed',
                          heatedBedTemperature
                        )
                      }
                    />
                    <Button
                      type='default'
                      style={{ width: 40 }}
                      onClick={() =>
                        handleSetTemperatureClick(
                          'heater_bed',
                          heatedBedTemperature
                        )
                      }
                    >
                      Set
                    </Button>
                  </Space.Compact>
                  <Button
                    type='default'
                    size='small'
                    style={{ width: 40 }}
                    onClick={() => handleSetTemperatureClick('heater_bed', 0)}
                  >
                    Off
                  </Button>
                </Space>
              )}
            </Flex>
          )}
          {showMoreInfo === true && (
            <CustomCollapse
              ghost
              size='small'
              items={moreInfoItems}
              expandIcon={({ isActive }) => (
                <CaretLeftOutlined rotate={isActive ? 90 : 0} />
              )}
            />
          )}
        </Flex>
      ) : (
        <Flex justify='centre'>
          <Spin indicator={<LoadingOutlined spin />} size='large' />
        </Flex>
      )}
    </div>
  )
}

PrinterTemperaturePanel.propTypes = {
  printerId: PropTypes.string.isRequired,
  showHotEndControls: PropTypes.bool,
  showHeatedBedControls: PropTypes.bool,
  showHotEnd: PropTypes.bool,
  showHeatedBed: PropTypes.bool,
  showMoreInfo: PropTypes.bool,
  shouldUnsubscribe: PropTypes.bool
}

export default PrinterTemperaturePanel
