import { TreeSelect, Space } from 'antd'
import React, { useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import axios from 'axios'
import CountryDisplay from './CountryDisplay'
import VendorIcon from '../../Icons/VendorIcon'

const propertyOrder = ['country']

const VendorSelect = ({ onChange, filter = {}, useFilter = false, value }) => {
  const [vendorsTreeData, setVendorsTreeData] = useState([])
  const [loading, setLoading] = useState(true)
  const [defaultValue, setDefaultValue] = useState(null)

  const fetchVendorsData = async (property, filter) => {
    setLoading(true)
    try {
      const response = await axios.get('http://localhost:8080/vendors', {
        params: {
          ...filter,
          property
        },
        headers: {
          Accept: 'application/json'
        },
        withCredentials: true
      })
      setLoading(false)
      return response.data
    } catch (err) {
      console.error(err)
    }
  }

  const getFilter = (node) => {
    var filter = {}
    var currentId = node.id
    while (currentId != 0) {
      const currentNode = vendorsTreeData.filter(
        (treeData) => treeData['id'] === currentId
      )[0]
      filter[propertyOrder[currentNode.propertyId]] =
        currentNode.value.split('-')[0]
      currentId = currentNode.pId
    }
    return filter
  }

  const generateVendorTreeNodes = async (node = null, filter = null) => {
    if (!node) {
      return
    }

    if (filter === null) {
      filter = getFilter(node)
    }

    const vendorData = await fetchVendorsData(null, filter)

    let newNodeList = []

    for (const vendor of vendorData) {
      const random = Math.random().toString(36).substring(2, 6)

      const newNode = {
        id: random,
        pId: node.id,
        value: vendor._id,
        vendor: vendor,
        key: vendor._id,
        title: (
          <Space>
            <VendorIcon />
            {vendor.name}
          </Space>
        ),
        isLeaf: true
      }

      newNodeList.push(newNode)
    }

    setVendorsTreeData(vendorsTreeData.concat(newNodeList))
  }

  const generateVendorCategoryTreeNodes = async (node = null) => {
    var filter = {}

    var propertyId = 0

    if (!node) {
      node = {}
      node.id = 0
    } else {
      filter = getFilter(node)
      propertyId = node.propertyId + 1
    }

    const propertyName = propertyOrder[propertyId]

    const propertyData = await fetchVendorsData(propertyName, filter)

    const newNodeList = []

    for (const item of propertyData) {
      const property = item[propertyName]
      const random = Math.random().toString(36).substring(2, 6)

      const newNode = {
        id: random,
        pId: node.id,
        value: property + '-' + random,
        key: property + '-' + random,
        propertyId: propertyId,
        title: <CountryDisplay countryCode={property} />,
        isLeaf: false,
        selectable: false
      }

      newNodeList.push(newNode)
    }

    setVendorsTreeData(vendorsTreeData.concat(newNodeList))
  }

  const handleVendorsTreeLoad = async (node) => {
    if (node) {
      if (node.propertyId !== propertyOrder.length - 1) {
        await generateVendorCategoryTreeNodes(node)
      } else {
        await generateVendorTreeNodes(node) // End of properties
      }
    } else {
      await generateVendorCategoryTreeNodes(null) // First property
    }
  }

  const handleOnChange = (value, selectedOptions) => {
    const vendorObject = vendorsTreeData.find(
      (node) => node.value === value
    )?.vendor
    onChange(vendorObject, selectedOptions)
  }

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

  useEffect(() => {
    if (vendorsTreeData.length === 0) {
      if (useFilter === true) {
        generateVendorTreeNodes({ id: 0 }, filter)
      } else {
        handleVendorsTreeLoad(null)
      }
    }
  }, [vendorsTreeData])

  useEffect(() => {
    if (value?.name) {
      setDefaultValue(value.name)
    }
  }, [value])

  return (
    <TreeSelect
      treeDataSimpleMode
      loadData={handleVendorsTreeLoad}
      treeData={vendorsTreeData}
      onChange={handleOnChange}
      loading={loading}
      placeholder='Select a vendor'
      style={{ width: '100%' }}
      value={defaultValue}
    />
  )
}

VendorSelect.propTypes = {
  onChange: PropTypes.func,
  filter: PropTypes.object,
  useFilter: PropTypes.bool,
  value: PropTypes.object
}

export default VendorSelect
