import { MinusOutlined } from '@ant-design/icons'
import { useEditorState } from '@tiptap/react'
import { useState } from 'react'
import {
  Button,
  Card,
  Checkbox,
  Flex,
  Input,
  Popover,
  Select,
  Space,
  Tooltip
} from 'antd'
import PropTypes from 'prop-types'
import BlockquoteIcon from '../../Icons/BlockquoteIcon'
import BoldIcon from '../../Icons/BoldIcon'
import BulletListIcon from '../../Icons/BulletListIcon'
import CheckIcon from '../../Icons/CheckIcon'
import ItalicIcon from '../../Icons/ItalicIcon'
import NumberedListIcon from '../../Icons/NumberedListIcon'
import JsonObjectIcon from '../../Icons/JsonObjectIcon'
import LinkIcon from '../../Icons/LinkIcon'
import TextFormatIcon from '../../Icons/TextFormatIcon'
import UnderlineIcon from '../../Icons/UnderlineIcon'

const BLOCK_TYPE_OPTIONS = [
  { label: 'Paragraph', value: 'paragraph' },
  { label: 'Heading 1', value: 'h1' },
  { label: 'Heading 2', value: 'h2' },
  { label: 'Heading 3', value: 'h3' },
  { label: 'Heading 4', value: 'h4' },
  { label: 'Quote', value: 'quote' }
]

const getBlockTypeValue = (editor) => {
  if (!editor) {
    return 'paragraph'
  }

  if (editor.isActive('blockquote')) {
    return 'quote'
  }

  for (const level of [1, 2, 3, 4]) {
    if (editor.isActive('heading', { level })) {
      return `h${level}`
    }
  }

  return 'paragraph'
}

const VIEW_ITEMS = [
  { key: 'editor', label: 'Editor' },
  { key: 'code', label: 'Code' }
]

