import { createElement } from 'react'
import { Dropdown, Button } from 'antd'
import { getModelByName } from '../../../database/ObjectModels'
import PropTypes from 'prop-types'
import { useNavigate, useLocation } from 'react-router-dom'

// Recursively filter actions based on visibleActions
function filterActionsByVisibility(actions, visibleActions) {
  if (!visibleActions) return actions

  return actions.filter((action) => {
    if (action.type === 'divider') {
      return true // Always show dividers
    }

    const actionKey = action.key || action.name
    const isVisible = visibleActions[actionKey] !== false

    // If this action has children, filter them recursively
    if (action.children && Array.isArray(action.children)) {
      const filteredChildren = filterActionsByVisibility(
        action.children,
        visibleActions
      )
      action.children = filteredChildren
      // Show parent if it has visible children or if it's explicitly visible
      return (
        isVisible &&
        (filteredChildren.length > 0 || visibleActions[actionKey] === true)
      )
    }

    return isVisible
  })
}

// Recursively map actions to AntD Dropdown items
function mapActionsToMenuItems(actions, currentUrlWithActions, id, objectData) {
  return actions.map((action) => {
    if (action.type === 'divider') {
      return { type: 'divider' }
    }
    const actionUrl = action.url ? action.url(id) : undefined

    var disabled = actionUrl && actionUrl === currentUrlWithActions

    if (action.disabled) {
      if (typeof action.disabled === 'function') {
        disabled = action.disabled(objectData)
      } else {
        disabled = action.disabled
      }
    }

    const item = {
      key: action.key || action.name,
      label: action.label,
      danger: action?.danger || false,
      icon: action.icon ? createElement(action.icon) : undefined,
      disabled
    }
    if (action.children && Array.isArray(action.children)) {
      item.children = mapActionsToMenuItems(
        action.children,
        currentUrlWithActions,
        id
      )
    }
    return item
  })
}

const stripActionParam = (pathname, search) => {
  const params = new URLSearchParams(search)
  params.delete('action')
  const query = params.toString()
  return pathname + (query ? `?${query}` : '')
}

const ObjectActions = ({
  type,
  id,
  objectData,
  disabled = false,
  buttonProps = {},
  visibleActions = {},
  ...dropdownProps
}) => {
  const model = getModelByName(type)
  const actions = model.actions || []
  const navigate = useNavigate()
  const location = useLocation()

  // Get current url without 'action' param
  const currentUrlWithoutActions = stripActionParam(
    location.pathname,
    location.search
  )

  // First filter by visibility, then by current URL
  const visibilityFilteredActions = filterActionsByVisibility(
    actions,
    visibleActions
  )

  const filteredActions = visibilityFilteredActions.filter(
    (action) =>
      typeof action.url !== 'function' ||
      action.url(id) !== currentUrlWithoutActions
  )

  const currentUrlWithActions = location.pathname + location.search

  // Compose AntD Dropdown menu items
  const menu = {
    items: mapActionsToMenuItems(
      filteredActions,
      currentUrlWithActions,
      id,
      objectData
    ),
    onClick: (info) => {
      // Find the action by key
      const findAction = (acts, key) => {
        for (const act of acts) {
          if ((act.key || act.name) === key) return act
          if (act.children) {
            const found = findAction(act.children, key)
            if (found) return found
          }
        }
        return null
      }
      const action = findAction(filteredActions, info.key)
      if (action && action.url) {
        navigate(action.url(id))
      }
    }
  }

  return (
    <Dropdown menu={menu} {...dropdownProps}>
      <Button {...buttonProps} disabled={disabled}>
        Actions
      </Button>
    </Dropdown>
  )
}

ObjectActions.propTypes = {
  type: PropTypes.string.isRequired,
  objectData: PropTypes.object.isRequired,
  id: PropTypes.string.isRequired,
  disabled: PropTypes.bool,
  buttonProps: PropTypes.object,
  buttonLabel: PropTypes.string,
  visibleActions: PropTypes.object
}

export default ObjectActions
