import { FontIcon, ListItem, Menu } from "@sc/components/ui";
import theme from "@sc/components/ui/theme";
import EditorObject from "@sc/modules/page/Builder/EditorObject";
import * as Tools from "@sc/modules/page/Builder/Properties";
import _ from "lodash";
import React from "react";

import LiveColumn from "./columnComponent";

const CURSOR_ID = 1111;

const Content = (props) => {
  const childContent = props.pageContent.filter(
    (itm) => itm.parent === props.settings.id
  );
  let isEmpty = false;
  if (childContent.length) {
    isEmpty = !!(childContent.length === 1 && childContent[0].id === CURSOR_ID);
  } else isEmpty = true;

  const defaultStyle = isEmpty ? { padding: 40 } : {};

  return <LiveColumn {...props} style={defaultStyle} />;
};

const BasicPropertiesTab = (props) => (
  <div style={{ width: "100%" }}>
    <Tools.Background
      {...props}
      accept="image/jpeg, image/png, video/mp4, video/ogg"
      isExpanded
    />
    <Tools.Section label="Padding" icon="import_export">
      <Tools.Padding {...props} />
    </Tools.Section>
    <Tools.BordersShadow {...props} hideBorderRadius hideShadow />
  </div>
);

const Properties = (props) => (
  <Tools.PropertiesWindow
    {...props}
    defaultTab="basic"
    tabs={[{ id: "basic", title: "Column", component: BasicPropertiesTab }]}
  />
);

const ColumnDropDownMenu = (props) => {
  const { settings, pageContent, updateContent, showProperties } = props;
  const theColumns = pageContent.filter(
    (itm) => itm.parent === settings.parent
  );

  const handleDropdownChange = (id) => {
    if (id === "add") {
      // resize existing item (cut in half), then duplicate it
      const columnSettings = {};
      const newColSettings = {};
      if (settings.hasOwnProperty("md")) {
        columnSettings.md = Math.round(settings.md / 2);
        newColSettings.md = settings.md - columnSettings.md;
      }
      if (settings.hasOwnProperty("xs")) {
        columnSettings.xs = Math.round(settings.xs / 2);
        newColSettings.xs = settings.xs - columnSettings.xs;
      }
      if (settings.hasOwnProperty("lg")) {
        columnSettings.lg = Math.round(settings.lg / 2);
        newColSettings.lg = settings.lg - columnSettings.lg;
      }
      if (settings.hasOwnProperty("sm")) {
        columnSettings.sm = Math.round(settings.sm / 2);
        newColSettings.sm = settings.sm - columnSettings.sm;
      }

      const updatedSettings = [
        {
          ...settings,
          ...columnSettings,
          state: "active",
        },
        {
          ...settings,
          ...newColSettings,
          id: Math.random()
            .toString(36)
            .slice(2),
        },
      ];

      const key = pageContent.findIndex((itm) => itm.id === settings.id);

      const content = [
        ...pageContent.slice(0, key),
        ...updatedSettings,
        ...pageContent.slice(key + 1),
      ];

      updateContent(content);
    }

    if (id === "delete") {
      // update parent without content & let the nearby column take up the remainining columns
      const siblings = pageContent.filter(
        (itm) => itm.parent === settings.parent
      );
      const leftKey = siblings.findIndex((itm) => itm.id === settings.id);

      const leftCol = siblings[leftKey];
      const rightCol =
        siblings.length - 1 > leftKey ? siblings[leftKey + 1] : false;

      // Update the Content
      const contentWithoutLeftColumn = pageContent.filter(
        (itm) => itm.id !== settings.id
      );

      // b. build second column
      let contentWithRightColumnUpdated = contentWithoutLeftColumn;
      if (rightCol) {
        const rightKey = contentWithRightColumnUpdated.findIndex(
          (itm) => itm.id === rightCol.id
        );
        contentWithRightColumnUpdated = [
          ...contentWithoutLeftColumn.slice(0, rightKey),
          {
            ...rightCol,
            md: rightCol.md + leftCol.md,
          },
          ...contentWithoutLeftColumn.slice(rightKey + 1),
        ];
      }

      // c. perform update
      updateContent(contentWithRightColumnUpdated);
    }

    if (id === "properties") {
      props.changeState(settings.id, "active", () => {
        showProperties();
      });
    }
  };

  return (
    <Menu
      onClick={(e) => {
        e.stopPropagation();
        console.log("CLICKED!!");
        props.changeState(settings.id, "active");
      }}
      position="BOTTOM_RIGHT"
      id="avatar-menu"
      icon={
        <FontIcon
          className="arrdropdown"
          style={{ zoom: "90%", color: "#666", marginTop: 10 }}
        >
          arrow_drop_down
        </FontIcon>
      }
    >
      <ListItem
        onClick={(e) => {
          e.stopPropagation();
          handleDropdownChange("properties");
        }}
      >
        Column Properties
      </ListItem>
      {_.filter(pageContent, (itm) => itm.id === settings.parent)[0].type ===
      "Columns" ? (
        <ListItem
          onClick={(e) => {
            e.stopPropagation();
            handleDropdownChange("add");
          }}
        >
          Add Column
        </ListItem>
      ) : (
        <div />
      )}
      {theColumns.length > 2 ? (
        <ListItem
          onClick={(e) => {
            e.stopPropagation();
            handleDropdownChange("delete");
          }}
        >
          Delete
        </ListItem>
      ) : (
        <div />
      )}
    </Menu>
  );
};

