import { useMemo, useState } from 'react'
import PropTypes from 'prop-types'
import NewGCodeFile from '../GCodeFiles/NewGCodeFile.jsx'
import NewJob from '../Jobs/NewJob.jsx'
import DeployJob from '../Jobs/DeployJob.jsx'
import WizardView from '../../common/WizardView.jsx'

const SlicerUploadFlow = ({
  currentPendingSlicerUpload,
  printer,
  onGCodeFileCreated,
  onJobCreated,
  onComplete
}) => {
  const [createdGCodeFile, setCreatedGCodeFile] = useState(
    () => currentPendingSlicerUpload.gcodeFile || null
  )
  const [createdJob, setCreatedJob] = useState(
    () => currentPendingSlicerUpload.job || null
  )
  const [currentSubStep, setCurrentSubStep] = useState(0)

  const gcodeFileDefaults = useMemo(
    () => ({
      ...(currentPendingSlicerUpload?.properties || {}),
      file: currentPendingSlicerUpload?.file
    }),
    [currentPendingSlicerUpload]
  )

  const jobDefaults = useMemo(
    () => ({
      quantity: 1,
      gcodeFile: createdGCodeFile,
      printers: [printer]
    }),
    [createdGCodeFile, printer]
  )

  const steps = [
    {
      title: 'GCode File',
      key: 'gcodeFile',
      subSteps: [
        {
          title: 'Required',
          key: 'required'
        },
        {
          title: 'Summary',
          key: 'summary'
        }
      ],
      content: (
        <NewGCodeFile
          defaultValues={gcodeFileDefaults}
          slicerIntegration={true}
          shouldPrint={currentPendingSlicerUpload.shouldPrint}
          currentStep={currentSubStep}
          onStepChange={setCurrentSubStep}
          onOk={(gcodeFile) => {
            if (currentPendingSlicerUpload.shouldPrint) {
              setCurrentSubStep(0)
              setCreatedGCodeFile(gcodeFile)
              onGCodeFileCreated(gcodeFile)
            } else {
              onComplete({ gcodeFile })
            }
          }}
        />
      )
    }
  ]

  if (currentPendingSlicerUpload.shouldPrint) {
    steps.push({
      title: 'Print Job',
      key: 'job',
      subSteps: [
        {
          title: 'Required',
          key: 'required'
        },
        {
          title: 'Summary',
          key: 'summary'
        }
      ],
      content: createdGCodeFile ? (
        <NewJob
          slicerIntegration={true}
          defaultValues={jobDefaults}
          currentStep={currentSubStep}
          onStepChange={setCurrentSubStep}
          onOk={(job) => {
            if (job == null || job == undefined) {
              onComplete({ gcodeFile: createdGCodeFile })
            } else {
              setCurrentSubStep(0)
              setCreatedJob(job)
              onJobCreated(job)
            }
          }}
        />
      ) : null
    })

    steps.push({
      title: 'Deploy',
      key: 'deploy',
      content: createdJob ? (
        <DeployJob
          objectData={createdJob}
          slicerIntegration={true}
          onOk={() =>
            onComplete({ gcodeFile: createdGCodeFile, job: createdJob })
          }
        />
      ) : null
    })
  }

  return (
    <WizardView
      title='Slicer Upload'
      steps={steps}
      currentStep={createdJob ? 2 : createdGCodeFile ? 1 : 0}
      currentSubStep={currentSubStep}
      showButtons={false}
      showTitle={false}
      showSteps={currentPendingSlicerUpload.shouldPrint}
      formValid={true}
      onSubmit={() => {}}
    />
  )
}

SlicerUploadFlow.propTypes = {
  currentPendingSlicerUpload: PropTypes.shape({
    file: PropTypes.oneOfType([PropTypes.string, PropTypes.object]).isRequired,
    gcodeFile: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    job: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
    shouldPrint: PropTypes.bool.isRequired,
    properties: PropTypes.object
  }).isRequired,
  printer: PropTypes.object.isRequired,
  onGCodeFileCreated: PropTypes.func.isRequired,
  onJobCreated: PropTypes.func.isRequired,
  onComplete: PropTypes.func.isRequired
}

export default SlicerUploadFlow
