import {EllipsisHorizontalIcon, PencilIcon, TrashIcon} from '@heroicons/react/24/outline'
import {FaceSmileIcon} from '@heroicons/react/24/solid'
import {JSONContent} from '@tiptap/react'
import clsx from 'clsx'
import {ChatMessage} from 'common/chat-message'
import {Dispatch, SetStateAction, useEffect, useRef, useState} from 'react'
import {toast} from 'react-hot-toast'
import DropdownMenu, {DropdownItem} from 'web/components/comments/dropdown-menu'
import {useClickOutside} from 'web/hooks/use-click-outside'
import {useIsMobile} from 'web/hooks/use-is-mobile'
import {useUser} from 'web/hooks/use-user'
import {api} from 'web/lib/api'
import {useT} from 'web/lib/locale'
import {updateReactionUI} from 'web/lib/supabase/chat-messages'
import {handleReaction} from 'web/lib/util/message-reactions'

const REACTIONS = ['👍', '❤️', '😂', '😮', '😢', '👎']

export function MessageActions(props: {
  message: {
    id: number
    userId: string
    content: JSONContent
    isEdited?: boolean
    reactions?: Record<string, boolean>
  }
  onRequestEdit?: () => void
  setMessages?: Dispatch<SetStateAction<ChatMessage[] | undefined>>
  className?: string
  // If provided, when this key changes, the emoji picker will open
  openEmojiPickerKey?: number
  // If true, hide the trigger menu button and only render the picker anchor
  hideTrigger?: boolean
}) {
  const {message, onRequestEdit, className, setMessages, openEmojiPickerKey, hideTrigger} = props
  const [showEmojiPicker, setShowEmojiPicker] = useState(false)
  const emojiPickerRef = useRef<HTMLDivElement>(null)
  const user = useUser()
  const isOwner = user?.id === message.userId
  const isMobile = useIsMobile()
  const t = useT()

  useClickOutside(emojiPickerRef, () => {
    setShowEmojiPicker(false)
  })

  // Open emoji picker when external key changes
  useEffect(() => {
    if (openEmojiPickerKey !== undefined) {
      setShowEmojiPicker(true)
    }
  }, [openEmojiPickerKey])

  const handleDelete = async () => {
    if (!confirm(t('messages.delete_confirm', 'Are you sure you want to delete this message?')))
      return
    const messageId = message.id
    try {
      await api('delete-message', {messageId})
      toast.success(t('messages.deleted', 'Message deleted'))
      setMessages?.((prevMessages) => {
        if (!prevMessages) return prevMessages
        return prevMessages.filter((m) => m.id !== messageId)
      })
    } catch (error) {
      toast.error(t('messages.delete_failed', 'Failed to delete message'))
      console.error(error)
    }
  }

  return (
    <div className={clsx('flex items-center gap-1', className)}>
      {showEmojiPicker && (
        <div
          ref={emojiPickerRef}
          className={clsx(
            'absolute mb-2 rounded-lg bg-canvas-100 p-2 shadow-lg pr-10 z-10 max-w-[250px]',
            isMobile ? 'left-1/2 transform -translate-x-1/2' : isOwner ? 'right-20' : 'left-20',
          )}
        >
          <div className="grid grid-cols-6 gap-8">
            {REACTIONS.map((reaction) => (
              <button
                key={reaction}
                className="text-2xl hover:scale-125"
                onClick={async () => {
                  setShowEmojiPicker(false)
                  updateReactionUI(message, user, reaction, setMessages)
                  await handleReaction(reaction, message.id)
                }}
              >
                {reaction}
              </button>
            ))}
          </div>
        </div>
      )}
      {!hideTrigger && (
        <DropdownMenu
          items={
            [
              isOwner && {
                name: t('messages.action.edit', 'Edit'),
                icon: <PencilIcon className="h-4 w-4" />,
                onClick: onRequestEdit,
              },
              isOwner && {
                name: t('messages.action.delete', 'Delete'),
                icon: <TrashIcon className="h-4 w-4" />,
                onClick: handleDelete,
              },
              {
                name: t('messages.action.add_reaction', 'Add Reaction'),
                icon: <FaceSmileIcon className="h-4 w-4" />,
                onClick: () => {
                  setShowEmojiPicker(!showEmojiPicker)
                },
              },
            ].filter(Boolean) as DropdownItem[]
          }
          closeOnClick={true}
          icon={<EllipsisHorizontalIcon className="h-5 w-5 text-gray-500" />}
          menuWidth="w-40"
          className="text-ink-500 hover:text-ink-700 rounded-full p-1 hover:bg-canvas-25"
        />
      )}
      {/*{message.isEdited && (*/}
      {/*  <span className="text-xs text-gray-400">{t('messages.edited', 'edited')}</span>*/}
      {/*)}*/}
    </div>
  )
}
