import * as GCodePreview from 'gcode-preview'
import PropTypes from 'prop-types'
import { useCallback, useEffect, useRef, useState } from 'react'
import * as THREE from 'three'

function GCodePreviewUI(props) {
  const {
    src,
    topLayerColor = '',
    lastSegmentColor = '',
    startLayer,
    endLayer,
    lineWidth,
    style = {}
  } = props
  const canvasRef = useRef(null)
  const [preview, setPreview] = useState()

  const resizePreview = useCallback(() => {
    preview?.resize()
  }, [preview])

  // Ex-ref methods removed; this component is now a regular functional component

  useEffect(() => {
    setPreview(
      GCodePreview.init({
        canvas: canvasRef.current,
        startLayer,
        endLayer,
        lineWidth,
        topLayerColor: new THREE.Color(topLayerColor).getHex(),
        lastSegmentColor: new THREE.Color(lastSegmentColor).getHex(),
        buildVolume: { x: 250, y: 220, z: 150 },
        initialCameraPosition: [0, 400, 450],
        allowDragNDrop: false
      })
    )

    window.addEventListener('resize', resizePreview)

    return () => {
      window.removeEventListener('resize', resizePreview)
    }
  }, [
    endLayer,
    lastSegmentColor,
    lineWidth,
    startLayer,
    topLayerColor,
    resizePreview
  ])

  useEffect(() => {
    const loadFromSrc = async () => {
      if (!src || !preview) return
      try {
        const response = await fetch(src)
        const text = await response.text()
        preview.processGCode(text)
      } catch (e) {
        console.error('Failed to load G-code from src', e)
      }
    }
    loadFromSrc()
  }, [src, preview])

  return <canvas ref={canvasRef} style={style}></canvas>
}

GCodePreviewUI.propTypes = {
  src: PropTypes.string,
  topLayerColor: PropTypes.string,
  lastSegmentColor: PropTypes.string,
  startLayer: PropTypes.number,
  endLayer: PropTypes.number,
  lineWidth: PropTypes.number,
  style: PropTypes.object
}

export default GCodePreviewUI
