import { Host, h } from "@stencil/core";
import { clampWithoutNative } from "../../../../global/utils/clamp";
import { nicelyFormattedDate } from "../../utils/date";
import insane from "insane";
import { getCsrfDecodedToken } from "../../../../global/utils/utils";
import { findRelevantOptionsByClass } from "../../utils/utils";
export class HomeAnnouncement {
  constructor() {
    /**
     * This is here because we needed to respond to the nodes being added to the component and respond in order to get things rendering correctly
     * The "clamping" was very fragile
     * @param {MutationRecord[]} mutationList
     * @param {MutationObserver} _observer
     */
    this.mutationCallback = (mutationList, _observer) => {
      mutationList.forEach((record) => {
        for (let i = 0; i < record.addedNodes.length; i++) {
          const messageEl = findRelevantOptionsByClass(record.addedNodes[i], "message-plain-text");
          if (messageEl && messageEl[0]) {
            this.clampIt(messageEl[0]);
          }
          else if (
          // @ts-ignore
          record.addedNodes[i].classList &&
            // @ts-ignore
            record.addedNodes[i].classList.contains("message")) {
            //if the button was rendered with the message div it won't show up as part of the subtree separtely
            const readMore = this.messageContainerDiv.querySelector(".read-more-button");
            if (readMore) {
              this.showAllButton = true;
              readMore.addEventListener("click", this.handleShowMoreClicked);
            }
          }
          if (
          // @ts-ignore
          record.addedNodes[i].classList &&
            // @ts-ignore
            record.addedNodes[i].classList.contains("read-more-button")) {
            this.showAllButton = true;
            record.addedNodes[i].addEventListener("click", this.handleShowMoreClicked);
          }
        }
      });
    };
    /**
     * This is a callback initiated by the show more/read more being clicked.
     * If either is clicked we are using the canvas API to mark the announcement as read.
     * Lastly lets hide initiating button.
     * @param _ev
     */
    this.handleShowMoreClicked = _ev => {
      this.showAll = true;
      if (!this.showAsInnerHTML) {
        this.getText();
      }
      else {
        const divToBeRemoved = this.messageContainerDiv.querySelector(".show-more-button");
        divToBeRemoved.remove();
      }
      if (!this.read) {
        const cookieValue = getCsrfDecodedToken();
        const options = {
          credentials: "same-origin",
          headers: {
            "Content-Type": "application/json",
            "x-csrf-token": decodeURIComponent(cookieValue),
            "x-requested-with": "XMLHttpRequest"
          },
          method: "PUT",
          body: JSON.stringify({})
        };
        fetch(this.markAsReadUrl, options);
        this.read = true;
      }
    };
    this.navigateToAnnouncement = _ev => {
      window.location.href = this.announcementUrl;
    };
    /**
     * show less is callback from an event listener that fires when show less is clicked
     * It forces things to be rerendered also by changing the keys on the divs
     * @param _ev
     */
    this.showLess = _ev => {
      this.showAll = false;
      this.getText();
      if (this.showPlainText) {
        this.takeFirstRerendered = true;
        this.plainTextRerenderedCount++;
      }
      else {
        this.htmlRerenderedCount++;
      }
    };
    this.showAllButton = true;
    this.showPlainText = false;
    this.plainText = undefined;
    this.sanitizedHTML = undefined;
    this.showAsInnerHTML = false;
    this.showAll = false;
    this.plainTextRerenderedCount = 0;
    this.htmlRerenderedCount = 0;
    this.takeFirstRerendered = false;
    this.isVideo = false;
    this.collapsedIsHtml = false;
    this.announcementTitle = undefined;
    this.avatar = undefined;
    this.read = undefined;
    this.announcementDate = undefined;
    this.announcerName = undefined;
    this.announcerBio = undefined;
    this.announcementUrl = undefined;
    this.message = undefined;
    this.markAsReadUrl = undefined;
    this.announcementId = undefined;
  }
  connectedCallback() {
    this.getText();
  }
  disconnectedCallback() {
    if (this.mutationO) {
      this.mutationO.disconnect();
      this.mutationO = undefined;
    }
  }
  messageDivLoaded() {
    this.mutationO = new MutationObserver(this.mutationCallback);
    this.mutationO.observe(this.messageContainerDiv, {
      childList: true,
      subtree: true,
      attributes: true
    });
  }
  /**
   * This uses a modified third party tool that we have just copied, pasted and modified. We are just clamping at a certain height... not using the native method.
   * @param el
   */
  clampIt(el) {
    if (el.querySelector("#read-more") == null) {
      const truncationHTML = '<span id="clamp-ellipses">... </span><button id="read-more" class="read-more-button">Read More</button>';
      clampWithoutNative(el, 42, truncationHTML);
    }
  }
  /**
   * This is the magic of the component. It decides the way the preview shows up.
   */
  getText() {
    const hasImage = this.message.toLowerCase().indexOf("<img") !== -1;
    const hasIframe = this.message.toLowerCase().indexOf("<iframe") !== -1;
    if (hasIframe) {
      //Check to see if the URL is a video URL
      this.isVideo =
        this.message.toLowerCase().indexOf("kaltura.com") !== -1 ||
          this.message.toLowerCase().indexOf("watch.liberty.edu") !== -1;
    }
    this.plainText = this.generatePlainText();
    // If it is only a picture or it has an iFrame or show all is toggled
    if ((hasImage && !this.plainText) || hasIframe || this.showAll) {
      if (!this.showAll) {
        this.collapsedIsHtml = true;
      }
      const common = [
        "class",
        "style",
        "width",
        "height",
        "id",
        "align",
        "valign",
        "border"
      ];
      const tableCommon = ["cellpadding", "cellspacing", "colspan"];
      const preppedHtml = insane(this.message, {
        allowedAttributes: {
          a: [...common, "href", "name", "target"],
          img: [...common, "src", "class", "alt"],
          body: [...common],
          div: [...common],
          span: [...common],
          table: [...common, ...tableCommon],
          tbody: [...common, ...tableCommon],
          th: [...common, ...tableCommon],
          thead: [...common, ...tableCommon],
          td: [...common, ...tableCommon],
          tr: [...common, ...tableCommon],
          u: [...common],
          ul: [...common],
          li: [...common],
          h1: [...common],
          h2: [...common],
          h3: [...common],
          h4: [...common],
          h5: [...common],
          h6: [...common],
          style: ["type"],
          iframe: [
            ...common,
            "allowfullscreen",
            "frameborder",
            "src",
            "title",
            "sandbox",
            "allow",
            "webkitallowfullscreen",
            "mozallowfullscreen"
          ]
        },
        allowedClasses: {},
        allowedSchemes: ["https", "mailto", "http", "tel"],
        allowedTags: [
          "html",
          "style",
          "body",
          "a",
          "article",
          "b",
          "blockquote",
          "br",
          "caption",
          "code",
          "del",
          "details",
          "div",
          "em",
          "h1",
          "h2",
          "h3",
          "h4",
          "h5",
          "h6",
          "hr",
          "i",
          "img",
          "ins",
          "kbd",
          "li",
          "main",
          "ol",
          "p",
          "pre",
          "section",
          "span",
          "strike",
          "strong",
          "sub",
          "summary",
          "sup",
          "table",
          "tbody",
          "td",
          "th",
          "thead",
          "tr",
          "u",
          "ul",
          "center",
          "iframe"
        ],
        filter: null,
        transformText: null
      });
      //add show more button
      this.sanitizedHTML =
        preppedHtml +
          `${this.showAll
            ? ""
            : `<div class="show-more-button"><button class="read-more-button">View Announcement</button></div>`}`;
      this.showAsInnerHTML = true;
      this.showPlainText = false;
    }
    else {
      this.showPlainText = true;
      this.showAsInnerHTML = false;
    }
  }
  /**
   * The collapsing process is CPU intensive... so limiting the number of characters that need to be parsed helps
   * @returns {string}
   */
  generatePlainText() {
    return this.message.replace(/<[^>]*>?/gm, " ").substring(0, 580);
  }
  render() {
    return (h(Host, { class: {
        unread: !this.read,
        isHtml: this.showAsInnerHTML && !this.showAll,
        showAll: this.showAll,
        noDate: !this.announcementDate
      } }, h("div", { class: "avatar-container" }, h("img", { src: this.avatar })), h("div", { class: "message-container", ref: el => {
        this.messageContainerDiv = el;
        this.messageDivLoaded();
      } }, h("div", { class: "title" }, this.isVideo ? h("lu-icon", { name: "logo-youtube" }) : null, this.announcementTitle), (!!this.showAsInnerHTML || !!this.showAll) && (h("div", { key: `html-message-rerender-${this.htmlRerenderedCount}`, class: "message", innerHTML: this.sanitizedHTML })), !!this.showPlainText && !this.showAll && (h("div", { class: "message message-plain-text", key: `plain-text-rerender-${this.plainTextRerenderedCount}`, "data-rerenders": this.plainTextRerenderedCount.toString() }, this.plainText)), (!!this.showAll || !this.showAllButton) && (h("div", { class: "actions" }, h("button", { onClick: this.showLess }, this.collapsedIsHtml ? "Show Less" : "Read Less"), h("span", null, " / "), h("button", { onClick: this.navigateToAnnouncement }, "Go to Announcement"))), h("div", { class: "details-container" }, this.announcementDate &&
      nicelyFormattedDate(new Date(this.announcementDate)), h("a", { href: this.announcerBio }, this.announcerName)))));
  }
  static get is() { return "lucan-home-announcement"; }
  static get encapsulation() { return "shadow"; }
  static get originalStyleUrls() {
    return {
      "$": ["home-announcement.scss"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["home-announcement.css"]
    };
  }
  static get properties() {
    return {
      "announcementTitle": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        },
        "attribute": "announcement-title",
        "reflect": false
      },
      "avatar": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        },
        "attribute": "avatar",
        "reflect": false
      },
      "read": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        },
        "attribute": "read",
        "reflect": false
      },
      "announcementDate": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        },
        "attribute": "announcement-date",
        "reflect": false
      },
      "announcerName": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        },
        "attribute": "announcer-name",
        "reflect": false
      },
      "announcerBio": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        },
        "attribute": "announcer-bio",
        "reflect": false
      },
      "announcementUrl": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        },
        "attribute": "announcement-url",
        "reflect": false
      },
      "message": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        },
        "attribute": "message",
        "reflect": false
      },
      "markAsReadUrl": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        },
        "attribute": "mark-as-read-url",
        "reflect": false
      },
      "announcementId": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": ""
        },
        "attribute": "announcement-id",
        "reflect": false
      }
    };
  }
  static get states() {
    return {
      "showAllButton": {},
      "showPlainText": {},
      "plainText": {},
      "sanitizedHTML": {},
      "showAsInnerHTML": {},
      "showAll": {},
      "plainTextRerenderedCount": {},
      "htmlRerenderedCount": {},
      "takeFirstRerendered": {},
      "isVideo": {},
      "collapsedIsHtml": {}
    };
  }
}
//# sourceMappingURL=home-announcement.js.map
