import PropTypes from 'prop-types'
import { ApiServerContext } from '../context/ApiServerContext'
import { useCallback, useContext, useEffect, useState, memo } from 'react'
import LoadingPlaceholder from './LoadingPlaceholder'
import GCodePreview from './GCodePreview'
import ThreeDPreview from './ThreeDPreview'
import { AuthContext } from '../context/AuthContext'

const FilePreview = ({ file, style = {} }) => {
  const { token } = useContext(AuthContext)
  const { fetchFileContent } = useContext(ApiServerContext)

  const [fileObjectUrl, setFileObjectUrl] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)

  const fetchPreview = useCallback(async () => {
    if (error != null) {
      return
    }
    setLoading(true)
    const objectUrl = await fetchFileContent(file, false)
    if (objectUrl == null) {
      setLoading(false)
      console.error('Failed to fetch file content', file)
      setError('Failed to fetch file content')
      return
    }
    setFileObjectUrl(objectUrl)
    setLoading(false)
  }, [file, fetchFileContent, error])

  useEffect(() => {
    if (file?.type && token != null) {
      fetchPreview()
    }
  }, [file._id, file?.type, fetchPreview, token])

  if (loading == true || !file?.type) {
    return <LoadingPlaceholder message={'Loading file preview...'} />
  }

  if (error != null) {
    return <div style={{ color: 'red' }}>{error}</div>
  }

  const isGcode =
    ['.g', '.gcode'].includes((file?.extension || '').toLowerCase()) || false

  const is3DModel =
    ['.stl', '.3mf'].includes((file?.extension || '').toLowerCase()) || false

  const isImage = file?.type.startsWith('image/')

  if (isGcode && fileObjectUrl) {
    return (
      <GCodePreview
        src={fileObjectUrl}
        topLayerColor={'#ff9800'}
        lastSegmentColor={'#e91e63'}
        startLayer={0}
        endLayer={undefined}
        lineWidth={1}
        style={style}
      />
    )
  }

  if (is3DModel && fileObjectUrl) {
    return (
      <ThreeDPreview
        src={fileObjectUrl}
        style={style}
        extension={file.extension}
      />
    )
  }

  if (isImage && fileObjectUrl) {
    return <img src={fileObjectUrl} style={style}></img>
  }
  return null
}

FilePreview.propTypes = {
  file: PropTypes.object.isRequired,
  style: PropTypes.object
}

// Custom comparison function to only re-render when file._id changes
const areEqual = (prevProps, nextProps) => {
  return (
    prevProps.file?._id === nextProps.file?._id &&
    JSON.stringify(prevProps.style) === JSON.stringify(nextProps.style)
  )
}

export default memo(FilePreview, areEqual)
