import React, {
  createContext,
  MutableRefObject,
  useState,
  useMemo,
  useContext,
  useRef,
  useCallback
} from 'react'
import Dialog, { Props } from './index'
import { DialogType, DialogContextType, DialogList, VisibleDialogsType } from "./types"
const DialogContext = createContext<DialogContextType>({
  dialogList: {},
  visibleDialogs: {},
  setDialog: () => { },
  hideDialog: () => { },
  hideAll: () => { }
})
const CustiomDialog = () => {
  const { dialogList, visibleDialogs,hideDialog } = useContext(DialogContext)
  const DialogListIds = () => {
    return Object.keys(visibleDialogs)
  }

  return (<>
    {
      DialogListIds().map((id) => {
        return <Dialog key={id} onChange={hideDialog} show={visibleDialogs[id]} {...dialogList[id]}></Dialog>
      })
    }
  </>)

}

export const DialogProvider = ({ children }: { children: any }) => {
  const [dialogList, setDialogList] = useState<DialogList>({})
  const [visibleDialogs, setVisibleDialogs] = useState<VisibleDialogsType>({});
  const dialogIndex = useRef(9000)
  const hideDialog = useCallback((id: any) => {
    setVisibleDialogs((prev) => {
      return { ...prev, [id]: false }
    })
  }, [setVisibleDialogs])
  const hideAll = useCallback(() => {
    setVisibleDialogs({})
  }, [setVisibleDialogs])
  const setDialog = useCallback(
    (props: DialogType): number => {
      const { id = dialogIndex.current++, ...rest } = props
      setDialogList((prev) => {
        return {
          ...prev, [id]: {
            id,
            ...rest
          }
        }
      })
      setVisibleDialogs((prev) => {
        return { ...prev, [id]: true }
      })
      return id
    }, [dialogList, visibleDialogs, hideDialog])


  const contextValue = useMemo(() => {
    return {
      dialogList,
      visibleDialogs,
      setDialog,
      hideDialog,
      hideAll
    }
  },
    [
      dialogList,
      visibleDialogs,
      setDialog,
      hideDialog,
      hideAll
    ])

  return (
    <DialogContext.Provider value={contextValue}>
      {children}
      <CustiomDialog></CustiomDialog>
    </DialogContext.Provider>
  )
}

export const useDialog = () => {
  const { setDialog, hideDialog, hideAll } = useContext(DialogContext)

  const dialog = useMemo(() => (
    {
      show: setDialog,
      close: hideDialog,
      closeAll: hideAll
    }
  ), [setDialog, hideDialog, hideAll])

  return dialog
}
