import { useState, useContext, useEffect, useCallback } from 'react'
import PropTypes from 'prop-types'
import WizardView from '../../common/WizardView'
import { ApiServerContext } from '../../context/ApiServerContext'
import { Descriptions, Flex, Typography } from 'antd'
import ObjectTable from '../../common/ObjectTable'
import ObjectProperty from '../../common/ObjectProperty'
const { Text } = Typography
const DeployJob = ({
  onOk,
  objectData = undefined,
  slicerIntegration = false
}) => {
  const [deployLoading, setDeployLoading] = useState(false)
  const [job, setJob] = useState(objectData)
  const [deployedSubJobsCount, setDeployedSubJobsCount] = useState(0)
  const [subJobsCount, setSubJobsCount] = useState(999)
  const [allPrintersOnline, setAllPrintersOnline] = useState(false)
  const { sendObjectAction, fetchObjects } = useContext(ApiServerContext)

  const handleDeploy = useCallback(async () => {
    setDeployLoading(true)
    var hasMore = true
    var currentPage = 1
    var subJobs = []
    while (hasMore == true) {
      const subJobsPage = await fetchObjects('subJob', {
        page: currentPage,
        filter: { 'job._id': job._id }
      })
      subJobs = [...subJobs, ...subJobsPage.data]
      if (subJobsPage.data.length >= 25) {
        currentPage = currentPage + 1
      } else {
        hasMore = false
      }
    }
    setSubJobsCount(subJobs.length)
    subJobs.forEach((subJob) => {
      sendObjectAction(
        subJob.printer._id,
        'printer',
        { type: 'deploy', data: subJob },
        () => {
          setDeployedSubJobsCount((prev) => prev + 1)
        }
      )
    })
  }, [job._id, sendObjectAction, fetchObjects])

  useEffect(() => {
    if (deployedSubJobsCount == subJobsCount && deployLoading == true) {
      onOk()
    }
  }, [deployedSubJobsCount, subJobsCount, deployLoading, onOk])

  useEffect(() => {
    if (objectData?.printers) {
      if (objectData.printers.every((printer) => printer.online)) {
        setAllPrintersOnline(true)
      } else {
        setAllPrintersOnline(false)
      }
    } else {
      setAllPrintersOnline(false)
    }
  }, [objectData])

  const steps = [
    {
      title: 'Confirm',
      key: 'confirm',
      content: (
        <Flex vertical gap={'middle'} style={{ width: '100%' }}>
          <Flex gap={'middle'} align='center' style={{ width: '100%' }}>
            <Descriptions
              column={1}
              items={[
                {
                  label: (
                    <Flex
                      align='center'
                      gap={'small'}
                      style={{ height: '100%' }}
                    >
                      <Text type='secondary'>Job</Text>
                    </Flex>
                  ),
                  children: (
                    <div
                      style={{
                        flexGrow: 1,
                        marginLeft: '3px',
                        marginBottom: '1px'
                      }}
                    >
                      <ObjectProperty
                        type={'object'}
                        name={'job'}
                        objectData={{ job: objectData }}
                        value={(object) => object.job}
                        readOnly={true}
                        isEditing={true}
                        objectType={'job'}
                        onChange={(newJob) => {
                          setJob(newJob)
                        }}
                      />
                    </div>
                  )
                },
                {
                  label: (
                    <Flex
                      align='center'
                      gap={'small'}
                      style={{ height: '100%' }}
                    >
                      <Text type='secondary'>Printers</Text>
                    </Flex>
                  ),
                  children: (
                    <div
                      style={{
                        flexGrow: 1,
                        marginLeft: '3px',
                        marginBottom: '1px'
                      }}
                    >
                      <ObjectProperty
                        type={'objectList'}
                        name={'printers'}
                        objectData={{ printers: objectData.printers }}
                        value={(object) => object.printers}
                        readOnly={true}
                        isEditing={true}
                        objectType={'printer'}
                      />
                    </div>
                  )
                }
              ]}
            />
          </Flex>

          <ObjectTable
            type={'subJob'}
            scrollHeight={'200px'}
            visibleColumns={{
              printer: false,
              job: false
            }}
            masterFilter={{ 'job._id': job?._id }}
            size={'small'}
            showActions={!slicerIntegration}
          />
        </Flex>
      )
    }
  ]

  return (
    <WizardView
      steps={steps}
      loading={deployLoading}
      formValid={objectData != undefined && allPrintersOnline}
      title='Deploy Job'
      showSteps={false}
      showSkipButton={slicerIntegration}
      onSkip={() => {
        onOk()
      }}
      submitText='Deploy'
      progress={(deployedSubJobsCount / subJobsCount) * 100}
      onSubmit={() => {
        handleDeploy()
      }}
    />
  )
}

DeployJob.propTypes = {
  onOk: PropTypes.func.isRequired,
  objectData: PropTypes.object,
  reset: PropTypes.bool,
  slicerIntegration: PropTypes.bool
}

export default DeployJob
