import { Input } from '@headlessui/react'
import {
  ArrowUturnLeftIcon,
  ArrowUturnRightIcon,
  Bars3BottomLeftIcon,
  Bars3BottomRightIcon,
  Bars3Icon,
  BoldIcon,
  CloudArrowUpIcon,
  CodeBracketIcon,
  DocumentTextIcon,
  H1Icon,
  H2Icon,
  H3Icon,
  ItalicIcon,
  LinkIcon,
  LinkSlashIcon,
  ListBulletIcon,
  NumberedListIcon,
  PhotoIcon,
  StrikethroughIcon,
  SwatchIcon,
  XCircleIcon,
} from '@heroicons/react/24/solid'
import {
  Bars3BottomCenterIcon,
  QuotationMarkIcon,
} from '@sidekickicons/react/24/solid'
import type { Editor } from '@tiptap/react'
import {
  type SetStateAction,
  type Dispatch,
  useState,
  useRef,
  useCallback,
  useEffect,
} from 'react'
import { HexColorInput, HexColorPicker } from 'react-colorful'

import { Button } from '~/components/ui/button'
import { useAdminContext } from '~/contexts/admin'
import { useClickOutside } from '~/hooks/use-click-outside'
import { isHexCompatible, rgbToHex } from '~/utils/color'

import { EditorButton } from './editor-button'

type TProperties = {
  editor: Editor | null
  setIsPlainHTML: Dispatch<SetStateAction<boolean>>
  category: string
  disabled?: boolean
}

