import * as React from "react";
import { get, head } from "lodash";
import { useDrag } from "react-dnd";
import { IconTypes } from "@sc/plugins/webcomponents/v2/Icon";

import ComponentWrapper from "../ComponentWrapper";
import { EditorObjectProps, EditorObjectState } from "./types";
import { EditorContext } from "../../Editor";
import { DragHandle } from "./DragHandle";
import { DragTypes, CURSOR_ID, EditorActions } from "../../types";

export enum AddTypes {
  BEFORE = "Before",
  AFTER = "After",
  INSIDE = "Inside",
}

const dragComplete = (item, monitor, { editor, id }) => {
  const dropResult = monitor.getDropResult();
  if (item && dropResult) {
    console.log(`The drag ended with ${id} on top of ${dropResult.id}`, item);
    // editor.dispatch({
    //   type: EditorActions.MOVE_THIS_BY_THAT,
    //   payload: { id1: id, id2: CURSOR_ID },
    //   // payload: { id1: id, id2: dropResult.id },
    // });
  }
};

/**
 * A component that makes child components compatible with the editor, enables drag-and-drop, serves widget toolbars, properties, etc.
 *
 * Each component in the editor should wrap itself with this component.
 *
 * This is the component that highlights the object in various ways to let the user know what they are editing at a given time
 */
export const EditorObject: React.FC<EditorObjectProps> = ({
  children,
  id,
  title = "Web Component",
  color = "#8b6e9a",
  isEditing = true,
  overlay = false,
  icon = IconTypes.PagesOutlined,
  actions = [],
  onClick = () => false,
}) => {
  const editor = React.useContext(EditorContext);
  const { content } = editor;

  const settings = head(content.filter((itm) => itm.id === id));
  const state = get(settings, "state", EditorObjectState.NORMAL);

  const [{ isDragging }, dragRef] = useDrag({
    item: { ...settings, type: DragTypes.EDITOROBJECT },
    end: (item, monitor) => dragComplete(item, monitor, { editor, id }),
    collect: (monitor) => ({
      isDragging: monitor.isDragging(),
    }),
  });

  const opacity = isDragging ? 0 : 1;

  return (
    <div
      onClick={(e) => {
        e.stopPropagation();
        editor.dispatch({
          type: EditorActions.CHANGE_STATE,
          payload: { id, state: EditorObjectState.ACTIVE },
        });
        onClick();
      }}
      onMouseEnter={(e) => {
        e.stopPropagation();
        if (state !== EditorObjectState.ACTIVE) {
          editor.dispatch({
            type: EditorActions.CHANGE_STATE,
            payload: { id, state: EditorObjectState.HOVER },
          });
        }
      }}
      onMouseLeave={(e) => {
        e.stopPropagation();
        if (state !== EditorObjectState.ACTIVE) {
          editor.dispatch({
            type: EditorActions.CHANGE_STATE,
            payload: { id, state: EditorObjectState.NORMAL },
          });
        }
      }}
      onMouseMove={(e) => {
        e.stopPropagation();
        if (settings.state !== EditorObjectState.HOVER)
          editor.dispatch({
            type: EditorActions.CHANGE_STATE,
            payload: { id, state: EditorObjectState.HOVER },
          });
      }}
      ref={dragRef}
      data-testid="Editor-EditorObject"
      style={{
        opacity,
        border: `1px solid ${
          state === EditorObjectState.NORMAL ? "transparent" : color
        }`,
        margin: -3,
        padding: 3,
        display: "inline-block",
      }}
    >
      <DragHandle
        color={color}
        icon={icon}
        label={title}
        state={state}
        actions={actions}
        id={id}
      />
      <ComponentWrapper id={id}>{children}</ComponentWrapper>
    </div>
  );
};

export { EditorObjectState };
export default EditorObject;
