// PrinterSelect.js
import PropTypes from 'prop-types'
import { TreeSelect, message, Tag } from 'antd'
import React, { useEffect, useState, useContext } from 'react'
import axios from 'axios'
import PrinterState from './PrinterState'
import { AuthContext } from '../../Auth/AuthContext'
import config from '../../../config'

const PrinterSelect = ({ onChange, disabled, checkable, value = [] }) => {
  const [printersTreeData, setPrintersTreeData] = useState([])
  const [printersData, setPrintersData] = useState([])
  const [loading, setLoading] = useState(true)
  const [messageApi] = message.useMessage()
  const [defaultValue, setDefaultValue] = useState(value)

  const { authenticated } = useContext(AuthContext)

  const fetchPrintersTreeData = async () => {
    if (!authenticated) {
      return
    }
    setLoading(true)

    try {
      const response = await axios.get(`${config.backendUrl}/printers`, {
        headers: {
          Accept: 'application/json'
        },
        withCredentials: true // Important for including cookies
      })
      setLoading(false)
      return response.data
    } catch (error) {
      if (error.response) {
        // For other errors, show a message
        messageApi.error('Error fetching printers data:', error.response.status)
      } else {
        messageApi.error(
          'An unexpected error occurred. Please try again later.'
        )
      }
    }
  }

  const generatePrinterItems = async () => {
    const printerData = await fetchPrintersTreeData()

    setPrintersData(printerData)

    // Create a map to store tags and their printers
    const tagMap = new Map()

    // Add printers to their respective tag groups
    printerData.forEach((printer) => {
      if (printer.tags && printer.tags.length > 0) {
        printer.tags.forEach((tag) => {
          if (!tagMap.has(tag)) {
            tagMap.set(tag, [])
          }
          tagMap.get(tag).push(printer)
        })
      } else {
        // If no tags, add to "Untagged" group
        if (!tagMap.has('Untagged')) {
          tagMap.set('Untagged', [])
        }
        tagMap.get('Untagged').push(printer)
      }
    })

    // Convert the map to tree data structure
    Array.from(tagMap.entries()).map(([tag, printers]) => {
      const newNode = {
        title: tag === 'Untagged' ? tag : <Tag color='blue'>{tag}</Tag>,
        value: `tag-${tag}`,
        key: `tag-${tag}`,
        children: printers.map((printer) => ({
          title: (
            <PrinterState
              printer={printer}
              showProgress={false}
              showControls={false}
            />
          ),
          value: printer._id,
          key: printer._id
        }))
      }
      setPrintersTreeData((prev) => {
        const filtered = prev.filter((node) => node.key !== newNode.key)
        return [...filtered, newNode]
      })
    })
  }

  const handleOnChange = (value, selectedOptions) => {
    if (checkable) {
      // Multiple selection mode
      const newValue = printersData.filter((printer) =>
        value.includes(printer._id)
      )
      setDefaultValue(newValue)
      onChange(newValue, selectedOptions)
    } else {
      // Single selection mode
      const selectedPrinter = printersData.find(
        (printer) => printer._id === value
      )
      setDefaultValue(selectedPrinter ? [selectedPrinter] : [])
      onChange(selectedPrinter, selectedOptions)
    }
  }

  useEffect(() => {
    if (value) {
      if (Array.isArray(value)) {
        setDefaultValue(value)
      } else {
        setDefaultValue([value])
      }
    }
  }, [value])

  useEffect(() => {
    generatePrinterItems()
  }, [])

  return (
    <TreeSelect
      treeData={printersTreeData}
      onChange={handleOnChange}
      loading={loading}
      disabled={disabled}
      treeDefaultExpandAll
      treeCheckable={checkable}
      treeNodeFilterProp='title'
      placeholder='Select printer'
      style={{ width: '100%' }}
      value={
        checkable ? defaultValue.map((item) => item._id) : defaultValue[0]?._id
      }
    />
  )
}

PrinterSelect.propTypes = {
  onChange: PropTypes.func.isRequired,
  disabled: PropTypes.bool.isRequired,
  checkable: PropTypes.bool,
  value: PropTypes.oneOfType([PropTypes.object, PropTypes.array])
}

export default PrinterSelect