const TheColumn = (props) => {
  const { settings, pageContent, getMobileState, changeState } = props;

  const theColumns = pageContent.filter(
    (itm) => itm.parent === settings.parent
  );
  const key = theColumns.findIndex((itm) => itm.id === settings.id);

  const currentMobileState = getMobileState();
  const hash = {
    smartphone: "xs",
    tablet: "sm",
    desktop: "md",
    fullscreen: "lg",
  };
  const mKey = hash[currentMobileState.type];

  let oldWidthChange = false;
  let oldLeftCol = false;

  const handleResize = (fn, monitor) => {
    const { pageContent, settings, parentCoordinates, updateContent } = props;

    // Where is my mouse?
    const initialClientOffset = monitor.getInitialClientOffset();
    const clientOffset = monitor.getClientOffset();

    // How far have I dragged this?
    const widthChange = clientOffset.x - initialClientOffset.x;

    // cancel if the same
    if (widthChange === oldWidthChange) return;
    oldWidthChange = widthChange;

    // change the width of the object to the right and this object
    // 1. get width of each
    const siblings = pageContent.filter(
      (itm) => itm.parent === settings.parent
    );
    const key = siblings.findIndex((itm) => itm.id === settings.id);
    const parentObject = pageContent.filter(
      (itm) => itm.id === settings.parent
    )[0];

    let parentWidth = parentCoordinates.width;
    if (parentObject.properties.hasOwnProperty("width")) {
      if (parentObject.properties.width !== "100%") {
        parentWidth = parentObject.properties.width;
      }
    }
    const singleColWidth = parentWidth / 100;

    // am i at the end? (do this to determine what is left vs right)
    const leftCol =
      key === siblings.length - 1 ? siblings[key - 1] : siblings[key];
    const leftColWidth =
      leftCol[mKey] * singleColWidth || leftCol.md * singleColWidth;

    const rightCol =
      key === siblings.length - 1 ? siblings[key] : siblings[key + 1];
    const rightColWidth =
      rightCol[mKey] * singleColWidth || rightCol.md * singleColWidth;

    // 2. reduce the first by the amount
    const newLeftWidth = leftColWidth + widthChange;
    const newLeftCol = Math.round(100 / (parentWidth / newLeftWidth));

    const newLeftColObj = {};
    newLeftColObj[mKey] = newLeftCol;

    // 3. increase the second by the amount
    const newRightWidth = rightColWidth - widthChange;
    const newRightCol = Math.round(100 / (parentWidth / newRightWidth));

    const newRightColObj = {};
    newRightColObj[mKey] = newRightCol;

    // cancel if the same (or out of bounds)
    if (
      newLeftCol === oldLeftCol ||
      newLeftCol < 3 ||
      newLeftCol > 100 ||
      Math.abs(newLeftCol - oldLeftCol) < 2
    )
      return;
    oldLeftCol = newLeftCol;

    // 4. Now Update the Content
    // a. build first column
    const leftKey = pageContent.findIndex((itm) => itm.id === leftCol.id);
    const contentWithLeftColumnUpdated = [
      ...pageContent.slice(0, leftKey),
      {
        ...leftCol,
        ...newLeftColObj,
      },
      ...pageContent.slice(leftKey + 1),
    ];

    // b. build second column
    let contentWithRightColumnUpdated = contentWithLeftColumnUpdated;
    if (rightCol) {
      const rightKey = contentWithLeftColumnUpdated.findIndex(
        (itm) => itm.id === rightCol.id
      );
      contentWithRightColumnUpdated = [
        ...contentWithLeftColumnUpdated.slice(0, rightKey),
        {
          ...rightCol,
          ...newRightColObj,
        },
        ...contentWithLeftColumnUpdated.slice(rightKey + 1),
      ];
    }

    // console.log(newLeftCol, newRightCol, parentWidth, widthChange);

    // c. perform update
    updateContent(contentWithRightColumnUpdated, true);
  };

  const handleResizeEnd = (myProps, monitor, component) => {
    console.log("Resize has ended!", myProps, monitor, component);
  };

  let rH = false;
  if (theColumns.length > 1) rH = key !== theColumns.length - 1 ? ["E"] : ["W"];

  let borderStyle = { border: "1px solid transparent", margin: 0 };
  if (
    theColumns.findIndex((itm) => itm.state === "hover") > -1 &&
    props.history.location.pathname.indexOf("/preview") === -1
  ) {
    borderStyle = { border: `1px solid ${theme.altColor[1]}`, margin: 0 };
  }

  const onClick = props.showingProperties
    ? {}
    : {
        onClick: () => changeState(settings.parent, "active"),
      };

  return (
    <EditorObject
      {...props}
      resizeHandles={rH}
      isResizable={rH !== false}
      onResize={handleResize}
      onResizeEnd={handleResizeEnd}
      PropertiesView={Properties}
      resizeHandleColor={theme.altColor[1]}
      color="transparent"
      dragHandle={false}
      draggable={false}
      onDragStart={(e) => {
        e.preventDefault();
      }}
      {...onClick}
      style={{ height: "100%" }}
    >
      {(settings.state === "hover" ||
        settings.state === "active" ||
        props.showResize) &&
      props.history.location.pathname.indexOf("/preview") === -1 ? (
        <div
          style={{
            display: "inline",
            position: "absolute",
            cursor: "pointer",
            top: -7,
            right: 0,
            zIndex: 10,
          }}
        >
          <ColumnDropDownMenu {...props} />
        </div>
      ) : null}
      <Content {...props} borderStyle={borderStyle} />
    </EditorObject>
  );
};

export default TheColumn;
