import { ListItem, Menu } from "@sc/components/ui";
import { Switch } from "@sc/components/ui/Inputs";
import EditorObject from "@sc/modules/page/Builder/EditorObject";
import * as Tools from "@sc/modules/page/Builder/Properties";
import { FancySelector, Icon } from "@sc/modules/page/Builder/Properties";
import _ from "lodash";
import React, { Component } from "react";
import fieldNames from "./fieldNames";
import selectOptions from "./selectOptions";
import style from "./style";

// Use DOMPurify.sanitize(<html>) (import DOMPurify from 'dompurify') on html
// elements to prevent xss scripts when using dangerouslySetInnerHTML

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 showAsSelect = (name) => {
  return (
    name === "country" ||
    name === "state" ||
    name === "cardType" ||
    name === "expirationMonth" ||
    name === "expirationYear" ||
    name === "shippingMethod" ||
    name === "billingModel"
  );
};

const getSelectionOptions = (name) => [selectOptions[name][0]];

const FormFieldContentEdit = (props) => {
  const type = showAsSelect(props.settings.name) ? "select" : "text";
  const fieldType = _.get(props.settings, "fieldType", type);

  return (
    <EditorObject {...props} PropertiesView={Properties}>
      <div style={{ marginTop: 0, padding: 0 }}>
        {fieldType === "select" ? (
          <div>
            <div style={style.coverObject} />
            <select
              disabled
              {...props.settings}
              style={{
                ...style.span,
                ...style.select,
                ...props.settings.properties,
                marginTop: 0,
                cursor: "move",
              }}
            >
              {getSelectionOptions(props.settings.name).map((itm, key) => (
                <option key={key} value={itm.name}>
                  {itm.value}
                </option>
              ))}
            </select>
          </div>
        ) : null}

        {fieldType === "text" ? (
          <input
            type="text"
            disabled
            {..._.omit(props.settings, "fieldType", "isRequired")}
            placeholder={`${props.settings.placeholder}${
              _.get(props, "settings.isRequired", false) ? " *" : ""
            }`}
            style={{
              ...style.span,
              cursor: "move",
              ...props.settings.properties,
              marginTop: 0,
            }}
          />
        ) : null}

        {fieldType === "textarea" ? (
          <textarea
            disabled
            {...props.settings}
            placeholder={`${props.settings.placeholder}${
              _.get(props, "settings.isRequired", false) ? " *" : ""
            }`}
            style={{
              ...style.span,
              cursor: "move",
              ...props.settings.properties,
              marginTop: 0,
            }}
          />
        ) : null}
      </div>
    </EditorObject>
  );
};

const FormField = (props) => {
  const { settings } = props;
  const marginTop = settings.properties ? settings.properties.marginTop : 0;
  const textAlign = settings.properties
    ? settings.properties.textAlign
    : "inherit";

  return (
    <div style={{ marginTop, textAlign }}>
      <FormFieldContentEdit {...props} />
    </div>
  );
};

class BasicPropertiesTab extends Component {
  constructor(props) {
    super(props);
    this.state = {
      placeholder: this.props.settings.placeholder || "",
      isRequired: _.get(this.props, "settings.isRequired", false),
    };
    this.handleChange = this.handleChange.bind(this);
    this.onNameChange = this.onNameChange.bind(this);
  }

  handleChange(e) {
    this.setState(
      {
        placeholder: e.target.value,
      },
      () => {
        this.props.updateComponentSettings(
          this.props.settings.id,
          {
            ...this.props.settings,
            placeholder: this.state.placeholder,
          },
          false
        );
      }
    );
  }

  doChange() {
    this.props.updateComponentSettings(
      this.props.settings.id,
      {
        ...this.props.settings,
        placeholder: this.state.placeholder,
      },
      true
    );
  }

  onNameChange(type) {
    this.props.updateComponentSettings(
      this.props.settings.id,
      {
        ...this.props.settings,
        name: type.name,
        placeholder: type.label,
        fieldType: showAsSelect(type.name) ? "select" : "text",
      },
      true,
      false
    );

    this.setState({ placeholder: type.label });
  }

