import _ from "lodash";
import React, { Component } from "react";
import { DropTarget } from "react-dnd";

import ColumnWrapper from "./ColumnWrapper";
import handleCanvasDragDrop from "./handleDragDrop";

export class WebComponent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      objCoordinates: false,
      parentCoordinates: false,
      showingProperties: false,
      isEditing: false,
    };

    this.setIsEditing = this.setIsEditing.bind(this);
    this.showProperties = this.showProperties.bind(this);
    this.hideProperties = this.hideProperties.bind(this);
  }

  componentWillReceiveProps() {
    const closest = (el, className) => {
      while (el.className !== className) {
        el = el.parentNode;
        if (!el) return null;
      }
      return el;
    };

    if (this.parentObject) {
      const {
        top,
        right,
        bottom,
        left,
        width,
        height,
      } = this.parentObject.getBoundingClientRect();
      const objCoordinates = { top, right, bottom, left, width, height };

      const objParent =
        this.props.type === "Column"
          ? closest(this.parentObject.parentNode, "wc")
          : closest(this.parentObject, "wc");

      if (objParent) {
        const pCoords = objParent.parentNode.getBoundingClientRect();

        const parentCoordinates = {
          top: pCoords.top,
          right: pCoords.right,
          bottom: pCoords.bottom,
          left: pCoords.left,
          width: pCoords.width,
          height: pCoords.height,
        };

        this.setState({ objCoordinates, parentCoordinates });
      } else {
        this.setState({ objCoordinates });
      }
    }
  }

  setIsEditing(isEditing) {
    if (this.props.show !== "preview") {
      this.setState({ isEditing });
      console.log("Set Is Editing: ", isEditing);
    }
  }

  showProperties() {
    console.log("showing Properties");
    this.setState({ showingProperties: true });
    const windows = this.props.getActivePropertyWindows();
    this.props.setActivePropertyWindows([...windows, this.props.settings.id]);
  }

  hideProperties() {
    this.setState({ showingProperties: false });

    const windows = this.props.getActivePropertyWindows();
    const newWindows = windows.filter((id) => id !== this.props.settings.id);
    this.props.setActivePropertyWindows(newWindows);
  }

  render() {
    const {
      type,
      settings,
      getMobileState,
      rSettings,
      mode,
      triggerHook,
    } = this.props;

    const pluginComponent = _.head(
      triggerHook(
        "onComponentRender",
        { id: "webcomponent", type: "component", mode },
        settings
      )
    );

    // For mobile rendering
    const currentMobileState = getMobileState();

    const connectDropTarget = _.get(
      this.props,
      "connectDropTarget",
      (ret) => ret
    );

    const componentProps =
      mode === "live"
        ? this.props
        : {
            isEditing: this.state.isEditing,
            setIsEditing: this.setIsEditing,
            objCoordinates: this.state.objCoordinates,
            parentCoordinates: this.state.parentCoordinates,
            settings: {
              ...rSettings,
              properties: _.omit(rSettings.properties, "mobile"),
            },
            showProperties: this.showProperties,
            hideProperties: this.hideProperties,
            showingProperties: this.state.showingProperties,
            key: `wc_${settings.id}`,
          };

    let conditionalStyle = {};
    if (settings.canHaveChildren || type === "Columns") {
      conditionalStyle = {
        height: type === "Column" ? "100%" : "unset",
        display: settings.properties.display || "block",
        justifyContent: settings.properties.justifyContent || "flex-start",
      };

      if (_.has(settings, "properties.height"))
        conditionalStyle.height = settings.properties.height;
    }

    const Comp = (
      <div
        id={settings.id}
        style={{ display: "block", width: "100%", ...conditionalStyle }}
        className={`wc wc-${type.toLowerCase()}`}
        ref={(node) => (this.parentObject = node)}
      >
        {React.createElement(pluginComponent, {
          ...this.props,
          ...componentProps,
        })}
      </div>
    );

    if (type === "Column") {
      const hash = {
        smartphone: "xs",
        tablet: "sm",
        desktop: "md",
        fullscreen: "lg",
      };
      const mKey = hash[currentMobileState.type];

      return (
        <ColumnWrapper
          mKey={mKey}
          settings={settings}
          type={currentMobileState}
          pageContent={this.props.pageContent}
        >
          {connectDropTarget(Comp)}
        </ColumnWrapper>
      );
    }

    return connectDropTarget(Comp);
  }
}

export default DropTarget(
  "box",
  { hover: handleCanvasDragDrop },
  (connect) => ({
    connectDropTarget: connect.dropTarget(),
  })
)(WebComponent);