const MarkdownToolbar = ({
  editor,
  size = 'small',
  showCard = true,
  viewState = { editor: true, code: false },
  onViewStateChange = () => {},
  editingToolsDisabled = false
}) => {
  const [linkPopoverOpen, setLinkPopoverOpen] = useState(false)
  const [linkUrl, setLinkUrl] = useState('')

  const editorState = useEditorState({
    editor,
    selector: ({ editor }) => ({
      blockTypeValue: getBlockTypeValue(editor),
      isBold: editor?.isActive('bold') ?? false,
      isItalic: editor?.isActive('italic') ?? false,
      isUnderline: editor?.isActive('underline') ?? false,
      isBulletList: editor?.isActive('bulletList') ?? false,
      isOrderedList: editor?.isActive('orderedList') ?? false
    })
  })

  const handleViewStateChange = (key, checked) => {
    const nextState = { ...viewState, [key]: checked }
    if (!nextState.editor && !nextState.code) {
      nextState[key] = true
    }
    onViewStateChange(nextState)
  }

  const handleLinkPopoverOpenChange = (open) => {
    setLinkPopoverOpen(open)
    if (open) {
      setLinkUrl(editor?.getAttributes('link').href ?? '')
    }
  }

  const handleLinkSubmit = () => {
    if (!editor) {
      return
    }

    const trimmedUrl = linkUrl.trim()

    if (!trimmedUrl) {
      editor.chain().focus().extendMarkRange('link').unsetLink().run()
    } else {
      editor
        .chain()
        .focus()
        .extendMarkRange('link')
        .setLink({ href: trimmedUrl })
        .run()
    }

    setLinkPopoverOpen(false)
  }

  const handleBlockTypeChange = (nextBlockType) => {
    if (!editor) {
      return
    }

    const chain = editor.chain().focus()

    if (editor.isActive('blockquote') && nextBlockType !== 'quote') {
      chain.toggleBlockquote()
    }

    if (nextBlockType === 'paragraph') {
      chain.setParagraph().run()
      return
    }

    if (nextBlockType === 'quote') {
      if (editor.isActive('heading')) {
        chain.setParagraph()
      }

      chain.toggleBlockquote().run()
      return
    }

    const headingLevel = Number(nextBlockType.replace('h', ''))
    chain.setHeading({ level: headingLevel }).run()
  }

  const linkPopoverContent = (
    <Space.Compact block style={{ width: 280 }}>
      <Input
        placeholder='Enter a URL...'
        value={linkUrl}
        onChange={(e) => setLinkUrl(e.target.value)}
        onPressEnter={handleLinkSubmit}
        style={{ flex: 1 }}
      />
      <Button
        type='primary'
        onClick={handleLinkSubmit}
        icon={<CheckIcon />}
        style={{ minWidth: 32 }}
      />
    </Space.Compact>
  )

  const cardContent = (
    <Space wrap size={8}>
      <Popover
        content={
          <Flex vertical gap='middle' style={{ margin: '4px 8px' }}>
            {VIEW_ITEMS.map((item) => (
              <Checkbox
                checked={viewState[item.key]}
                key={item.key}
                onChange={(e) =>
                  handleViewStateChange(item.key, e.target.checked)
                }
              >
                {item.label}
              </Checkbox>
            ))}
          </Flex>
        }
        placement='bottomLeft'
        trigger='hover'
        arrow={false}
      >
        <Button size={size} style={{ minWidth: 32 }}>
          View
        </Button>
      </Popover>
      <Select
        size={size}
        value={editorState.blockTypeValue}
        options={BLOCK_TYPE_OPTIONS}
        onChange={handleBlockTypeChange}
        prefix={<TextFormatIcon />}
        style={{ width: 160 }}
        status={'defult'}
        disabled={!editor || editingToolsDisabled}
      />
      <Space.Compact size='small'>
        <Tooltip title='Bold' arrow={false}>
          <Button
            size={size}
            type={editorState.isBold ? 'primary' : 'default'}
            icon={<BoldIcon />}
            onClick={() => editor?.chain().focus().toggleBold().run()}
            disabled={!editor || editingToolsDisabled}
            style={{ minWidth: 32 }}
          />
        </Tooltip>
        <Tooltip title='Italic' arrow={false}>
          <Button
            size={size}
            type={editorState.isItalic ? 'primary' : 'default'}
            icon={<ItalicIcon />}
            onClick={() => editor?.chain().focus().toggleItalic().run()}
            disabled={!editor || editingToolsDisabled}
            style={{ minWidth: 32 }}
          />
        </Tooltip>
        <Tooltip title='Underline' arrow={false}>
          <Button
            size={size}
            type={editorState.isUnderline ? 'primary' : 'default'}
            icon={<UnderlineIcon />}
            onClick={() => editor?.chain().focus().toggleUnderline().run()}
            disabled={!editor || editingToolsDisabled}
            style={{ minWidth: 32 }}
          />
        </Tooltip>
      </Space.Compact>
      <Space.Compact size='small'>
        <Tooltip title='Bulleted list' arrow={false}>
          <Button
            size={size}
            type={editorState.isBulletList ? 'primary' : 'default'}
            icon={<BulletListIcon />}
            onClick={() => editor?.chain().focus().toggleBulletList().run()}
            disabled={!editor || editingToolsDisabled}
            style={{ minWidth: 32 }}
          />
        </Tooltip>
        <Tooltip title='Numbered list' arrow={false}>
          <Button
            size={size}
            type={editorState.isOrderedList ? 'primary' : 'default'}
            icon={<NumberedListIcon />}
            onClick={() => editor?.chain().focus().toggleOrderedList().run()}
            disabled={!editor || editingToolsDisabled}
            style={{ minWidth: 32 }}
          />
        </Tooltip>
      </Space.Compact>
      <Tooltip title='Block quote' arrow={false}>
        <Button
          size={size}
          type={editorState.blockTypeValue === 'quote' ? 'primary' : 'default'}
          icon={<BlockquoteIcon />}
          onClick={() =>
            handleBlockTypeChange(
              editorState.blockTypeValue === 'quote' ? 'paragraph' : 'quote'
            )
          }
          disabled={!editor || editingToolsDisabled}
          style={{ minWidth: 32 }}
        />
      </Tooltip>
      <Popover
        content={linkPopoverContent}
        placement='bottom'
        trigger='click'
        arrow={false}
        open={linkPopoverOpen}
        styles={{ body: { borderRadius: '22px' } }}
        onOpenChange={handleLinkPopoverOpenChange}
      >
        <Tooltip title='Insert link' arrow={false}>
          <Button
            size={size}
            icon={<LinkIcon />}
            disabled={!editor || editingToolsDisabled}
            style={{ minWidth: 32 }}
          />
        </Tooltip>
      </Popover>
      <Tooltip title='Insert code block' arrow={false}>
        <Button
          size={size}
          icon={<JsonObjectIcon />}
          onClick={() => editor?.chain().focus().toggleCodeBlock().run()}
          disabled={!editor || editingToolsDisabled}
          style={{ minWidth: 32 }}
        />
      </Tooltip>
      <Tooltip title='Insert horizontal rule' arrow={false}>
        <Button
          size={size}
          icon={<MinusOutlined />}
          onClick={() => editor?.chain().focus().setHorizontalRule().run()}
          disabled={!editor || editingToolsDisabled}
          style={{ minWidth: 32 }}
        />
      </Tooltip>
    </Space>
  )

  return (
    <>
      {showCard ? (
        <Card
          style={{
            width: '100%',
            borderRadius: '12px 12px 0 0',
            borderTop: 'none',
            borderLeft: 'none',
            borderRight: 'none'
          }}
          styles={{
            body: {
              padding: 12
            }
          }}
        >
          {cardContent}
        </Card>
      ) : (
        cardContent
      )}
    </>
  )
}

MarkdownToolbar.propTypes = {
  editor: PropTypes.shape({
    chain: PropTypes.func,
    getAttributes: PropTypes.func,
    isActive: PropTypes.func
  }),
  size: PropTypes.string,
  showCard: PropTypes.bool,
  viewState: PropTypes.object,
  onViewStateChange: PropTypes.func,
  editingToolsDisabled: PropTypes.bool
}

export default MarkdownToolbar
