import { SendOutlined, SmileOutlined } from '@ant-design/icons';
import { Popover } from 'antd';
import React, { FC, useMemo, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { Transforms, createEditor, BaseEditor, Text, Descendant, Editor, Node, Path } from 'slate';
import { Slate, Editable, withReact, ReactEditor, useSelected, useFocused } from 'slate-react';
import dynamic from 'next/dynamic';
import WebsocketService from '../../../services/websocket-service';
import { websocketServiceAtom } from '../../stores/ClientConfigStore';
import { MessageType } from '../../../interfaces/socket-events';
import styles from './ChatTextField.module.scss';
// Lazy loaded components
const EmojiPicker = dynamic(() => import('./EmojiPicker').then(mod => mod.EmojiPicker));
type CustomElement = { type: 'paragraph' | 'span'; children: CustomText[] } | ImageNode;
type CustomText = { text: string };
type EmptyText = {
  text: string;
};
type ImageNode = {
  type: 'image';
  alt: string;
  src: string;
  name: string;
  children: EmptyText[];
};
declare module 'slate' {
  interface CustomTypes {
    Editor: BaseEditor & ReactEditor;
    Element: CustomElement;
    Text: CustomText;
  }
}
const Image = p => {
  const { attributes, element, children } = p;
  const selected = useSelected();
  const focused = useFocused();
  return (
    
      
      {children}
    
  );
};
const withImages = editor => {
  const { isVoid } = editor;
  // eslint-disable-next-line no-param-reassign
  editor.isVoid = element => (element.type === 'image' ? true : isVoid(element));
  // eslint-disable-next-line no-param-reassign
  editor.isInline = element => element.type === 'image';
  return editor;
};
const serialize = node => {
  if (Text.isText(node)) {
    const string = node.text;
    return string;
  }
  let children;
  if (node.children.length === 0) {
    children = [{ text: '' }];
  } else {
    children = node.children?.map(n => serialize(n)).join('');
  }
  switch (node.type) {
    case 'paragraph':
      return `
${children}
`;
    case 'image':
      return `
`;
    default:
      return children;
  }
};
export type ChatTextFieldProps = {};
export const ChatTextField: FC = () => {
  const [showEmojis, setShowEmojis] = useState(false);
  const websocketService = useRecoilValue(websocketServiceAtom);
  const editor = useMemo(() => withReact(withImages(createEditor())), []);
  const defaultEditorValue: Descendant[] = [
    {
      type: 'paragraph',
      children: [{ text: '' }],
    },
  ];
  const sendMessage = () => {
    if (!websocketService) {
      console.log('websocketService is not defined');
      return;
    }
    const message = serialize(editor);
    websocketService.send({ type: MessageType.CHAT, body: message });
    // Clear the editor.
    Transforms.delete(editor, {
      at: {
        anchor: Editor.start(editor, []),
        focus: Editor.end(editor, []),
      },
    });
  };
  const createImageNode = (alt, src, name): ImageNode => ({
    type: 'image',
    alt,
    src,
    name,
    children: [{ text: '' }],
  });
  const insertImage = (url, name) => {
    if (!url) return;
    const { selection } = editor;
    const image = createImageNode(name, url, name);
    Transforms.insertNodes(editor, image, { select: true });
    if (selection) {
      const [parentNode, parentPath] = Editor.parent(editor, selection.focus?.path);
      if (editor.isVoid(parentNode) || Node.string(parentNode).length) {
        // Insert the new image node after the void node or a node with content
        Transforms.insertNodes(editor, image, {
          at: Path.next(parentPath),
          select: true,
        });
      } else {
        // If the node is empty, replace it instead
        // Transforms.removeNodes(editor, { at: parentPath });
        Transforms.insertNodes(editor, image, { at: parentPath, select: true });
        Editor.normalize(editor, { force: true });
      }
    } else {
      // Insert the new image node at the bottom of the Editor when selection
      // is falsey
      Transforms.insertNodes(editor, image, { select: true });
    }
  };
  const onEmojiSelect = (e: any) => {
    ReactEditor.focus(editor);
    if (e.url) {
      // Custom emoji
      const { url } = e;
      insertImage(url, url);
    } else {
      // Native emoji
      const { emoji } = e;
      Transforms.insertText(editor, emoji);
    }
  };
  const onCustomEmojiSelect = (e: any) => {
    ReactEditor.focus(editor);
    const { url } = e;
    insertImage(url, url);
  };
  const onKeyDown = (e: React.KeyboardEvent) => {
    if (e.key === 'Enter') {
      e.preventDefault();
      sendMessage();
    }
  };
  const renderElement = p => {
    switch (p.element.type) {
      case 'image':
        return ;
      default:
        return ;
    }
  };
  return (
    
      
        
          
          
            }
            trigger="click"
            onVisibleChange={visible => setShowEmojis(visible)}
            visible={showEmojis}
          />
        
        
          
          
        
       
     
  );
};