import { LexicalComposer } from '@lexical/react/LexicalComposer'
import { ContentEditable } from '@lexical/react/LexicalContentEditable'
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'
import { BehaviourPlugin } from './BehaviourPlugin.js'
import { ValuePlugin } from './ValuePlugin.js'
import { Toolbar } from './Toolbar.js'
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin'
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary'
import { NODES } from './nodes.js'
import { ListPlugin } from '@lexical/react/LexicalListPlugin'
import { styled } from 'inlines'
import { useState } from 'react'
import { colors } from '../../utils/colors.js'
import { radius } from '../../utils/radius.js'
import { Text } from '../Text/index.js'
import { Icon } from '../Icon/index.js'
import { FloatingLinkPlugin } from './FloatingLinkPlugin.js'
import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin'

const EDITOR_STYLES = {
  '& .editor > *': {
    marginBottom: 14,
  },
  '& .editor-heading-h1': {
    fontFamily: 'Geist',
    fontSize: 28,
    fontWeight: 600,
    lineHeight: 1.1,
    letterSpacing: 28 * -0.02,
  },
  '& .editor-heading-h2': {
    fontFamily: 'Geist',
    fontSize: 22,
    fontWeight: 600,
    lineHeight: 1.25,
    letterSpacing: 0,
  },
  '& .editor-heading-h3': {
    fontFamily: 'Geist',
    fontSize: 18,
    fontWeight: 600,
    lineHeight: 1.25,
    letterSpacing: 0,
  },
  '& .editor-paragraph': {
    fontFamily: 'Geist',
    fontSize: 14,
    fontWeight: 400,
    lineHeight: 1.25,
    letterSpacing: 28 * 0.01,
  },
  '& .editor-quote': {
    fontFamily: 'Geist',
    fontSize: 14,
    fontWeight: 400,
    lineHeight: 1.25,
    letterSpacing: 28 * 0.01,
    borderLeft: `2px solid ${colors.neutral20}`,
    paddingLeft: 14,
  },
  '& .editor-list-ol, & .editor-list-ul': {
    padding: '0 0 0 16px',
  },
  '& .editor-listitem, & .editor-listitem::marker': {
    fontFamily: 'Geist',
    fontSize: 14,
    fontWeight: 400,
    lineHeight: 1.25,
    letterSpacing: 28 * 0.01,
  },
  '& .editor-link': {
    color: colors.blue100,
    textDecoration: 'none',
  },
  '& .editor-link:hover': {
    textDecoration: 'underline',
  },
  '& .text-bold': {
    fontWeight: 700,
  },
  '& .text-italic': {
    fontStyle: 'italic',
  },
  '& .text-underline': {
    textDecoration: 'underline',
  },
  '& .text-strikethrough': {
    textDecoration: 'line-through',
  },
  '& .text-underline-strikethrough': {
    textDecoration: 'underline line-through',
  },
}

type RichTextEditorProps = {
  value?: string
  onChange: (value: string) => void
  placeholder?: string
  disabled?: boolean
  error?: boolean
}

const COMMON_CONFIG = {
  namespace: `based_ui_rte`,
  onError: console.error,
  nodes: NODES,
  theme: {
    heading: {
      h1: 'editor-heading-h1',
      h2: 'editor-heading-h2',
      h3: 'editor-heading-h3',
    },
    link: 'editor-link',
    list: {
      listitem: 'editor-listitem',
      ol: 'editor-list-ol',
      ul: 'editor-list-ul',
    },
    quote: 'editor-quote',
    paragraph: 'editor-paragraph',
    text: {
      bold: 'text-bold',
      italic: 'text-italic',
      strikethrough: 'text-strikethrough',
      underline: 'text-underline',
      underlineStrikethrough: 'text-underline-strikethrough',
    },
  },
}

