import { useState, useRef, useEffect, useContext } from 'react'
import { useLocation } from 'react-router-dom'
import { Space, Flex, Card, Splitter, Divider, Modal } from 'antd'
import loglevel from 'loglevel'
import config from '../../../../config.js'
import useCollapseState from '../../hooks/useCollapseState.jsx'
import NotesPanel from '../../common/NotesPanel.jsx'
import InfoCollapse from '../../common/InfoCollapse.jsx'
import ViewButton from '../../common/ViewButton.jsx'
import NoteIcon from '../../../Icons/NoteIcon.jsx'
import ObjectForm from '../../common/ObjectForm.jsx'
import ActionHandler from '../../common/ActionHandler.jsx'
import ObjectActions from '../../common/ObjectActions.jsx'
import PropTypes from 'prop-types'

import ObjectInfo from '../../common/ObjectInfo.jsx'
import PrinterIcon from '../../../Icons/PrinterIcon.jsx'

import PrinterTemperaturePanel from '../../common/PrinterTemperaturePanel.jsx'
import PrinterPositionPanel from '../../common/PrinterPositionPanel.jsx'
import PrinterMovementPanel from '../../common/PrinterMovementPanel.jsx'
import PrinterMiscPanel from '../../common/PrinterMiscPanel.jsx'
import JobIcon from '../../../Icons/JobIcon.jsx'
import SubJobIcon from '../../../Icons/SubJobIcon.jsx'
import FilamentStockIcon from '../../../Icons/FilamentStockIcon.jsx'
import MissingPlaceholder from '../../common/MissingPlaceholder.jsx'
import { useMediaQuery } from 'react-responsive'
import AlertsDisplay from '../../common/AlertsDisplay.jsx'
import { ApiServerContext } from '../../context/ApiServerContext.jsx'

import LoadFilamentStock from '../../Inventory/FilamentStocks/LoadFilamentStock.jsx'
import UnloadFilamentStock from '../../Inventory/FilamentStocks/UnloadFilamentStock.jsx'
import ScrollBox from '../../common/ScrollBox.jsx'

const log = loglevel.getLogger('ControlPrinter')
log.setLevel(config.logLevel)

