'use client'

import * as React from 'react'
import type { LinkPopoverOpenMode } from '../control-options'
import type { ControlAvailability } from '../control-options'
import type { LinkButtonProps } from './link-button'
import type { UseLinkPopoverConfig } from '@admin/hooks/content-editor/use-link-popover'
import { useLinkPopover } from '@admin/hooks/content-editor/use-link-popover'
import { useTiptapEditor } from '@admin/hooks/content-editor/use-tiptap-editor'
import {
  shouldHideUnavailableControl,
  shouldOpenLinkPopoverFromActiveLink
} from '../control-options'
import { LinkControlPopover } from './link-control-popover'

export { LinkButton } from './link-button'
export { LinkContent } from './link-content'
export type { LinkControlPopoverProps } from './link-control-popover'
export { LinkControlPopover } from './link-control-popover'
export type { LinkMainProps } from './link-main'

export interface LinkPopoverProps
  extends Omit<LinkButtonProps, 'type'>, Omit<UseLinkPopoverConfig, 'hideWhenUnavailable'> {
  availability?: ControlAvailability
  onOpenChange?: (isOpen: boolean) => void
  openMode?: LinkPopoverOpenMode
}

type LinkPopoverOpenState = {
  isActive: boolean
  openMode: LinkPopoverOpenMode
  open: boolean | null
}

export function LinkPopover({
  editor: providedEditor,
  availability,
  onSetLink,
  onOpenChange,
  openMode = 'active-link',
  onClick,
  children,
  ref,
  ...buttonProps
}: LinkPopoverProps) {
  const { editor } = useTiptapEditor(providedEditor)

  const { isVisible, canSet, isActive, url, setUrl, setLink, removeLink, label, Icon } =
    useLinkPopover({
      editor,
      hideWhenUnavailable: shouldHideUnavailableControl(availability),
      onSetLink
    })

  const [openState, setOpenState] = React.useState<LinkPopoverOpenState>({
    isActive,
    openMode,
    open: null
  })
  let manualOpen = openState.open
  if (openState.openMode !== openMode || openState.isActive !== isActive) {
    manualOpen = null
    setOpenState({
      isActive,
      openMode,
      open: null
    })
  }
  const editorControlsOpen = shouldOpenLinkPopoverFromActiveLink(openMode) && isActive
  const isOpen = manualOpen ?? editorControlsOpen

  const handleOnOpenChange = React.useCallback(
    (nextIsOpen: boolean) => {
      setOpenState({
        isActive,
        openMode,
        open: nextIsOpen
      })
      onOpenChange?.(nextIsOpen)
    },
    [isActive, onOpenChange, openMode]
  )

  if (!isVisible) {
    return null
  }

  return (
    <LinkControlPopover
      canSet={canSet}
      isActive={isActive}
      label={label}
      onClick={onClick}
      onOpenChange={handleOnOpenChange}
      open={isOpen}
      removeLink={removeLink}
      setLink={setLink}
      setUrl={setUrl}
      url={url}
      {...buttonProps}
      ref={ref}
    >
      {children ?? <Icon />}
    </LinkControlPopover>
  )
}

export default LinkPopover
