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

function GCodePreviewUI(props) {
  const {
    src,
    topLayerColor = '',
    lastSegmentColor = '',
    startLayer,
    endLayer,
    lineWidth,
    style = {}
  } = props
  const canvasRef = useRef(null)
  const previewRef = useRef(null)

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

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

  useEffect(() => {
    if (!canvasRef.current) return

    previewRef.current?.dispose?.()
    previewRef.current = 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)
      previewRef.current?.dispose?.()
      previewRef.current = null
    }
  }, [
    endLayer,
    lastSegmentColor,
    lineWidth,
    startLayer,
    topLayerColor,
    resizePreview
  ])

  useEffect(() => {
    let cancelled = false

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

    return () => {
      cancelled = true
    }
  }, [endLayer, lastSegmentColor, lineWidth, src, startLayer, topLayerColor])

  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
