import React, { useState, useEffect, useContext } from 'react'
import { useLocation } from 'react-router-dom'
import axios from 'axios'
import {
  Descriptions,
  Spin,
  Space,
  Button,
  message,
  Progress,
  Typography,
  Collapse
} from 'antd'
import { LoadingOutlined, CaretRightOutlined } from '@ant-design/icons'
import TimeDisplay from '../../common/TimeDisplay'
import JobState from '../../common/JobState'
import IdText from '../../common/IdText'
import SubJobsTree from '../../common/SubJobsTree'
import { SocketContext } from '../../context/SocketContext'
import GCodeFileIcon from '../../../Icons/GCodeFileIcon'
import ReloadIcon from '../../../Icons/ReloadIcon'
import useCollapseState from '../../hooks/useCollapseState'
import config from '../../../../config'

const { Title } = Typography

const PrintJobInfo = () => {
  const [printJobData, setPrintJobData] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)
  const location = useLocation()
  const [messageApi] = message.useMessage()
  const printJobId = new URLSearchParams(location.search).get('printJobId')
  const { socket } = useContext(SocketContext)
  const [collapseState, updateCollapseState] = useCollapseState(
    'PrintJobInfo',
    {
      info: true,
      subJobs: true
    }
  )

  useEffect(() => {
    if (printJobId) {
      fetchPrintJobDetails()
    }
  }, [printJobId])

  useEffect(() => {
    if (socket && printJobId) {
      socket.on('notify_job_update', (updateData) => {
        if (updateData._id === printJobId) {
          setPrintJobData((prevData) => {
            if (!prevData) return prevData
            return {
              ...prevData,
              state: updateData.state,
              ...updateData
            }
          })
        }
      })
    }

    return () => {
      if (socket) {
        socket.off('notify_job_update')
      }
    }
  }, [socket, printJobId])

  const fetchPrintJobDetails = async () => {
    try {
      setLoading(true)
      const response = await axios.get(
        `${config.backendUrl}/printjobs/${printJobId}`,
        {
          headers: {
            Accept: 'application/json'
          },
          withCredentials: true // Important for including cookies
        }
      )
      setPrintJobData(response.data)
      setError(null)
    } catch (err) {
      setError('Failed to fetch print job details')
      messageApi.error('Failed to fetch print job details')
    } finally {
      setLoading(false)
    }
  }

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

  if (error || !printJobData) {
    return (
      <Space
        direction='vertical'
        style={{ width: '100%', textAlign: 'center' }}
      >
        <p>{error || 'Print job not found'}</p>
        <Button icon={<ReloadIcon />} onClick={fetchPrintJobDetails}>
          Retry
        </Button>
      </Space>
    )
  }

  return (
    <div style={{ height: '100%', minHeight: 0, overflowY: 'auto' }}>
      <Collapse
        ghost
        collapsible='icon'
        activeKey={collapseState.info ? ['1'] : []}
        onChange={(keys) => updateCollapseState('info', keys.length > 0)}
        expandIcon={({ isActive }) => (
          <CaretRightOutlined
            rotate={isActive ? 90 : 0}
            style={{ paddingTop: '2px' }}
          />
        )}
        className='no-h-padding-collapse no-t-padding-collapse'
      >
        <Collapse.Panel
          header={
            <Title level={5} style={{ margin: 0 }}>
              Print Job Information
            </Title>
          }
          key='1'
        >
          <Descriptions
            bordered
            column={{
              xs: 1,
              sm: 1,
              md: 1,
              lg: 2,
              xl: 2,
              xxl: 2
            }}
          >
            <Descriptions.Item label='ID'>
              <IdText id={printJobData._id} type={'job'} />
            </Descriptions.Item>
            <Descriptions.Item label='Status'>
              <JobState
                job={printJobData}
                showProgress={false}
                showQuantity={false}
                showId={false}
              />
            </Descriptions.Item>
            <Descriptions.Item label='GCode File Name'>
              <Space>
                <GCodeFileIcon />
                {printJobData.gcodeFile?.name || 'Not specified'}
              </Space>
            </Descriptions.Item>
            <Descriptions.Item label='GCode File ID'>
              <IdText
                id={printJobData.gcodeFile.id}
                type={'gcodeFile'}
                showHyperlink={true}
              />
            </Descriptions.Item>
            <Descriptions.Item label='Quantity'>
              {printJobData.quantity || 1}
            </Descriptions.Item>
            <Descriptions.Item label='Created At'>
              <TimeDisplay dateTime={printJobData.createdAt} showSince={true} />
            </Descriptions.Item>
            <Descriptions.Item label='Started At'>
              {printJobData.startedAt ? (
                <TimeDisplay
                  dateTime={printJobData.startedAt}
                  showSince={true}
                />
              ) : (
                'n/a'
              )}
            </Descriptions.Item>
            {printJobData.state.type === 'printing' && (
              <Descriptions.Item label='Progress'>
                <Progress
                  percent={Math.round((printJobData.state.progress || 0) * 100)}
                />
              </Descriptions.Item>
            )}
            <Descriptions.Item label='Assigned Printers'>
              {printJobData.printers?.length > 0 ? (
                <span>{printJobData.printers.length} printers assigned</span>
              ) : (
                'Any available printer'
              )}
            </Descriptions.Item>
          </Descriptions>
        </Collapse.Panel>
      </Collapse>

      <Collapse
        ghost
        collapsible='icon'
        activeKey={collapseState.subJobs ? ['2'] : []}
        onChange={(keys) => updateCollapseState('subJobs', keys.length > 0)}
        expandIcon={({ isActive }) => (
          <CaretRightOutlined
            rotate={isActive ? 90 : 0}
            style={{ paddingTop: '2px' }}
          />
        )}
        className='no-h-padding-collapse'
      >
        <Collapse.Panel
          header={
            <Title level={5} style={{ margin: 0 }}>
              Sub Job Information
            </Title>
          }
          key='2'
        >
          <SubJobsTree printJobData={printJobData} />
        </Collapse.Panel>
      </Collapse>
    </div>
  )
}

export default PrintJobInfo