const ControlPrinter = ({ slicerIntegration = false }) => {
  const location = useLocation()
  const objectFormRef = useRef(null)
  const actionHandlerRef = useRef(null)
  const isMobile = useMediaQuery({ maxWidth: 768 })
  const printerId = new URLSearchParams(location.search).get('printerId')
  const [collapseState, updateCollapseState] = useCollapseState(
    'ControlPrinter',
    {
      printer: true,
      job: true,
      subjob: true,
      filamentStock: true,
      temperature: true,
      position: true,
      movement: true,
      misc: true
    }
  )

  const { connected, sendObjectAction } = useContext(ApiServerContext)
  const [sideBarVisible, setSideBarVisible] = useState(
    collapseState.temperature ||
      collapseState.position ||
      collapseState.movement ||
      collapseState.misc
  )

  const [loadFilamentStockOpen, setLoadFilamentStockOpen] = useState(false)
  const [unloadFilamentStockOpen, setUnloadFilamentStockOpen] = useState(false)

  useEffect(() => {
    setSideBarVisible(
      collapseState.temperature ||
        collapseState.position ||
        collapseState.movement ||
        collapseState.misc
    )
  }, [collapseState])

  const [objectFormState, setEditFormState] = useState({
    isEditing: false,
    editLoading: false,
    formValid: false,
    activities: [],
    loading: false,
    objectData: {}
  })

  const actions = {
    edit: () => {
      objectFormRef?.current.startEditing()
      return false
    },
    cancelEdit: () => {
      objectFormRef?.current.cancelEditing()
      return true
    },
    finishEdit: () => {
      objectFormRef?.current.handleUpdate()
      return true
    },
    restartFirmware: () => {
      if (connected == true) {
        sendObjectAction(printerId, 'printer', {
          type: 'restartPrinterFirmware'
        })
      }
      return true
    },
    restartMoonraker: () => {
      if (connected == true) {
        sendObjectAction(printerId, 'printer', {
          type: 'restartMoonraker'
        })
      }
      return true
    },
    restart: () => {
      if (connected == true) {
        sendObjectAction(printerId, 'printer', {
          type: 'restartPrinter'
        })
      }
      return true
    },
    startQueue: () => {
      if (connected == true) {
        sendObjectAction(printerId, 'printer', {
          type: 'startQueue'
        })
      }
      return true
    },
    pauseJob: () => {
      if (connected == true) {
        sendObjectAction(printerId, 'printer', {
          type: 'pauseJob'
        })
      }
      return true
    },

    resumeJob: () => {
      if (connected == true) {
        sendObjectAction(printerId, 'printer', {
          type: 'resumeJob'
        })
      }
      return true
    },
    cancelJob: () => {
      if (connected == true) {
        sendObjectAction(printerId, 'printer', {
          type: 'cancelJob'
        })
      }
      return true
    },
    loadFilamentStock: () => {
      setLoadFilamentStockOpen(true)
      return true
    },
    unloadFilamentStock: () => {
      setUnloadFilamentStockOpen(true)
      return true
    }
  }

  const sideBarItems = (
    <Flex gap={isMobile ? 'large' : 'middle'} vertical>
      {collapseState.temperature && (
        <Card
          style={{ width: '100%' }}
          title='Temperature'
          size='small'
          styles={{ body: { padding: '25px' } }}
        >
          <PrinterTemperaturePanel id={printerId} />
        </Card>
      )}
      {collapseState.position && (
        <Card
          style={{ width: '100%' }}
          title='Position'
          size='small'
          styles={{ body: { padding: '25px' } }}
        >
          <PrinterPositionPanel id={printerId} />
        </Card>
      )}
      {collapseState.movement && (
        <Card
          style={{ width: '100%' }}
          title='Movement'
          size='small'
          styles={{ body: { padding: '25px' } }}
        >
          <PrinterMovementPanel id={printerId} />
        </Card>
      )}
      {collapseState.misc && (
        <Card
          style={{ width: '100%' }}
          title='Misc'
          size='small'
          styles={{ body: { padding: '25px' } }}
        >
          <PrinterMiscPanel id={printerId} />
        </Card>
      )}
    </Flex>
  )

  return (
    <>
      <Flex
        gap='large'
        vertical='true'
        style={{
          maxHeight: '100%',
          minHeight: 0
        }}
      >
        <Flex justify={'space-between'}>
          <Space size='middle'>
            <Space size='small'>
              <ObjectActions
                type='printer'
                id={printerId}
                disabled={objectFormState.loading}
                visibleActions={{
                  edit: false,
                  info: !slicerIntegration,
                  control: !slicerIntegration
                }}
                objectData={objectFormState.objectData}
              />
              <ViewButton
                disabled={objectFormState.loading}
                items={[
                  {
                    key: 'printer',
                    label: 'Printer'
                  },
                  {
                    key: 'job',
                    label: 'Job'
                  },
                  {
                    key: 'subJob',
                    label: 'Sub Job'
                  },
                  {
                    key: 'filamentStock',
                    label: 'Filament Stock'
                  },
                  {
                    key: 'temperature',
                    label: 'Temperature'
                  },
                  {
                    key: 'position',
                    label: 'Position'
                  },
                  {
                    key: 'movement',
                    label: 'Movement'
                  },
                  {
                    key: 'misc',
                    label: 'Misc'
                  },
                  { key: 'notes', label: 'Notes' }
                ]}
                visibleState={collapseState}
                updateVisibleState={updateCollapseState}
              />
            </Space>
          </Space>
        </Flex>

        <AlertsDisplay
          alerts={objectFormState.objectData?.alerts}
          printerId={printerId}
        />

        <ScrollBox>
          <Flex vertical gap={'large'}>
            <ActionHandler
              actions={actions}
              loading={objectFormState.loading}
              ref={actionHandlerRef}
            >
              <Flex vertical>
                <Splitter className={'farmcontrol-splitter'}>
                  <Splitter.Panel>
                    <Flex vertical gap={'large'}>
                      <InfoCollapse
                        title={'Printer'}
                        icon={<PrinterIcon />}
                        collapseKey='printer'
                        active={collapseState.printer}
                        onToggle={(expanded) =>
                          updateCollapseState('printer', expanded)
                        }
                      >
                        <ObjectForm
                          id={printerId}
                          type='printer'
                          ref={objectFormRef}
                          onStateChange={(state) => {
                            setEditFormState((prev) => ({ ...prev, ...state }))
                          }}
                        >
                          {({
                            loading: printerObjectLoading,
                            objectData: printerObjectData
                          }) => {
                            return (
                              <ObjectInfo
                                loading={printerObjectLoading}
                                column={sideBarVisible ? 1 : undefined}
                                visibleProperties={{
                                  connectedAt: false,
                                  vendor: false,
                                  'vendor._id': false,
                                  host: false,
                                  'host._id': false,
                                  'moonraker.port': false,
                                  'moonraker.apiKey': false,
                                  'moonraker.protocol': false,
                                  'moonraker.host': false,
                                  tags: false,
                                  firmware: false,
                                  alerts: false,
                                  online: false,
                                  active: false,
                                  currentFilamentStock: false,
                                  'currentFilamentStock._id': false,
                                  currentJob: false,
                                  'currentJob._id': false,
                                  currentSubJob: false,
                                  'currentSubJob._id': false,
                                  createdAt: false,
                                  updatedAt: false,
                                  state: !slicerIntegration,
                                  pendingSlicerUploads: false,
                                  name: !slicerIntegration
                                }}
                                objectPropertyProps={{
                                  showHyperlink: !slicerIntegration
                                }}
                                objectData={printerObjectData}
                                type='printer'
                                labelWidth='120px'
                              />
                            )
                          }}
                        </ObjectForm>
                      </InfoCollapse>
                      <InfoCollapse
                        title={'Job'}
                        icon={<JobIcon />}
                        collapseKey='job'
                        active={collapseState.job}
                        onToggle={(expanded) =>
                          updateCollapseState('job', expanded)
                        }
                      >
                        {objectFormState.objectData?.currentJob?._id ? (
                          <ObjectForm
                            id={objectFormState.objectData.currentJob._id}
                            type='job'
                            onStateChange={() => {}}
                          >
                            {({
                              loading: jobObjectLoading,
                              objectData: jobObjectData
                            }) => {
                              return (
                                <ObjectInfo
                                  loading={jobObjectLoading}
                                  column={sideBarVisible ? 1 : undefined}
                                  showHyperlink={!slicerIntegration}
                                  visibleProperties={{
                                    printers: false,
                                    createdAt: false,
                                    finishedAt: false
                                  }}
                                  objectPropertyProps={{
                                    showHyperlink: !slicerIntegration
                                  }}
                                  objectData={jobObjectData}
                                  type='job'
                                />
                              )
                            }}
                          </ObjectForm>
                        ) : (
                          <MissingPlaceholder
                            message={'No job.'}
                            hasBackground={false}
                          />
                        )}
                      </InfoCollapse>
                      <InfoCollapse
                        title={'Sub Job'}
                        icon={<SubJobIcon />}
                        collapseKey='subJob'
                        active={collapseState.subJob}
                        onToggle={(expanded) =>
                          updateCollapseState('subJob', expanded)
                        }
                      >
                        {objectFormState.objectData?.currentSubJob?._id ? (
                          <ObjectForm
                            id={objectFormState.objectData.currentSubJob._id}
                            type='subJob'
                            onStateChange={() => {}}
                          >
                            {({
                              loading: subJobObjectLoading,
                              objectData: subJobObjectData
                            }) => {
                              return (
                                <ObjectInfo
                                  loading={subJobObjectLoading}
                                  column={sideBarVisible ? 1 : undefined}
                                  showHyperlink={!slicerIntegration}
                                  visibleProperties={{
                                    printers: false,
                                    createdAt: false,
                                    finishedAt: false,
                                    moonrakerJobId: false,
                                    job: false,
                                    printer: false
                                  }}
                                  objectPropertyProps={{
                                    showHyperlink: !slicerIntegration
                                  }}
                                  objectData={subJobObjectData}
                                  type='subJob'
                                />
                              )
                            }}
                          </ObjectForm>
                        ) : (
                          <MissingPlaceholder
                            message={'No sub job.'}
                            hasBackground={false}
                          />
                        )}
                      </InfoCollapse>
                      <InfoCollapse
                        title={'Filament Stock'}
                        icon={<FilamentStockIcon />}
                        collapseKey='filamentStock'
                        active={collapseState.filamentStock}
                        onToggle={(expanded) =>
                          updateCollapseState('filamentStock', expanded)
                        }
                      >
                        {objectFormState.objectData?.currentFilamentStock
                          ?._id ? (
                          <ObjectForm
                            id={
                              objectFormState.objectData.currentFilamentStock
                                ._id
                            }
                            type='filamentStock'
                            onStateChange={() => {}}
                          >
                            {({
                              loading: filamentStockObjectLoading,
                              objectData: filamentStockObjectData
                            }) => {
                              return (
                                <ObjectInfo
                                  loading={filamentStockObjectLoading}
                                  column={sideBarVisible ? 1 : undefined}
                                  showHyperlink={!slicerIntegration}
                                  visibleProperties={{
                                    updatedAt: false,
                                    createdAt: false
                                  }}
                                  objectData={filamentStockObjectData}
                                  type='filamentStock'
                                />
                              )
                            }}
                          </ObjectForm>
                        ) : (
                          <MissingPlaceholder
                            message={'No filament stock.'}
                            hasBackground={false}
                          />
                        )}
                      </InfoCollapse>
                    </Flex>
                  </Splitter.Panel>
                  {sideBarVisible && !isMobile ? (
                    <Splitter.Panel
                      style={{ minWidth: '325px' }}
                      defaultSize='20%'
                      max='35%'
                    >
                      {sideBarItems}
                    </Splitter.Panel>
                  ) : null}
                </Splitter>
                {isMobile ? (
                  <>
                    <Divider />
                    {sideBarItems}
                  </>
                ) : null}
              </Flex>
            </ActionHandler>
            <InfoCollapse
              title='Notes'
              icon={<NoteIcon />}
              active={collapseState.notes}
              onToggle={(expanded) => updateCollapseState('notes', expanded)}
              collapseKey='notes'
            >
              <Card>
                <NotesPanel _id={printerId} type='printer' />
              </Card>
            </InfoCollapse>
          </Flex>
        </ScrollBox>
      </Flex>
      <Modal
        open={loadFilamentStockOpen}
        onCancel={() => setLoadFilamentStockOpen(false)}
        footer={null}
        width='700px'
        destroyOnHidden={true}
      >
        <LoadFilamentStock
          printer={objectFormState.objectData}
          onOk={() => setLoadFilamentStockOpen(false)}
          reset={false}
          filamentStockLoaded={false}
        />
      </Modal>
      <Modal
        open={unloadFilamentStockOpen}
        onCancel={() => setUnloadFilamentStockOpen(false)}
        footer={null}
        width='700px'
        destroyOnHidden={true}
      >
        <UnloadFilamentStock
          printer={objectFormState.objectData}
          onOk={() => setUnloadFilamentStockOpen(false)}
          reset={false}
          filamentStockLoaded={false}
        />
      </Modal>
    </>
  )
}

ControlPrinter.propTypes = {
  slicerIntegration: PropTypes.bool
}

export default ControlPrinter
