import { decode } from "@sc/api/utils";
import Popup from "@sc/plugins/webcomponents/v1/popup/settings";
import { Cell, Grid, ListItem, Menu } from "@sc/components/ui";
import { AppConfig } from "@sc/modules/app";
import objects from "@sc/modules/campaign/shared/objects";

import _ from "lodash";
import React, { Component } from "react";
import { Link } from "react-router-dom";
import { Section } from "..";
import style from "../style";

const NiceMenu = (props) => (
  <div style={{ ...style.selectField, cursor: "pointer", ...props.style }}>
    <Menu {...props} style={{ width: "100%", textAlign: "left" }}>
      <div style={{ maxHeight: 200, overflowY: "scroll" }}>
        {props.children}
      </div>
    </Menu>
  </div>
);

const ComponentSelector = (props) => {
  const {
    listComponents,
    changeState,
    pageContent,
    filterOut,
    filterOnly,
    onChange,
  } = props;

  return (
    <NiceMenu style={{ marginTop: 10 }} label={props.label}>
      {_.map(listComponents(pageContent, filterOut, filterOnly), (itm) => (
        <ListItem
          key={itm.settings.id}
          onClick={() => onChange(itm)}
          leftIcon={_.get(itm, "icon", false)}
          onMouseEnter={() => changeState(itm.settings.id, "hover")}
          onMouseLeave={() => changeState(itm.settings.id, "normal")}
        >
          {_.get(itm, "html", "")}
        </ListItem>
      ))}
      {props.children}
    </NiceMenu>
  );
};

export const GoToUrl = (props) => {
  const { action, updateAction } = props;
  const { payload } = action;

  console.log({ payload });

  return (
    <AppConfig.Consumer>
      {({ app }) => (
        // show dropdown menu of pages, with option to enter url
        <NiceMenu
          style={{ marginTop: 10 }}
          label={_.get(payload, "urlPageName", "Choose a page to link to...")}
        >
          <ListItem
            icon="link"
            onClick={() => {
              const urlPrompt = window.prompt(
                "Enter the url you want to link to",
                _.get(payload, "url", "http://")
              );

              if (urlPrompt) {
                const url =
                  urlPrompt.indexOf("http") > -1
                    ? urlPrompt
                    : `http://${urlPrompt}`;

                updateAction(
                  action,
                  {
                    url,
                    urlPageName: url,
                    useTag: false,
                  },
                  { href: url }
                );
              }
            }}
          >
            Enter a Custom URL
          </ListItem>
          {/* <ListItem
            icon="label"
            onClick={() => {
              const url = window.prompt(
                "Enter the name of the tag you want to use",
                _.get(payload, "url", "")
              );
              updateAction(action, { url, urlPageName: url, useTag: true });
              updateComponentSettings(
                props.settings.id,
                {
                  ...props.settings,
                  href: url
                },
                true,
                false
              );
            }}
          >
            Get Url From Tag Value
          </ListItem> */}

          <ListItem
            icon="skip_next"
            onClick={() => {
              updateAction(
                action,
                {
                  url: "{next_page}",
                  urlPageName: "Go to the next page",
                  useTag: false,
                },
                { href: "{next_page}" }
              );
            }}
          >
            Go to the next page
          </ListItem>

          <div style={style.divider} />
          {_.map(
            _.get(props, "getCampaignQuery.campaign.objects", []),
            (page, key) => {
              const thumbnail = _.head(
                _.filter(
                  _.get(objects, "pages", []),
                  (itm) => itm.pageType === page.page.type
                )
              );

              return (
                <ListItem
                  key={key}
                  onClick={() => {
                    updateAction(
                      action,
                      {
                        url: `/${page.page.slug}/`,
                        urlPageName: page.name,
                        useTag: false,
                      },
                      {
                        href: `/${page.page.slug}/`,
                      }
                    );
                  }}
                >
                  <Grid>
                    <Cell
                      style={{ width: 50, height: 45, textAlign: "center" }}
                    >
                      <img
                        alt="Screenshot"
                        src={_.get(thumbnail, "screenshot", app.logoIcon)}
                        style={{
                          height: "100%",
                          marginTop: 5,
                          border: "5px solid transparent",
                        }}
                      />
                    </Cell>
                    <Cell>
                      <div style={{ fontSize: 14, padding: "20px 10px" }}>
                        {page.name.length > 23
                          ? `${page.name.substring(0, 20)}...`
                          : page.name}
                      </div>
                    </Cell>
                  </Grid>
                </ListItem>
              );
            }
          )}
        </NiceMenu>
      )}
    </AppConfig.Consumer>
  );
};

