function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import React, { useEffect, useRef, useState, useMemo } from "react";
import { AdvancedOptions, CheckboxField, DropdownButton, generateField, RadioGroupField } from "teselagen-react-components";
import { getReverseComplementSequenceString } from "@teselagen/sequence-utils";
import AddOrEditAnnotationDialog from "../AddOrEditAnnotationDialog";
import { convertRangeTo0Based } from "@teselagen/range-utils";
import { getAcceptedChars } from "../../utils/editorUtils";
import classNames from "classnames";
import "./style.css";
import { getSequenceWithinRange } from "@teselagen/range-utils";
import { flatMap } from "lodash";
import CaretPositioning, { selectionSaveCaretPosition } from "./EditCaretPosition";
import { Menu, MenuItem } from "@blueprintjs/core";
import MeltingTemp from "../../StatusBar/MeltingTemp";
import { getStructuredBases } from "../../RowItem/StackedAnnotations/getStructuredBases";
var CustomContentEditable = generateField(function CustomContentEditable(_ref) {
  var input = _ref.input,
    disabled = _ref.disabled,
    sequenceData = _ref.sequenceData,
    sequenceLength = _ref.sequenceLength,
    start = _ref.start,
    end = _ref.end,
    primerBindsOn = _ref.primerBindsOn,
    bases = _ref.bases,
    forward = _ref.forward;
  var _useState = useState(false),
    hasTempError = _useState[0],
    setTempError = _useState[1];
  var inputRef = useRef(null);
  var _useState2 = useState({
      start: 0,
      end: 0
    }),
    caretPosition = _useState2[0],
    setCaretPosition = _useState2[1];
  var emitChange = function emitChange(e) {
    var newVal = e.target.innerText;
    var savedCaretPosition = CaretPositioning.saveSelection(e.currentTarget);
    setCaretPosition(savedCaretPosition);
    var acceptedChars = getAcceptedChars(sequenceData);
    var newBases = "";
    newVal.split("").forEach(function (letter) {
      if (acceptedChars.includes(letter.toLowerCase())) {
        newBases += letter;
      }
    });
    if (newVal.length !== newBases.length) {
      setTempError(true);
      setTimeout(function () {
        setTempError(false);
      }, 200);
    }
    var restore = selectionSaveCaretPosition(inputRef.current);
    input.onChange(newBases || "");
    setTimeout(function () {
      restore();
    }, 0);
  };
  useEffect(function () {
    CaretPositioning.restoreSelection(inputRef.current, caretPosition);
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [bases]);
  var basesToUse = bases || "";
  var _getStructuredBases = getStructuredBases({
      annotationRange: {
        start: start - 1,
        end: end - 1
      },
      forward: forward,
      bases: basesToUse,
      start: start - 1,
      end: end - 1,
      fullSequence: sequenceData.sequence,
      primerBindsOn: primerBindsOn,
      sequenceLength: sequenceLength
    }),
    allBasesWithMetaData = _getStructuredBases.allBasesWithMetaData;
  var html = flatMap(allBasesWithMetaData, function (_ref2) {
    var b = _ref2.b,
      isMatch = _ref2.isMatch,
      isAmbiguousMatch = _ref2.isAmbiguousMatch;
    if (b === "&") return [];
    return "<span class=\"" + (isMatch ? "" : isAmbiguousMatch ? "tg-ambiguous-match-seq" : "tg-no-match-seq") + "\">" + b + "</span>";
  });
  html = html.join("");
  return /*#__PURE__*/React.createElement("div", {
    style: _extends({
      display: "flex"
    }, disabled ? {
      pointerEvents: "none"
    } : {})
  }, /*#__PURE__*/React.createElement("span", {
    style: {
      verticalAlign: "top",
      marginTop: 9,
      marginRight: 3,
      fontSize: 12,
      color: "grey"
    }
  }, "5'"), /*#__PURE__*/React.createElement("span", {
    ref: inputRef,
    spellCheck: "false",
    contentEditable: !disabled,
    className: classNames("bp3-input tg-custom-sequence-editable", {
      hasTempError: hasTempError
    }),
    onInput: emitChange,
    dangerouslySetInnerHTML: {
      __html: html
    } // innerHTML of the editable div
  }), /*#__PURE__*/React.createElement("span", {
    style: {
      alignSelf: "end",
      marginBottom: 9,
      marginLeft: 3,
      fontSize: 12,
      color: "grey"
    }
  }, "3'"));
});
var RenderBases = function RenderBases(props) {
  var sequenceData = props.sequenceData,
    readOnly = props.readOnly,
    start = props.start,
    end = props.end,
    linkedOligo = props.linkedOligo,
    getLinkedOligoLink = props.getLinkedOligoLink,
    useLinkedOligo = props.useLinkedOligo,
    sequenceLength = props.sequenceLength,
    primerBindsOn = props.primerBindsOn,
    bases = props.bases,
    forward = props.forward,
    defaultLinkedOligoMessage = props.defaultLinkedOligoMessage,
    change = props.change;
  var defaultValue;
  var seqLen = sequenceData.sequence.length;
  var validate = useMemo(function () {
    return function (val /* vals, props */) {
      if (!val) return;
      if (val.length > seqLen) {
        return "Primer cannot be longer than sequence";
      }
      return;
    };
  }, [seqLen]);
  var normalizedSelection = convertRangeTo0Based({
    start: start,
    end: end
  });
  if (!bases) {
    var bps = getSequenceWithinRange(normalizedSelection, sequenceData.sequence);
    if (!forward) {
      bps = getReverseComplementSequenceString(bps);
    }
    defaultValue = bps;
  }
  return /*#__PURE__*/React.createElement("div", {
    style: {
      borderTop: "1px solid #A7B6C2",
      borderBottom: "1px solid #A7B6C2"
    }
  }, /*#__PURE__*/React.createElement("div", {
    style: {
      display: "flex",
      alignItems: "center",
      justifyContent: "space-between"
    }
  }, /*#__PURE__*/React.createElement(CheckboxField, {
    name: "useLinkedOligo",
    label: "Linked Oligo?",
    tooltipInfo: "Check this box to link this primer to an oligo in your Oligo Library. If the primer bases match exactly the bases of an existing oligo, it will be linked to that existing oligo. If the bases don't match, a new oligo will be created in the library.",
    noMarginBottom: true,
    defaultValue: true,
    disabled: readOnly
  }), useLinkedOligo && /*#__PURE__*/React.createElement("div", {
    className: "tg-linked-oligo-holder",
    style: {
      marginTop: -5,
      fontStyle: "italic",
      fontSize: 11
    }
  }, getLinkedOligoLink && getLinkedOligoLink(props) || linkedOligo || (defaultLinkedOligoMessage !== undefined ? defaultLinkedOligoMessage : "Will Be Created On Save"))), useLinkedOligo && /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(CustomContentEditable
  // inlineLabel
  , _extends({
    showErrorIfUntouched: true,
    tooltipError: true,
    primerBindsOn: primerBindsOn,
    validate: validate,
    sequenceLength: sequenceLength,
    disabled: readOnly
  }, props, defaultValue ? {
    defaultValue: defaultValue
  } : {}, {
    name: "bases",
    label: /*#__PURE__*/React.createElement("div", {
      className: "tg-bases-label"
    }, /*#__PURE__*/React.createElement("div", {
      style: {
        display: "flex"
      }
    }, "Bases", " ", /*#__PURE__*/React.createElement("div", {
      style: {
        fontSize: 10
      }
    }, " ", "\xA0 (Length: ", bases ? bases.length : 0, ")")), /*#__PURE__*/React.createElement("div", {
      style: {
        width: "fit-content"
      }
    }, /*#__PURE__*/React.createElement(DropdownButton, {
      disabled: readOnly,
      intent: "primary",
      small: true,
      menu: /*#__PURE__*/React.createElement(Menu, null, /*#__PURE__*/React.createElement(MenuItem, {
        onClick: function onClick() {
          change("forward", true);
          change("bases", getSequenceWithinRange(normalizedSelection, sequenceData.sequence));
        },
        key: "forward",
        text: "Forward"
      }), /*#__PURE__*/React.createElement(MenuItem, {
        onClick: function onClick() {
          change("forward", false);
          change("bases", getReverseComplementSequenceString(getSequenceWithinRange(normalizedSelection, sequenceData.sequence)));
        },
        key: "reverse",
        text: "Reverse"
      }))
    }, "Set From Selection")))
  })), /*#__PURE__*/React.createElement(AdvancedOptions, {
    style: {
      marginBottom: 10
    }
  }, /*#__PURE__*/React.createElement(RadioGroupField, {
    name: "primerBindsOn",
    inline: true,
    inlineLabel: true,
    disabled: readOnly,
    label: "Oligo Binds On",
    tooltipError: true,
    options: [{
      label: "5' End",
      value: "5prime"
    }, {
      label: "3' End",
      value: "3prime"
    }]
  })), /*#__PURE__*/React.createElement(MeltingTemp, {
    InnerWrapper: InnerWrapperMeltingTemp,
    sequence: bases
  })));
};
export default AddOrEditAnnotationDialog({
  formName: "AddOrEditPrimerDialog",
  getProps: function getProps(props) {
    return {
      upsertAnnotation: props.upsertPrimer,
      annotationTypePlural: "primers",
      RenderBases: RenderBases
    };
  }
});
var InnerWrapperMeltingTemp = function InnerWrapperMeltingTemp(p) {
  return /*#__PURE__*/React.createElement("div", {
    className: "bp3-text-muted bp3-text-small",
    style: {
      marginBottom: 15,
      marginTop: -5,
      fontStyle: "italic"
    }
  }, p.children);
};