// PrinterSelect.js
import PropTypes from 'prop-types'
import { Tree, Card, Spin, Space, Button, message } from 'antd'
import { LoadingOutlined, ReloadOutlined } from '@ant-design/icons'
import React, { useState, useEffect, useContext, useCallback } from 'react'
import PrinterState from './PrinterState'
import axios from 'axios'
import { SocketContext } from '../context/SocketContext'

import SubJobState from './SubJobState'
const SubJobsTree = ({ printJobData }) => {
  const [treeData, setTreeData] = useState([])
  const [loading, setLoading] = useState(false)
  const [error, setError] = useState(null)
  const { socket } = useContext(SocketContext)
  const [messageApi] = message.useMessage()
  const [expandedKeys, setExpandedKeys] = useState([])
  const [currentPrintJobData, setCurrentPrintJobData] = useState(null)

  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 ? (
            <PrinterState
              printer={printerData}
              text={printerData.name}
              showProgress={false}
            />
          ) : (
            <Spin indicator={<LoadingOutlined />} />
          ),
          key: `printer-${printerData.id}`,
          children: printerSubJobs.map((subJob) => {
            return {
              title: (
                <SubJobState
                  subJob={subJob}
                  text={`Subjob #${subJob.number}`}
                  showProgress={true}
                />
              ),
              key: `subjob-${subJob._id}`,
              isLeaf: true
            }
          })
        }
      })

      setTreeData(printerNodes)
    },
    [expandedKeys]
  )

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

  useEffect(() => {
    const initializeData = async () => {
      if (!printJobData) {
        try {
          setLoading(true)
          const response = await axios.get('http://localhost:8080/printjobs', {
            headers: { Accept: 'application/json' },
            withCredentials: true
          })
          if (response.data) {
            setCurrentPrintJobData(response.data)
          }
        } catch (err) {
          setError('Failed to fetch print job details')
          messageApi.error('Failed to fetch print job details')
        } finally {
          setLoading(false)
        }
      } else {
        setCurrentPrintJobData(printJobData)
      }
    }

    initializeData()

    // Add socket.io event listener for deployment updates
    if (socket) {
      socket.on('notify_deployment_update', (updateData) => {
        console.log('Received deployment update:', updateData)
        setCurrentPrintJobData((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
        })
      })
      socket.on('notify_subjob_update', (updateData) => {
        // Handle sub-job updates
        if (updateData.subJobId) {
          console.log('Received subjob update:', updateData)
          setCurrentPrintJobData((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 (socket) {
        socket.off('notify_deployment_update')
      }
    }
  }, [printJobData, socket])

  if (loading) {
    return (
      <div style={{ textAlign: 'center', padding: '20px' }}>
        <Spin indicator={<LoadingOutlined style={{ fontSize: 24 }} spin />} />
      </div>
    )
  }

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

  return (
    <Card>
      <Tree
        treeData={treeData}
        expandedKeys={expandedKeys}
        onExpand={setExpandedKeys}
      />
    </Card>
  )
}

SubJobsTree.propTypes = {
  printJobData: PropTypes.object.isRequired
}

export default SubJobsTree