export const DownloadFile = (props) => {
  const { action, updateAction } = props;
  const { payload } = action;

  return (
    <AppConfig.Consumer>
      {({ app }) => (
        // show dropdown menu of files
        <NiceMenu
          style={{ marginTop: 10 }}
          label={_.get(payload, "urlFileName", "Choose a file...")}
        >
          <ListItem
            icon="link"
            onClick={() => {
              const urlPrompt = window.prompt(
                "Enter the url to the file you want downloaded",
                _.get(payload, "url", "http://")
              );

              if (urlPrompt) {
                const url =
                  urlPrompt.indexOf("http") > -1
                    ? urlPrompt
                    : `http://${urlPrompt}`;

                updateAction(
                  action,
                  {
                    url,
                    urlFileName: url,
                    useTag: false,
                  },
                  { href: url }
                );
              }
            }}
          >
            Enter a Custom URL
          </ListItem>
        </NiceMenu>
      )}
    </AppConfig.Consumer>
  );
};

export class PopupOptions extends React.Component {
  constructor(props) {
    super(props);

    this.createPopupWindow = this.createPopupWindow.bind(this);
    this.setPopup = this.setPopup.bind(this);
    this.showSelectedPopup = this.showSelectedPopup.bind(this);
  }

  componentWillUpdate(newProps) {
    if (this.props.pageContent.length !== newProps.pageContent.length) {
      const oldPageContent = this.props.pageContent;
      const newPageContent = newProps.pageContent;

      this.setState({ pageContent: newPageContent });
      console.log(
        "length",
        this.props.pageContent.length,
        newProps.pageContent.length
      );

      // find the new Popup
      const oldPopups = _.map(
        _.filter(oldPageContent, (itm) => itm.type === "Popup"),
        (itm) => itm.id
      );
      const newPopups = _.map(
        _.filter(newPageContent, (itm) => itm.type === "Popup"),
        (itm) => itm.id
      );

      const difference = _.difference(newPopups, oldPopups);

      if (difference.length) {
        const newPopupId = _.head(difference);
        const newPopupContent = _.head(
          _.filter(newPageContent, (itm) => itm.id === newPopupId)
        );
        console.log({ oldPopups, newPopups, difference, newPopupContent });

        this.setPopup({
          settings: {
            ...newPopupContent,
            id: newPopupId,
          },
        });
      }
    }
  }

  setPopup(itm) {
    const { action, updateAction } = this.props;
    updateAction(action, {
      ..._.get(action, "payload", false),
      showId: itm.settings.id,
      showLabel: itm.settings.name,
    });
  }

  createPopupWindow() {
    const { addThisAfterThat, pageContent } = this.props;

    const bodyObj = _.head(_.filter(pageContent, (itm) => itm.type === "Body"));
    const rootObjs = _.filter(pageContent, (itm) => itm.parent === bodyObj.id);

    const id = _.get(rootObjs, `${rootObjs.length - 1}.id`, false);

    if (id) {
      const name = window.prompt(
        "Please give your Popup Window a name...",
        "Default Popup"
      );
      if (name) {
        addThisAfterThat(
          {
            ...Popup.default,
            children: Popup.default.children.reverse(),
            name,
          },
          id
          // (res) => alert(JSON.stringify({ res }, null, 2))
          // (popup) => this.setPopup(popup)
        );
      }
    }
  }

  showSelectedPopup() {
    const { action, updateComponentSettings, pageContent } = this.props;
    const { showId } = action.payload;
    const component = _.head(_.filter(pageContent, (itm) => itm.id === showId));
    updateComponentSettings(
      showId,
      {
        ...component,
        state: "active",
        properties: {
          ...component.properties,
          display: "block",
        },
      },
      true,
      false
    );
    window.scrollTo(0, 0);
  }

  render() {
    const { action, pageContent } = this.props;
    const { payload } = action;

    const content = _.has(payload, "showId")
      ? _.filter(pageContent, (itm) => itm.id === payload.showId)
      : [];

    return (
      <React.Fragment>
        <ComponentSelector
          {...this.props}
          filterOnly={[["type", "Popup"]]}
          label={
            _.has(payload, "showLabel") && content.length
              ? `Show: ${payload.showLabel}`
              : "Select a Popup to Show..."
          }
          onChange={(itm) => this.setPopup(itm)}
          children={<div />}
        >
          <ListItem leftIcon="open_in_new" onClick={this.createPopupWindow}>
            Create a new Popup Window
          </ListItem>
        </ComponentSelector>
        {_.has(payload, "showLabel") && content.length ? (
          <span onClick={this.showSelectedPopup} style={style.linkStyle}>
            Show Popup Window Now
          </span>
        ) : null}
      </React.Fragment>
    );
  }
}

