import React, { useState, useCallback, useEffect, useContext } from "react"
import classNames from "classnames"
import { useId } from "@reach/auto-id"

import Button from "../button"

export const ActionContext = React.createContext({
  actions: [],
  register: () => {},
  remove: () => {},
  update: () => {},
})

export const ActionProvider = ({ children }) => {
  const [actions, setActions] = useState([])

  const remove = useCallback((id) => {
    setActions((actions) => actions.filter((action) => action.id !== id))
  }, [])

  const register = useCallback((id, props, ref) => {
    setActions((actions) => {
      let index = actions.findIndex((action) => action.id === id)

      if (index == -1) index = actions.length

      return Object.assign([], actions, {
        [index]: {
          id,
          ...actions[index],
          ...{ ...props, ref },
        },
      })
    })
  }, [])

  return (
    <ActionContext.Provider value={{ actions, register, remove }}>
      {children}
    </ActionContext.Provider>
  )
}

const useAction = (id, props, ref) => {
  const { register, remove } = useContext(ActionContext)

  useEffect(() => {
    if (!id) return
    register(id, props, ref)
    return () => remove(id)
  }, [id, props, ref, register, remove])
}

export const Actions = () => {
  const { actions } = useContext(ActionContext)

  if (actions.length === 0) return null

  return (
    <div
      className="flex justify-end rounded-b-lg border-t border-gray-200 py-6 px-6 sticky bottom-0 bg-white"
      data-testid="actions"
    >
      <div className="-mr-2">
        {actions.map(({ id, ...props }) => (
          <Button
            key={id}
            {...props}
            className={classNames(
              "mx-2 flex-auto justify-center font-semibold",
              props.className
            )}
          />
        ))}
      </div>
    </div>
  )
}

const Action = React.forwardRef((props, ref) => {
  const id = useId()
  useAction(id, props, ref)

  return null
})

export default Action