  render() {
    const inputTypes = [
      {
        id: "text",
        component: (props) => <Icon {...props} icon="input" />,
        label: "Single Line",
      },
      {
        id: "textarea",
        component: (props) => <Icon {...props} icon="wrap_text" />,
        label: "Multi-Line",
      },
    ];

    return (
      <div style={{ width: "100%" }}>
        <Tools.Section
          {...this.props}
          label="Text Content"
          icon="text_fields"
          isExpanded
        >
          <fieldset style={{ ...style.fieldset, paddingLeft: 15 }}>
            <legend>Placeholder Text...</legend>
            <input
              placeholder="Type Placeholder Text"
              value={this.state.placeholder}
              ref={(el) => (this.input = el)}
              onMouseDown={() => this.input.select()}
              onChange={this.handleChange}
              onKeyUp={this.handleKeyUp}
              onFocus={() => this.props.setIsEditing(true)}
              onBlur={() => {
                this.props.setIsEditing(false);
                this.doChange();
              }}
              style={{
                padding: 10,
                width: "100%",
                borderRadius: 5,
                // border: "1px solid #CCC"
                border: "none",
              }}
            />
          </fieldset>
          <fieldset style={{ ...style.fieldset, paddingLeft: 15 }}>
            <legend>Field Type...</legend>
            <NiceMenu
              style={{ marginTop: 10, width: "95%" }}
              label={
                this.props.settings.hasOwnProperty("name")
                  ? _.get(
                      _.head(
                        _.filter(
                          fieldNames,
                          (type) => type.name === this.props.settings.name
                        )
                      ),
                      "label",
                      _.startCase(
                        _.toLower(
                          _.get(
                            this.props.settings,
                            "name",
                            "Choose a Field Type"
                          )
                        )
                      )
                    ).replace(/_/g, " ")
                  : "Choose a Field Type"
              }
            >
              {fieldNames.map((type, key) => (
                <ListItem key={key} onClick={() => this.onNameChange(type)}>
                  {type.label}
                </ListItem>
              ))}
              <div style={style.divider} />
              <ListItem
                onClick={() => {
                  const name = window.prompt(
                    "Name of Custom Field...",
                    _.get(this.props.settings, "name", "")
                  );
                  if (name)
                    this.onNameChange({
                      name: name.replace(/ /g, "_").toLowerCase(),
                      label: _.startCase(_.toLower(name)).replace(/_/g, " "),
                    });
                }}
              >
                Use a Custom Field Name
              </ListItem>
            </NiceMenu>
            {_.findIndex(
              fieldNames,
              (itm) => itm.name === this.props.settings.name
            ) === -1 ? (
              <div style={{ textAlign: "left", padding: 0, marginTop: 10 }}>
                <FancySelector
                  items={inputTypes}
                  onChange={(id) =>
                    this.props.updateComponentSettings(this.props.settings.id, {
                      ...this.props.settings,
                      fieldType: id,
                    })
                  }
                />
              </div>
            ) : null}
            <div style={{ textAlign: "left", padding: 0, marginTop: 10 }}>
              <Switch
                // type="switch"
                // inline
                // checked={_.get(this.props, "settings.isRequired", false)}
                checked={this.state.isRequired}
                onClick={() => {
                  const isRequired = !_.get(
                    this.props,
                    "settings.isRequired",
                    false
                  );

                  this.setState({ isRequired }, () => {
                    this.props.updateComponentSettings(
                      this.props.settings.id,
                      {
                        ...this.props.settings,
                        isRequired,
                      },
                      true,
                      false
                    );
                  });
                }}
              />
              <span style={{ position: "relative", padding: 0, top: -4 }}>
                This Field is Required
              </span>
            </div>
          </fieldset>
        </Tools.Section>
        <Tools.Typography {...this.props} showColors={false} />
        <Tools.PositionPadding {...this.props} />
        <Tools.WidthHeight label="Field Size" {...this.props} />
        <Tools.Alignment {...this.props} verticalAlign={false} textAlign />
      </div>
    );
  }
}

const Properties = (props) => (
  <Tools.PropertiesWindow
    {...props}
    defaultTab="basic"
    tabs={[{ id: "basic", title: "Form Field", component: BasicPropertiesTab }]}
  />
);

export default FormField;
