/**
 * @module tgam-patterns-sub-pencil
 * js logic specific to opening and closing the Pencil Ad
 */

import throttle from "lodash/throttle";
import ee from "./event-emitter";

const eventspace = "sub-pencil-ad";

// CSS selectors for various internal components
const select = {
  root: ".js-sub-pencil",
  control: ".js-sub-pencil-control",
  open: "o-sub-pencil--open",
  closed: "o-sub-pencil--closed"
};

// DOM elements of various internal components
const dom = {};

// track auto-open panel state
let allowExpand = true;

/**
 * @method init
 * @description init method, adds event listeners
 * @param root {querySelector} of parent element
 * @param expanded {boolean} true for panel to become open; false to become closed.
 * @return {undefined}
 */
export default function init(root = select.root, expanded = false) {
  select.root = root;
  dom.root = document.querySelector(select.root);
  if (!dom.root) {
    return;
  }

  dom.control = document.querySelector(select.control);
  dom.control.addEventListener("click", onToggleClicked);

  // set the initial expand or collapsed state
  setPanelState(expanded);

  // throttled event handlers
  window.addEventListener("scroll", throttle(onWindowScroll, 50));

  // reveal the element, after it's initialized
  dom.root.removeAttribute("hidden");

  return dom.root;
}

/**
 * @method isPanelOpen
 * @description determine if panel's state is expanded or collapsed
 * @return {boolean} true if panel is expanded; false if panel is collapsed.
 */
function isPanelOpen() {
  return dom.root.classList.contains(select.open);
}

/**
 * @method setPanelState
 * @description update element classes and properties to set expanded/collapsed state.
 * @param expanded {boolean} true for panel to become open; false to become closed.
 * @return {undefined}
 */
function setPanelState(expanded) {
  dom.root.classList[expanded ? "add" : "remove"](select.open);
  dom.root.classList[expanded ? "remove" : "add"](select.closed);
  dom.control.setAttribute("aria-expanded", expanded);
}

/**
 * @method onToggleClicked
 * @description callback for clicking on the left or right control button toggles
 * @param e {MouseEvent} click event
 * @return {undefined}
 */
function onToggleClicked() {
  const isOpen = !isPanelOpen();
  setPanelState(isOpen);
  // only broadcast event for user initiated toggling
  ee.emit(`${eventspace}:${isOpen ? "expand" : "collapse"}`);
}

/**
 * @method onWindowScroll
 * @description callback for throttled window scroll event.
 * @return {undefined}
 */
function onWindowScroll() {
  const isOpen = isPanelOpen();
  const scrollTop = (document.body.scrollTop || document.documentElement.scrollTop) === 0;
  // we want to auto-open the panel only when the user scrolls away from the top of the page,
  // but not re-auto-open the panel again, after the user has manually closed the panel once.
  if (!scrollTop && !isOpen && allowExpand) {
    allowExpand = false;
    setPanelState(true);
  } else if (scrollTop && isOpen) {
    allowExpand = true;
    setPanelState(false);
  }
}
