// PrinterSelect.js
import PropTypes from 'prop-types'
import { Tree, Card, Spin, Space, Button, Typography } from 'antd'
import { LoadingOutlined } from '@ant-design/icons'
import { useState, useEffect, useContext, useCallback } from 'react'
import { useNavigate } from 'react-router-dom'
import { useMessageContext } from '../context/MessageContext'
import PrinterState from './PrinterState'
import axios from 'axios'
import { PrintServerContext } from '../context/PrintServerContext'
import PrinterIcon from '../../Icons/PrinterIcon'
import SubJobState from './SubJobState'
import SubJobIcon from '../../Icons/SubJobIcon'
import ReloadIcon from '../../Icons/ReloadIcon'
import IdDisplay from './IdDisplay'

const { Text } = Typography

import config from '../../../config'

const SubJobsTree = ({ jobData, loading }) => {
  const [treeData, setTreeData] = useState([])
  const [treeLoading, setTreeLoading] = useState(loading)
  const [error, setError] = useState(null)
  const { printServer } = useContext(PrintServerContext)
  const { showError } = useMessageContext()
  const [expandedKeys, setExpandedKeys] = useState([])
  const [currentJobData, setCurrentJobData] = useState(null)
  const navigate = useNavigate()

  const buildTreeData = useCallback(
    (jobData) => {
      if (!jobData?.subJobs?.length) {
        setTreeData([])
        setExpandedKeys([])
        return
      }

      // Create tree nodes for each printer
      const printerNodes = jobData.printers.map((printerData) => {
        // Find subjobs for this printer
        const printerSubJobs = jobData.subJobs.filter(
          (subJob) => subJob.printer === printerData.id
        )
        setExpandedKeys((prev) => [...prev, `printer-${printerData.id}`])
        return {
          title: printerData.state ? (
            <Space size={'small'}>
              <PrinterIcon />
              <Text>{printerData.name}</Text>
              <IdDisplay id={printerData._id} type='printer' longId={false} />
              <PrinterState state={printerData.state} showProgress={false} />
            </Space>
          ) : (
            <Spin indicator={<LoadingOutlined />} />
          ),
          key: `printer-${printerData.id}`,
          children: printerSubJobs.map((subJob) => {
            return {
              title: (
                <Space size={'small'}>
                  <SubJobIcon />
                  <Text>
                    {'Sub Job #' + subJob?.number.toString().padStart(2, '0')}
                  </Text>
                  <SubJobState state={subJob?.state} showProgress={true} />
                </Space>
              ),
              key: `subjob-${subJob._id}`,
              isLeaf: true
            }
          })
        }
      })

      setTreeData(printerNodes)
    },
    [expandedKeys]
  )

  const handleNodeClick = (selectedKeys) => {
    const key = selectedKeys[0]
    if (key.startsWith('printer-')) {
      const printerId = key.replace('printer-', '')
      navigate(`/dashboard/production/printers/info?printerId=${printerId}`)
    }
  }

  useEffect(() => {
    buildTreeData(currentJobData)
  }, [currentJobData])

  useEffect(() => {
    const initializeData = async () => {
      if (!jobData) {
        try {
          setTreeLoading(true)
          const response = await axios.get(`${config.backendUrl}/jobs`, {
            headers: { Accept: 'application/json' },
            withCredentials: true
          })
          if (response.data) {
            setCurrentJobData(response.data)
          }
        } catch (err) {
          console.error(err)
          setError('Failed to fetch print job details')
          showError('Failed to fetch print job details')
        } finally {
          setTreeLoading(false)
        }
      } else {
        setCurrentJobData(jobData)
      }
    }

    initializeData()

    // Add printServer.io event listener for deployment updates
    if (printServer) {
      printServer.on('notify_deployment_update', (updateData) => {
        setCurrentJobData((prevData) => {
          if (!prevData) return prevData

          // Handle printer updates
          if (updateData.printerId) {
            return {
              ...prevData,
              printers: prevData.printers.map((printer) => {
                if (
                  printer.id === updateData.printerId &&
                  updateData.state == 'deploying'
                ) {
                  return {
                    ...printer,
                    deploymentProgress: updateData.progress
                  }
                } else if (
                  printer.id === updateData.printerId &&
                  updateData.state == 'complete'
                ) {
                  return {
                    ...printer,
                    deploymentProgress: undefined
                  }
                }
                return printer
              })
            }
          }

          return prevData
        })
      })
      printServer.on('notify_subjob_update', (updateData) => {
        // Handle sub-job updates
        if (updateData.subJobId) {
          setCurrentJobData((prevData) => {
            if (!prevData) return prevData
            return {
              ...prevData,
              // eslint-disable-next-line camelcase
              subJobs: prevData.subJobs.map((subJob) => {
                if (subJob._id === updateData._id) {
                  return {
                    ...subJob,
                    state: updateData.state,
                    subJobId: updateData.subJobId
                  }
                }
                return subJob
              })
            }
          })
        }
      })
    }

    return () => {
      if (printServer) {
        printServer.off('notify_deployment_update')
      }
    }
  }, [jobData, printServer])

  if (error) {
    return (
      <Space
        direction='vertical'
        style={{ width: '100%', textAlign: 'center' }}
      >
        <p>{error}</p>
        <Button icon={<ReloadIcon />} onClick={() => buildTreeData(jobData)}>
          Retry
        </Button>
      </Space>
    )
  }

  return (
    <Spin indicator={<LoadingOutlined />} spinning={treeLoading}>
      <Card style={{ minHeight: 160 }}>
        <Tree
          treeData={treeData}
          expandedKeys={expandedKeys}
          onExpand={setExpandedKeys}
          onSelect={handleNodeClick}
          showLine={true}
        />
      </Card>
    </Spin>
  )
}

SubJobsTree.propTypes = {
  jobData: PropTypes.object.isRequired,
  loading: PropTypes.bool
}

export default SubJobsTree
