import {
  flip,
  FloatingPortal,
  offset,
  shift,
  useFloating,
} from '@floating-ui/react'
import { Button } from '@langgenius/dify-ui/button'
import { cn } from '@langgenius/dify-ui/cn'
import {
  RiEditLine,
  RiExternalLinkLine,
  RiLinkUnlinkM,
} from '@remixicon/react'
import { useClickAway } from 'ahooks'
import { escape } from 'es-toolkit/string'
import {
  memo,
  useCallback,
  useEffect,
  useRef,
  useState,
} from 'react'
import { useTranslation } from 'react-i18next'
import { useStore } from '../../store'
import { useLink } from './hooks'

type LinkEditorComponentProps = {
  containerElement: HTMLDivElement | null
}
const LinkEditorComponent = ({
  containerElement,
}: LinkEditorComponentProps) => {
  const { t } = useTranslation()
  const {
    handleSaveLink,
    handleUnlink,
  } = useLink()
  const selectedLinkUrl = useStore(s => s.selectedLinkUrl)
  const linkAnchorElement = useStore(s => s.linkAnchorElement)
  const linkOperatorShow = useStore(s => s.linkOperatorShow)
  const setLinkAnchorElement = useStore(s => s.setLinkAnchorElement)
  const setLinkOperatorShow = useStore(s => s.setLinkOperatorShow)
  const [url, setUrl] = useState(selectedLinkUrl)
  const floatingRef = useRef<HTMLDivElement | null>(null)
  const { refs, floatingStyles, elements } = useFloating({
    placement: 'top',
    middleware: [
      offset(4),
      shift(),
      flip(),
    ],
  })

  const handleCancelLinkEdit = useCallback(() => {
    if (!linkOperatorShow && !selectedLinkUrl) {
      handleUnlink()
      return
    }

    setLinkAnchorElement()
    setLinkOperatorShow(false)
  }, [handleUnlink, linkOperatorShow, selectedLinkUrl, setLinkAnchorElement, setLinkOperatorShow])

  useClickAway(() => {
    handleCancelLinkEdit()
  }, [floatingRef, linkAnchorElement])

  useEffect(() => {
    setUrl(selectedLinkUrl)
  }, [selectedLinkUrl])

  useEffect(() => {
    if (linkAnchorElement)
      refs.setReference(linkAnchorElement)
  }, [linkAnchorElement, refs])

  return (
    <>
      {
        elements.reference && (
          <FloatingPortal root={containerElement}>
            <div
              className={cn(
                'nodrag nopan z-10 inline-flex w-max items-center rounded-md border-[0.5px] border-components-actionbar-border bg-components-actionbar-bg',
                !linkOperatorShow && 'p-1 shadow-md',
                linkOperatorShow && 'p-0.5 system-xs-medium text-text-tertiary shadow-sm',
              )}
              style={floatingStyles}
              ref={(node) => {
                refs.setFloating(node)
                floatingRef.current = node
              }}
            >
              {
                !linkOperatorShow && (
                  <>
                    <input
                      className="mr-0.5 h-6 w-[196px] appearance-none rounded-xs bg-transparent p-1 text-[13px] text-components-input-text-filled outline-hidden"
                      value={url}
                      onChange={e => setUrl(e.target.value)}
                      onKeyDown={(e) => {
                        if (e.key === 'Enter') {
                          e.preventDefault()
                          e.stopPropagation()
                          if (url)
                            handleSaveLink(url)
                          return
                        }

                        if (e.key === 'Escape') {
                          e.preventDefault()
                          e.stopPropagation()
                          handleCancelLinkEdit()
                        }
                      }}
                      placeholder={t('nodes.note.editor.enterUrl', { ns: 'workflow' }) || ''}
                      autoFocus
                    />
                    <Button
                      variant="primary"
                      size="small"
                      disabled={!url}
                      onClick={() => handleSaveLink(url)}
                    >
                      {t('operation.ok', { ns: 'common' })}
                    </Button>
                  </>
                )
              }
              {
                linkOperatorShow && (
                  <>
                    <a
                      className="flex h-6 items-center rounded-md px-2 hover:bg-state-base-hover"
                      href={escape(url)}
                      target="_blank"
                      rel="noopener noreferrer"
                    >
                      <RiExternalLinkLine className="mr-1 size-3" />
                      <div className="mr-1">
                        {t('nodes.note.editor.openLink', { ns: 'workflow' })}
                      </div>
                      <div
                        title={escape(url)}
                        className="max-w-[140px] truncate text-text-accent"
                      >
                        {escape(url)}
                      </div>
                    </a>
                    <div className="mx-1 h-3.5 w-px bg-divider-regular"></div>
                    <div
                      className="mr-0.5 flex h-6 cursor-pointer items-center rounded-md px-2 hover:bg-state-base-hover"
                      onClick={(e) => {
                        e.stopPropagation()
                        setLinkOperatorShow(false)
                      }}
                    >
                      <RiEditLine className="mr-1 size-3" />
                      {t('operation.edit', { ns: 'common' })}
                    </div>
                    <div
                      className="flex h-6 cursor-pointer items-center rounded-md px-2 hover:bg-state-base-hover"
                      onClick={handleUnlink}
                    >
                      <RiLinkUnlinkM className="mr-1 size-3" />
                      {t('nodes.note.editor.unlink', { ns: 'workflow' })}
                    </div>
                  </>
                )
              }
            </div>
          </FloatingPortal>
        )
      }
    </>
  )
}

export default memo(LinkEditorComponent)