function RichTextEditor({
  value,
  onChange,
  placeholder,
  disabled,
  error,
}: RichTextEditorProps) {
  const [open, setOpen] = useState(false)

  if (!open)
    return (
      <div style={{ width: '100%', height: '100%' }}>
        <LexicalComposer
          key={`o:${open};d:${disabled};v:${value}`}
          initialConfig={{
            editable: open,
            editorState: value,
            ...COMMON_CONFIG,
          }}
        >
          <styled.div
            tabIndex={0}
            onClick={() => {
              if (disabled) return

              setOpen(true)
            }}
            data-disabled={disabled ? true : undefined}
            data-error={error ? true : undefined}
            style={{
              position: 'relative',
              display: 'flex',
              border: `1px solid ${colors.neutral20Adjusted}`,
              borderRadius: radius[8],
              '&[data-disabled]': {
                color: colors.neutral20,
                background: colors.neutral5,
                border: `1px solid transparent`,
              },
              '&[data-error]:not([data-disabled])': {
                border: `1px solid ${colors.red80}`,
              },
              '&:not([data-error]):not([data-disabled]):focus-visible': {
                background: colors.neutralInverted100,
                border: `1px solid ${colors.neutral100}`,
                outline: `4px solid ${colors.neutral20}`,
              },
              '&[data-error]:focus-visible': {
                background: colors.neutralInverted100,
                border: `1px solid ${colors.red100}`,
                outline: `4px solid ${colors.red60}`,
              },
              '&:not([data-disabled]):focus-visible > .overlay, &:not([data-disabled]):hover > .overlay':
                {
                  display: 'flex !important',
                },
              ...EDITOR_STYLES,
            }}
          >
            <div
              className="overlay"
              style={{
                position: 'absolute',
                inset: 0,
                backdropFilter: 'blur(4px)',
                background: colors.neutralInverted80,
                display: 'none',
                justifyContent: 'center',
                alignItems: 'center',
                borderRadius: radius[8],
                color: colors.neutral80,
                gap: 4,
                zIndex: 3,
              }}
              onClick={() => {
                if (disabled) return

                setOpen(true)
              }}
            >
              <Icon variant="full-screen" />
              <Text variant="subtext-medium" color="inherit">
                Click to edit
              </Text>
            </div>
            <div style={{ pointerEvents: 'none', width: '100%' }}>
              <RichTextPlugin
                contentEditable={
                  <ContentEditable
                    className="editor"
                    style={{
                      outline: 'none',
                      padding: '6px 8px',
                      width: '100%',
                      height: 200,
                      overflow: 'hidden',
                    }}
                  />
                }
                placeholder={
                  <div style={{ position: 'absolute', left: 8, top: 6 }}>
                    <Text color="neutral60" variant="display-regular">
                      {placeholder}
                    </Text>
                  </div>
                }
                ErrorBoundary={LexicalErrorBoundary}
              />
            </div>
          </styled.div>
          <ListPlugin />
        </LexicalComposer>
      </div>
    )

  return (
    <div
      style={{
        position: 'fixed',
        inset: 0,
        background: colors.neutralInverted100,
        zIndex: 3,
      }}
    >
      <LexicalComposer initialConfig={COMMON_CONFIG}>
        <Toolbar onOpenChange={setOpen} />
        <styled.div
          style={{
            position: 'relative',
            display: 'flex',
            justifyContent: 'center',
            height: 'calc(100% - 49px)',
            overflowY: 'auto',
            overflowX: 'hidden',
            ...EDITOR_STYLES,
          }}
        >
          <RichTextPlugin
            contentEditable={
              <ContentEditable
                className="editor"
                style={{
                  outline: 'none',
                  padding: '16px 24px',
                  width: '100%',
                  maxWidth: 750,
                  minHeight: 600,
                  margin: '0 auto',
                }}
              />
            }
            placeholder={
              <div
                style={{
                  position: 'absolute',
                  left: 0,
                  right: 0,
                  top: 0,
                  pointerEvents: 'none',
                }}
              >
                <div
                  style={{
                    width: '100%',
                    maxWidth: 750,
                    padding: '16px 24px',
                    margin: '0 auto',
                  }}
                >
                  <Text color="neutral60" variant="display-regular">
                    {placeholder}
                  </Text>
                </div>
              </div>
            }
            ErrorBoundary={LexicalErrorBoundary}
          />
        </styled.div>
        <BehaviourPlugin />
        <ValuePlugin value={value} onChange={onChange} />
        <ListPlugin />
        <LinkPlugin />
        <HistoryPlugin />
        <FloatingLinkPlugin />
      </LexicalComposer>
    </div>
  )
}

export { RichTextEditor }
export type { RichTextEditorProps }