const ShowHide = (props) => {
  const { action, updateAction } = props;
  const { payload } = action;

  return (
    <React.Fragment>
      <ComponentSelector
        {...props}
        onChange={(itm) =>
          updateAction(action, {
            ..._.get(action, "payload", false),
            showId: itm.settings.id,
            showLabel: itm.html,
          })
        }
        filterOut={[["type", "Body"]]}
        filterOnly={[["canHaveChildren", true]]}
        label={
          _.has(payload, "showLabel")
            ? `Show: ${payload.showLabel}`
            : "Select an Item to Show..."
        }
        children={<div />}
      />
      <ComponentSelector
        {...props}
        onChange={(itm) =>
          updateAction(action, {
            ..._.get(action, "payload", false),
            hideId: itm.settings.id,
            hideLabel: itm.html,
          })
        }
        filterOut={[["type", "Body"]]}
        filterOnly={[["canHaveChildren", true]]}
        label={
          _.has(payload, "hideLabel")
            ? `Hide: ${payload.hideLabel}`
            : "Select an Item to Hide..."
        }
        children={<div />}
      />
    </React.Fragment>
  );
};

const CreateTag = (props) => {
  const { action, updateAction } = props;
  const { payload } = action;

  const tagName = _.get(payload, "tagName", "");
  const tagValue = _.get(payload, "tagValue", "");

  return (
    <div>
      <TextInput
        placeholder="Name of Tag"
        style={{ marginTop: 10 }}
        value={tagName}
        onBlur={(e) =>
          updateAction(action, { tagValue, tagName: e.target.value })
        }
        focusOnMount
        focusOnClick
      />
      <TextInput
        placeholder="(Optional) Value of tag"
        style={{ marginTop: 10 }}
        value={tagValue}
        onBlur={(e) =>
          updateAction(action, { tagName, tagValue: e.target.value })
        }
        focusOnClick
      />
    </div>
  );
};

class Payload extends Component {
  constructor(props) {
    super(props);
    this.updateAction = this.updateAction.bind(this);
  }

  static contextType = AppConfig;

  updateAction(action, payload, newSettings = {}) {
    const { setAction, myKey } = this.props;
    setAction(myKey || 0, { ...action, payload }, action.behavior, newSettings);
  }

  componentDidMount() {
    console.log("The Payload is", this.props.action.payload);
  }

  render() {
    const { app } = this.context;
    const { type, action, match, getPageQuery } = this.props;
    const { campaignId, nodeId } = match.params;

    const pageSettings = getPageQuery.page.pageSettings;

    const storedEmailPayload = _.get(pageSettings, "email.payload", false);
    const emailPayload = storedEmailPayload
      ? JSON.parse(decode(storedEmailPayload))
      : false;

    if (type === "GO_TO_URL" || type === "SUBMIT_FORM")
      return (
        <React.Fragment>
          <GoToUrl
            action={action}
            updateAction={this.updateAction}
            {...this.props}
          />
          {type === "SUBMIT_FORM" && (
            <Link
              to={`/campaign/${campaignId}/${nodeId}/email/${
                app.showProviderStep && !_.has(emailPayload, "campaignId")
                  ? "provider"
                  : "campaign"
              }`}
            >
              <span style={style.linkStyle}>Open Campaign Settings</span>
            </Link>
          )}
        </React.Fragment>
      );
    if (type === "DOWNLOAD_FILE")
      return (
        <DownloadFile
          action={action}
          updateAction={this.updateAction}
          {...this.props}
        />
      );
    if (type === "OPEN_POPUP")
      return (
        <PopupOptions
          {...this.props}
          action={action}
          updateAction={this.updateAction}
        />
      );
    if (type === "TRIGGER_PURCHASE")
      return (
        <React.Fragment>
          {/* <PurchaseOptions action={action} updateAction={this.updateAction} /> */}
          <Link to={`/campaign/${campaignId}/${nodeId}/merchant/index`}>
            <span style={style.linkStyle}>Open Payment Settings</span>
          </Link>
        </React.Fragment>
      );
    if (type === "TRIGGER_UPSELL")
      return (
        <Link to={`/campaign/${campaignId}/${nodeId}/merchant/index`}>
          <span style={style.linkStyle}>Open Payment Settings</span>
        </Link>
      );
    if (type === "SHOW_AND_HIDE")
      return (
        <ShowHide
          {...this.props}
          action={action}
          updateAction={this.updateAction}
        />
      );
    if (type === "CREATE_TAG")
      return (
        <CreateTag
          {...this.props}
          action={action}
          updateAction={this.updateAction}
        />
      );
    return null;
  }
}

