import type { PopoverProps } from '@os-design/core';
import { EditorState, RichUtils } from 'draft-js';
import React, { useCallback, useMemo } from 'react';
import Toolbar from './Toolbar.js';
import ToolbarButton from './ToolbarButton.js';
import type { StyleToolbarItem } from './utils/defaultStyleToolbarItems.js';
import setLink from './utils/setLink.js';
import unsetLink from './utils/unsetLink.js';

interface StyleToolbarProps extends Omit<PopoverProps, 'onChange'> {
  items: StyleToolbarItem[];
  value: EditorState;
  onChange: (value: EditorState) => void;
}

const StyleToolbar: React.FC<StyleToolbarProps> = ({
  items,
  value,
  onChange = () => {},
  ...rest
}) => {
  const currentBlockType = useMemo(
    () => RichUtils.getCurrentBlockType(value),
    [value]
  );
  const currentBlockContainsLink = useMemo(
    () => RichUtils.currentBlockContainsLink(value),
    [value]
  );

  const toggleLink = useCallback(() => {
    if (currentBlockContainsLink) {
      onChange(unsetLink(value));
      return;
    }
    const url = prompt('Paste or type a link');
    if (!url) return;
    onChange(setLink(value, url));
  }, [currentBlockContainsLink, value, onChange]);

  const clickHandler = useCallback<(item: StyleToolbarItem) => void>(
    (item) => {
      if (item.type === 'inline') {
        onChange(RichUtils.toggleInlineStyle(value, item.name));
      } else if (item.type === 'block') {
        onChange(RichUtils.toggleBlockType(value, item.name));
      }
    },
    [value, onChange]
  );

  if (items.length === 0) return null;

  return (
    <Toolbar {...rest}>
      {items.map((item) => {
        const isLink = item.name === 'LINK' && item.type === 'inline';

        const active = isLink
          ? currentBlockContainsLink
          : value.getCurrentInlineStyle().has(item.name) ||
            currentBlockType === item.name;
        const onClick = isLink ? toggleLink : () => clickHandler(item);

        return (
          <ToolbarButton key={item.name} active={active} onClick={onClick}>
            {item.icon}
          </ToolbarButton>
        );
      })}
    </Toolbar>
  );
};

StyleToolbar.displayName = 'StyleToolbar';

export default StyleToolbar;