export const EditorMenuBar = (properties: TProperties) => {
  const { editor, setIsPlainHTML, category, disabled = false } = properties
  const { setIsUploadOpen, uploadedFile, setUploadedFile, isUploadOpen } =
    useAdminContext()
  const [isOpenImage, setIsOpenImage] = useState(false)
  const [imageUrl, setImageUrl] = useState('')
  const [isOpenColor, setIsOpenColor] = useState(false)
  const popover = useRef<HTMLDivElement>(null)
  const close = useCallback(() => {
    setIsOpenColor(false)
    setIsOpenImage(false)
    if (imageUrl) {
      addImage(imageUrl)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [imageUrl])

  useEffect(() => {
    if (uploadedFile && isUploadOpen === category) {
      addImage(uploadedFile)
      setUploadedFile(undefined)
      setIsUploadOpen(undefined)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [uploadedFile])

  useClickOutside(popover, close)

  const setLink = useCallback(() => {
    const previousUrl = editor?.getAttributes('link').href
    const url = globalThis.prompt('URL', previousUrl)

    // cancelled
    if (url === null) {
      return
    }

    // empty
    if (url === '') {
      editor?.chain().focus().extendMarkRange('link').unsetLink().run()

      return
    }

    // update link
    editor?.chain().focus().extendMarkRange('link').setLink({ href: url }).run()
  }, [editor])

  if (!editor) {
    return
  }

  const addImage = (url: string) => {
    if (url) {
      editor.chain().focus().setImage({ src: url }).run()
    }
  }

  const currentColor: string = editor.getAttributes('textStyle').color
  const rgbColor = isHexCompatible(currentColor)
    ? currentColor
    : rgbToHex(currentColor)
  const handleChangeColor = (selectedColor: string) => {
    if (selectedColor.length === 7) {
      editor.chain().focus().setColor(selectedColor).run()
    }
  }

  return (
    <div className="flex items-start justify-between gap-4 px-4 py-3">
      <div className="flex divide-x">
        <div className="flex max-w-[150px] flex-wrap items-start gap-1 px-1">
          <EditorButton
            onClick={() => editor.chain().focus().toggleBold().run()}
            disabled={
              disabled || !editor.can().chain().focus().toggleBold().run()
            }
            isActive={editor.isActive('bold')}
            title="Bold"
          >
            <BoldIcon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() => editor.chain().focus().toggleItalic().run()}
            disabled={
              disabled || !editor.can().chain().focus().toggleItalic().run()
            }
            isActive={editor.isActive('italic')}
            title="Italic"
          >
            <ItalicIcon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() => editor.chain().focus().toggleStrike().run()}
            disabled={
              disabled || !editor.can().chain().focus().toggleStrike().run()
            }
            isActive={editor.isActive('strike')}
            title="Strike"
          >
            <StrikethroughIcon className="size-4" />
          </EditorButton>
          <div className="relative">
            <EditorButton
              onClick={() => setIsOpenColor(true)}
              title="Text Color"
              style={{
                color: rgbColor,
              }}
              isActive={true}
              disabled={disabled}
            >
              <SwatchIcon className="size-4" />
            </EditorButton>
            {isOpenColor && (
              <div
                className="border-md absolute top-8 left-0"
                ref={popover}
              >
                <HexColorPicker
                  className="z-10 rounded-lg shadow"
                  color={rgbColor}
                  onChange={handleChangeColor}
                />
                <div className="">
                  <HexColorInput
                    color={rgbColor}
                    onChange={handleChangeColor}
                    prefixed
                    className="relative z-10 mt-1 flex w-full rounded-lg border-0 bg-white px-3 py-2 text-sm shadow read-only:bg-gray-100 focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none focus-visible:outline-0 disabled:bg-gray-100"
                  />
                </div>
              </div>
            )}
          </div>
          <EditorButton
            onClick={() => editor.chain().focus().setTextAlign('left').run()}
            disabled={
              disabled ||
              !editor.can().chain().focus().setTextAlign('left').run()
            }
            isActive={editor.isActive({ textAlign: 'left' })}
            title="Align Left"
          >
            <Bars3BottomLeftIcon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() => editor.chain().focus().setTextAlign('center').run()}
            disabled={
              disabled ||
              !editor.can().chain().focus().setTextAlign('center').run()
            }
            isActive={editor.isActive({ textAlign: 'center' })}
            title="Align Center"
          >
            <Bars3BottomCenterIcon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() => editor.chain().focus().setTextAlign('right').run()}
            disabled={
              disabled ||
              !editor.can().chain().focus().setTextAlign('right').run()
            }
            isActive={editor.isActive({ textAlign: 'right' })}
            title="Align Right"
          >
            <Bars3BottomRightIcon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() => editor.chain().focus().setTextAlign('justify').run()}
            disabled={
              disabled ||
              !editor.can().chain().focus().setTextAlign('justify').run()
            }
            isActive={editor.isActive({ textAlign: 'justify' })}
            title="Align Justify"
          >
            <Bars3Icon className="size-4" />
          </EditorButton>
        </div>
        <div className="flex max-w-[150px] flex-wrap items-start gap-1 px-1">
          <EditorButton
            onClick={() =>
              editor.chain().focus().toggleHeading({ level: 1 }).run()
            }
            isActive={editor.isActive('heading', { level: 1 })}
            title="Heading 1"
            disabled={disabled}
          >
            <H1Icon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() =>
              editor.chain().focus().toggleHeading({ level: 2 }).run()
            }
            isActive={editor.isActive('heading', { level: 2 })}
            title="Heading 2"
            disabled={disabled}
          >
            <H2Icon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() =>
              editor.chain().focus().toggleHeading({ level: 3 }).run()
            }
            isActive={editor.isActive('heading', { level: 3 })}
            title="Heading 3"
            disabled={disabled}
          >
            <H3Icon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() => editor.chain().focus().toggleCodeBlock().run()}
            isActive={editor.isActive('codeBlock')}
            title="Code Block"
            disabled={disabled}
          >
            <CodeBracketIcon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() => editor.chain().focus().toggleBulletList().run()}
            isActive={editor.isActive('bulletList')}
            title="Bullet List"
            disabled={disabled}
          >
            <ListBulletIcon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() => editor.chain().focus().toggleOrderedList().run()}
            isActive={editor.isActive('orderedList')}
            title="Ordered List"
            disabled={disabled}
          >
            <NumberedListIcon className="size-4" />
          </EditorButton>
          {/* <EditorButton
            onClick={() => editor.chain().focus().setParagraph().run()}
            isActive={editor.isActive('paragraph')}
            title="Paragraph"
            disabled={disabled}
          >
            <PilcrowIcon className="size-4" />
          </EditorButton> */}
          <EditorButton
            onClick={() => editor.chain().focus().toggleBlockquote().run()}
            isActive={editor.isActive('blockquote')}
            title="Blockquote"
            disabled={disabled}
          >
            <QuotationMarkIcon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() => {
              editor.chain().focus().unsetAllMarks().run()
              editor.chain().focus().clearNodes().run()
            }}
            title="Clear Format"
            disabled={disabled}
          >
            <XCircleIcon className="size-4" />
          </EditorButton>
          {/* <EditorButton
              onClick={() => editor.chain().focus().setHorizontalRule().run()}
              title="Horizontal Rule"
              disabled={disabled}
            >
              <RiSeparator />
            </EditorButton> */}
        </div>
        {/* <div className="flex items-start gap-1 px-1">
            <EditorButton
              onClick={() => editor.chain().focus().setHardBreak().run()}
              title="Hard Break"
              disabled={disabled}
            >
              <RiTextWrap />
            </EditorButton>
          </div> */}
        <div className="flex items-start gap-1 px-1">
          <div className="relative">
            <EditorButton
              onClick={() => setIsOpenImage(true)}
              title="Insert Image"
              disabled={disabled}
            >
              <PhotoIcon className="size-4" />
            </EditorButton>
            {isOpenImage && (
              <div
                className="border-md absolute top-8 left-0 w-50"
                ref={popover}
              >
                <div className="relative">
                  <Input
                    placeholder="Masukkan URL Gambar"
                    color={rgbColor}
                    onChange={(event) => {
                      setImageUrl(event.target.value)
                    }}
                    className="z-10 flex h-[42px] w-full rounded-lg border-0 bg-white p-2 pr-8 text-sm shadow read-only:bg-gray-100 focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none focus-visible:outline-0 disabled:bg-gray-100"
                  />
                  <Button
                    type="button"
                    variant="icon"
                    size="fit"
                    className="absolute top-0 right-3 h-[42px]"
                    onClick={() => {
                      setIsUploadOpen('content')
                    }}
                  >
                    <CloudArrowUpIcon className="size-4 text-gray-500/50" />
                  </Button>
                </div>
              </div>
            )}
          </div>
          <EditorButton
            onClick={() => setLink()}
            disabled={
              disabled ||
              !editor
                .can()
                .chain()
                .focus()
                .extendMarkRange('link')
                .setLink({ href: '' })
                .run()
            }
            isActive={editor.isActive('link')}
            title="Set Link"
          >
            <LinkIcon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() => editor.chain().focus().unsetLink().run()}
            disabled={disabled || !editor.isActive('link')}
            title="Unset Link"
          >
            <LinkSlashIcon className="size-4" />
          </EditorButton>
        </div>
        <div className="flex items-start gap-1 px-1">
          <EditorButton
            onClick={() => editor.chain().focus().undo().run()}
            disabled={disabled || !editor.can().chain().focus().undo().run()}
            title="Undo"
          >
            <ArrowUturnLeftIcon className="size-4" />
          </EditorButton>
          <EditorButton
            onClick={() => editor.chain().focus().redo().run()}
            disabled={disabled || !editor.can().chain().focus().redo().run()}
            title="Redo"
          >
            <ArrowUturnRightIcon className="size-4" />
          </EditorButton>
        </div>
      </div>
      <div>
        <div className="flex gap-1 px-1">
          <EditorButton
            onClick={() => setIsPlainHTML(true)}
            title="Switch to Plain Text"
          >
            <DocumentTextIcon className="size-4" />
          </EditorButton>
        </div>
      </div>
    </div>
  )
}