class Interaction extends Component {
  constructor(props) {
    super(props);

    this.updateAction = this.updateAction.bind(this);
  }

  static contextType = AppConfig;

  updateAction(action, behavior) {
    const { setAction, myKey } = this.props;
    setAction(myKey || 0, action, behavior);
  }

  render() {
    // const { app } = this.context;
    const {
      label,
      action,
      behavior,
      setAction,
      myKey,
      onlyTheseActions = false,
    } = this.props;

    const actions = [
      {
        type: "DO_NOTHING",
        name: "Do Nothing",
        payload: false,
      },
      {
        type: "TRIGGER_NEXT_NODE",
        name: "Go to the next page",
        payload: {
          url: "{next_page}",
        },
      },
      {
        type: "GO_TO_URL",
        name: "Go to a Specific Page",
      },
      {
        type: "DOWNLOAD_FILE",
        name: "Download a File",
      },
      {
        type: "OPEN_POPUP",
        name: "Show a Popup Window",
        payload: false,
      },
      {
        type: "SUBMIT_FORM",
        name: "Submit this Form",
        payload: {
          url: "{next_page}",
          urlPageName: "Go to the next page",
          useTag: false,
        },
      },
      {
        type: "TRIGGER_PURCHASE",
        name: "Purchase Items (New card)",
        payload: false,
      },
      {
        type: "TRIGGER_UPSELL",
        name: "Purchase Items (One Click Upsell)",
        payload: false,
      },
      // ...(app.ecommerce
      //   ? {
      //       type: "ADD_TO_CART",
      //       name: "Add Item To Cart",
      //       payload: false
      //     }
      //   : {}),
      // ...(app.ecommerce
      //   ? {
      //       type: "REMOVE_FROM_CART",
      //       name: "Remove Item From Cart",
      //       payload: false
      //     }
      //   : {})
      {
        type: "SHOW_AND_HIDE",
        name: "Show / Hide Items",
        payload: false,
      },
      {
        type: "CREATE_TAG",
        name: "Create/Update Tag",
        payload: false,
      },
    ];

    return (
      <div>
        <fieldset style={style.fieldset} title={label}>
          <legend>{label}</legend>
          <div style={{ padding: "5px 10px" }}>
            <NiceMenu label={action.name}>
              {actions
                .filter((itm) => {
                  if (!onlyTheseActions) return true;
                  return onlyTheseActions.indexOf(itm.type) > -1;
                })
                .map((itm, key) => (
                  <ListItem
                    key={key}
                    onClick={() => this.updateAction(itm, behavior)}
                  >
                    {itm.name}
                  </ListItem>
                ))}
            </NiceMenu>

            {action.hasOwnProperty("payload") ? (
              <Payload
                {...this.props}
                setAction={setAction}
                type={action.type}
                action={action}
                myKey={myKey}
              />
            ) : null}
          </div>
        </fieldset>
      </div>
    );
  }
}

export default class Interactions extends Component {
  constructor(props) {
    super(props);

    this.state = {
      // actions: props.settings.hasOwnProperty("actions")
      actions: _.get(props, "settings.actions", false)
        ? props.settings.actions
        : [
            {
              type: "DO_NOTHING",
              behavior: "click",
              name: "Do this...",
            },
          ],
    };

    this.setAction = this.setAction.bind(this);
  }

  setAction(key, action, behavior, newSettings = {}) {
    console.log({ key, action, props: this.props });

    this.setState(
      (prevState) => ({
        actions: [
          ...prevState.actions.slice(0, key),
          {
            ...action,
            behavior,
            payload: _.get(action, "payload", false),
          },
          ...prevState.actions.slice(key + 1),
        ],
      }),
      () => {
        console.log("updating actions", {
          ...this.props.settings,
          actions: this.state.actions,
        });

        this.props.updateComponentSettings(
          this.props.settings.id,
          {
            ...this.props.settings,
            actions: this.state.actions,
            ...newSettings,
          },
          true,
          false
        );

        this.props.onUpdate(this.state.actions);
      }
    );
  }

  render() {
    const { actions } = this.state;

    return (
      <Section label="Interactions" icon="link" {...this.props}>
        {this.props.children}
        {actions.map((action, key) => (
          <Interaction
            {...this.props}
            behavior={this.props.behavior || "click"}
            label={_.get(this.props, "label", "When Object is Clicked...")}
            action={action}
            myKey={key}
            key={key}
            setAction={this.setAction}
          />
        ))}
      </Section>
    );
  }
}

Interactions.defaultProps = {
  onUpdate: () => false,
};
