// PrinterTemperaturePanel.js
import { useContext, useState, useEffect } from 'react'
import {
  Progress,
  Typography,
  Spin,
  Flex,
  Space,
  Collapse,
  InputNumber,
  Button,
  Divider
} from 'antd'
import { LoadingOutlined, CaretRightOutlined } from '@ant-design/icons'
import styled from 'styled-components'
import PropTypes from 'prop-types'
import { ApiServerContext } from '../context/ApiServerContext'
import merge from 'lodash/merge'

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 = ({
  id,
  showExtruderControls = true,
  showBedControls = true,
  showExtruder = true,
  showBed = true,
  showMoreInfo = true,
  disabled = false,
  offline = true
}) => {
  const [temperatureData, setTemperatureData] = useState({
    extruder: {
      current: 0,
      target: 0,
      power: 0
    },
    bed: {
      current: 0,
      target: 0,
      power: 0
    },
    pinda: 0,
    ambiant: 0
  })

  useEffect(() => {
    if (offline) {
      setTemperatureData({
        extruder: { current: 0, target: 0, power: 0 },
        bed: { current: 0, target: 0, power: 0 },
        pinda: 0,
        ambiant: 0
      })
    }
  }, [offline])

  const { subscribeToObjectEvent, connected, sendObjectAction } =
    useContext(ApiServerContext)
  const controlsDisabled = disabled || !connected
  // Sync input values with actual temperature targets
  useEffect(() => {
    if (temperatureData.extruder?.target !== undefined) {
      setExtruderTarget(temperatureData.extruder.target)
    }
  }, [temperatureData.extruder?.target])

  useEffect(() => {
    if (temperatureData.bed?.target !== undefined) {
      setBedTarget(temperatureData.bed.target)
    }
  }, [temperatureData.bed?.target])

  useEffect(() => {
    if (id && connected == true && offline == false) {
      const temperatureEventUnsubscribe = subscribeToObjectEvent(
        id?.toLowerCase(),
        'printer',
        'temperature',
        (event) => {
          setTemperatureData((prev) => {
            const merged = merge({}, prev, event.data)
            return merged
          })
        }
      )
      return () => {
        if (temperatureEventUnsubscribe) temperatureEventUnsubscribe()
      }
    }
  }, [id, connected, subscribeToObjectEvent, offline])

  const [extruderTarget, setExtruderTarget] = useState(0)
  const [bedTarget, setBedTarget] = useState(0)

  const handleSetTemperature = async (data) => {
    if (id && connected == true) {
      await sendObjectAction(
        id,
        'printer',
        {
          type: 'setTemperature',
          data
        },
        () => {}
      )
    }
  }

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

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

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

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

PrinterTemperaturePanel.propTypes = {
  id: PropTypes.string.isRequired,
  showExtruderControls: PropTypes.bool,
  showBedControls: PropTypes.bool,
  showExtruder: PropTypes.bool,
  showBed: PropTypes.bool,
  showMoreInfo: PropTypes.bool,
  shouldUnsubscribe: PropTypes.bool,
  disabled: PropTypes.bool,
  offline: PropTypes.bool
}

export default PrinterTemperaturePanel
