class FSCollapsibleFieldset {
  collapsed;
  fieldset;
  legend;

  constructor(fieldset, collapsed = false) {
    this.fieldset = fieldset;
    this.collapsed = collapsed;
    this.initialize();
  }

  handleLegendClick = (event) => {
    this.setIsCollapsed(!this.getIsCollapsed());
  };

  getIsCollapsed() {
    return this.fieldset.classList.contains("fsrd-collapsed");
  }

  setIsCollapsed(collapsed) {
    if (collapsed) {
      this.fieldset.classList.add("fsrd-collapsed");
    } else {
      this.fieldset.classList.remove("fsrd-collapsed");
    }
  }

  initialize() {
    this.fieldset.classList.add("fsrd-collapsible");
    this.legend = this.fieldset.querySelector("legend");
    this.setIsCollapsed(this.collapsed);
    this.legend.addEventListener("click", this.handleLegendClick);
  }
}

class FSCollapsibleFieldsetManager {
  #targets = [];

  manage(target, collapsed = true) {
    if (!this.#targets.includes(target)) {
      this.#targets.push(target);
      new FSCollapsibleFieldset(target, collapsed);
    }
  }
}

const fsCollapsibleFieldsetManager = new FSCollapsibleFieldsetManager();

class FSRDContentManagement {
  #collabsibleObserver = new MutationObserver(this.handleCollabsibleObserver);
  #collabsibleObserverConfig = {
    attributes: true,
    childList: true,
    subtree: true,
  };
 

  //#region Event Handlers

  handleCollapseAllClick = (event) => {
    let accordions = document.querySelectorAll(
      ".usa-accordion, .usa-accordion__button"
    );
    accordions.forEach((accordion) => {
      accordion.setAttribute("aria-expanded", false);
    });
    let content = document.querySelectorAll(".usa-accordion__content");
    content.forEach((item) => {
      if (item.id != 'edit-revision-information-content') {
        item.hidden = true;
      }
    });

    let fieldsets = document.querySelectorAll("fieldset.fsrd-collapsible");
    fieldsets.forEach((fieldset) => {
      fieldset.classList.add("fsrd-collapsed");
    });
  };

  handleCollapseAllMouseEnter = (event) => {
    event.srcElement.innerHTML = "Collapse All";
  };

  handleCollapseAllMouseLeave = (event) => {
    event.srcElement.innerHTML = " — ";
  };

  handleCollabsibleObserver(mutationList, observer) {
    mutationList.forEach((mutation) => {
      if (mutation.target.tagName === "FIELDSET") {
        if (mutation.target.classList.contains("fsrd-collapsible")) {
          fsCollapsibleFieldsetManager.manage(mutation.target);
        }
      }
    });
  }

  //#endregion

  isAdminTheme() {
    return document.body.classList.contains("user-logged-in");
  }

  isMicrositeLoggedIn() {
    let adminBar = document.querySelectorAll(".fsrd-user-tools");
    let isMicrositeAdmin = adminBar.length > 0;
    return isMicrositeAdmin;
  }

  //#region Page Tests

  isAdminContent() {
    let matches = window.location.pathname.endsWith("/admin/content");
    return matches ?? false;
  }

  isAdminMedia() {
    let matches = window.location.pathname.endsWith("/admin/content/media");
    return matches ?? false;
  }

  isAdminMediaGrid() {
    let matches = window.location.pathname.endsWith(
      "/admin/content/media-grid"
    );
    return matches ?? false;
  }

  isNodeEdit() {
    let nodeForm = document.querySelector("form.node-form");
    return nodeForm != null;
  }

  isNodeCreate() {
    let matches = window.location.pathname.endsWith("/node/add");
    return matches ?? false;
  }

  isMediaCreate() {
    let matches = window.location.pathname.endsWith("/media/add");
    return matches ?? false;
  }

  isMediaCreateBulk() {
    let matches = window.location.pathname.endsWith("/media/bulk-upload");
    return matches ?? false;
  }

  isMediaEdit() {
    let mediaForm = document.querySelector("form.media-form");
    return mediaForm != null;
  }

  isMenu() {
    let matches = window.location.pathname.includes(
      "/admin/structure/menu/manage/"
    );
    return matches ?? false;
  }

  isMenuItem() {
    let matches = window.location.pathname.includes(
      "/admin/structure/menu/item/"
    );
    return matches ?? false;
  }

  //#region Group

  isGroupHome() {
    let groupHomeArticle = document.querySelector("article.group--full");
    return groupHomeArticle != null;
  }

  isGroupNodeCreate() {
    let matches = window.location.pathname.match("\/group\/[0-9]+\/node\/create");
    return matches ?? false;
  }

  isGroupDashboard() {
    return document.body.classList.contains("page-node-type-group_dashboard");
  }

  isGroupNotes() {
    return document.body.classList.contains("page-node-type-group_notes");
  }

  //#endregion

  //#endregion

  //#region Content Values

  getDestinationParam() {
    let query = window.location.search;
    let urlParams = new URLSearchParams(query);
    if (urlParams.has("destination")) {
      return urlParams.get("destination");
    }
    return null;
  }

  getGroupName() {
    let groupName = "Station";
    let groupTitle = document.querySelector(".fsrd-group-menu__title");
    if (groupTitle != null) {
      let groupLink = groupTitle.querySelector("a");
      groupName = groupLink.innerText;
    }
    return groupName;
  }

  //#endregion

  //#region Content Injection

  addBodyClass(className) {
    document.body.classList.add(className);
  }

  addCollapseAll() {
    let collapseButton = document.createElement("div");
    collapseButton.style =
      "z-index: 2000; position: fixed; right:0; bottom:1rem;";
    collapseButton.innerHTML = " — ";
    collapseButton.title = "Collapse All";
    collapseButton.classList.add("usa-button");
    document.body.appendChild(collapseButton);
    collapseButton.addEventListener("click", this.handleCollapseAllClick);
    collapseButton.addEventListener(
      "mouseenter",
      this.handleCollapseAllMouseEnter
    );
    collapseButton.addEventListener(
      "mouseleave",
      this.handleCollapseAllMouseLeave
    );
  }

  addHeading(text) {
    let main = document.querySelector(".usa-layout-docs__main");
    let heading = document.createElement("h1");
    heading.innerText = text;
    main.prepend(heading);
  }

  addPreviewReminder() {
    let nodeForm = document.querySelector("form.node-form");
    let editActions = document.getElementById("edit-actions");

    let reminder = document.createElement("div");
    reminder.classList.add("fsrd-node-form__reminder");
    reminder.innerText =
      "Remember to preview your page prior to publishing, and after publishing to ensure the page looks as you intended.";

    nodeForm.insertBefore(reminder, editActions);
  }

  //#endregion

  //#region Content Removal

  removeHero() {
    let hero = document.querySelector(".fsrd-hero");
    if (hero != null) {
      hero.remove();
    }
  }

  removeBreadcrumbs() {
    let breadcrumbs = document.getElementById("block-fsrd-breadcrumbs");
    if (breadcrumbs != null) {
      breadcrumbs.innerHTML = `<div style="height: .5rem;"></div>`;
    }
  }

  removeLocalTasksBlock() {
    if (!this.isAdminTheme()) {
      let tasks = document.getElementById("block-fsrd-local-tasks");
      tasks?.remove();
    }
  }

  removeAddRelationsButton() {
    let actionButtonDiv = document.getElementById("block-fsrd-local-actions");
    if (actionButtonDiv != null) {
      let buttons = document.querySelectorAll("a");
      buttons.forEach((button) => {
        if (button.textContent === "Add existing content") {
          button.parentElement.remove();
        }
      });
    }
  }

  removeActions() {
    let actionsDiv = document.getElementById("edit-header");
    if (actionsDiv != null) {
      actionsDiv.remove();
    }
    let actions2 = document.getElementById("edit-actions--2");
    if (actions2 != null) {
      actions2.remove();
    }
  }

  removeRevisionAccordion(formClass = "node-form") {
    let revision = document.getElementById("edit-revision-information");
    if (revision != null) {
      revision.classList.remove("usa-accordion", "usa-accordion--bordered");
      let revisionHeader = revision.querySelector(
        "button.usa-accordion-button"
      );
      revisionHeader.remove();
    }

    let fieldset = document.createElement("fieldset");
    fieldset.classList.add("usa-fieldset");

    let legend = document.createElement("legend");
    legend.classList.add("usa-legend");
    legend.innerText = "Revision Log";
    fieldset.append(legend);

    let nodeForm = document.querySelector(`form.${formClass}`);
    let editActions = document.getElementById("edit-actions");
    nodeForm.insertBefore(fieldset, editActions);

    fieldset.append(revision);
  }

  //#endregion

  //#region Other Content Tweaks

  disableStickyTables() {
    let tables = document.getElementsByTagName("table");
    for (let i = 0; i < tables.length; i++) {
      let table = tables[i];
      table.classList.remove("sticky-enabled");
      table.classList.remove("sticky-table");
    }
  }

  fixContentTypeList(entityType = "content") {
    let contentBlock = document.getElementById("block-fsrd-content");
    let typeList = contentBlock.querySelector("dl");
    typeList.classList.add("fsrd-node-create__list");

    let instruction = document.createElement("div");
    instruction.innerText = `Select the type of ${entityType} to add:`;

    contentBlock.insertBefore(instruction, typeList);

    let typeTerms = typeList.querySelectorAll("dt");
    let typeDefinitions = typeList.querySelectorAll("dd");

    typeTerms.forEach((element) => {
      let link = element.querySelector("a");
      link.innerText = link.innerText
        .replace("Group node (", "")
        .replace(")", "");
      element.classList.add("fsrd-node-create__item");
    });

    typeDefinitions.forEach((element) => {
      element.style.display = "none";
    });
  }

  fixMenuParentSelect() {
    let destination = this.getDestinationParam();
    if (destination != null) {
      let menuSlug = destination.substring(destination.lastIndexOf('/') + 1);

      let parentSelect = document.getElementById("edit-menu-parent");
      for (let i = parentSelect.children.length - 1; i >= 0; i--) {
        let option = parentSelect.children[i];
        if (!option.value.startsWith(menuSlug)) {
          parentSelect.children[i].remove();
        }
      }
    }
  }

  findParentOfClass(element, className) {
    while (
      (element = element.parentElement) &&
      !element.classList.contains(className)
    );
    return element;
  }

  addTabIdToHref(selector) {
    let targets = document.querySelectorAll(selector);
    targets.forEach((target) => {
      let parent = this.findParentOfClass(target, "fsrd-view-tab");
      target.href = `${target.href}#${parent.id}`;
    });
  }

  addTabIdToFormAction(selector) {
    let targets = document.querySelectorAll(selector);
    targets.forEach((target) => {
      let parent = this.findParentOfClass(target, "fsrd-view-tab");
      target.action = `${target.action}#${parent.id}`;
    });
  }

  fixUSWDSPaginationInTabs() {
    this.addTabIdToHref(".usa-pagination__link, .usa-pagination__button");
  }

  fixFilterFormButtonsInTabs() {
    this.addTabIdToFormAction(".views-exposed-form");
  }

  fixTableSortLinksInTabs() {
    this.addTabIdToHref("th.views-field a");
  }

  //#endregion

  //#region Page Fixes

  fixAdminContent() {
    if (this.isAdminContent()) {
      this.addBodyClass("fsrd-node-list");
      this.addHeading("Content");
      this.removeBreadcrumbs();
      this.removeLocalTasksBlock();
      this.removeActions();
      this.disableStickyTables();
    }
  }

  fixAdminMedia() {
    if (this.isAdminMedia() || this.isAdminMediaGrid()) {
      this.addBodyClass("fsrd-media-library-admin");
      if (this.isAdminMedia()) {
        this.addBodyClass("fsrd-media-library-admin--table");
      }
      if (this.isAdminMediaGrid()) {
        this.addBodyClass("fsrd-media-library-admin--grid");
      }
      this.addHeading("Media (Asset) Library");
      this.removeBreadcrumbs();

      this.removeActions();
    }
  }

  fixNodeCreate() {
    if (this.isNodeCreate()) {
      this.removeBreadcrumbs();
      this.addHeading("Add new content");
      this.fixContentTypeList();
    }
  }

  fixNodeEdit() {
    if (this.isNodeEdit()) {
      //this.applyCollapsible();
      this.#collabsibleObserver.observe(
        document.body,
        this.#collabsibleObserverConfig
      );
      this.removeHero();
      this.removeBreadcrumbs();
      this.removeRevisionAccordion();
      this.addPreviewReminder();
      this.addCollapseAll();
      // Make fieldsets in nested accodion collapsible.
      let fieldsets = document.querySelectorAll(
        ".node-form .usa-accordion .usa-accordion .usa-accordion__content > fieldset"
      );
      for (let i = 0; i < fieldsets.length; i++) {
        let fieldset = fieldsets[i];
        fieldset.classList.add("fsrd-collapsible");
      }
    }
  }

  fixMediaCreate() {
    if (this.isMediaCreate()) {
      this.removeBreadcrumbs();
      this.addHeading("Add new media");
      this.fixContentTypeList("asset");
    }
  }

  fixMediaCreateBulk() {
    if (this.isMediaCreateBulk()) {
      this.removeBreadcrumbs();
      this.addHeading("Upload multiple media files");
      this.fixContentTypeList("assets");
    }
  }

  fixMediaEdit() {
    if (this.isMediaEdit()) {
      this.removeBreadcrumbs();
      this.removeRevisionAccordion("media-form");
      this.addCollapseAll();
    }
  }

  fixMenu() {
    if (this.isMenu()) {
      this.removeBreadcrumbs();
      this.removeLocalTasksBlock();
      document.querySelector(".form-type-language-select").remove();
      document.querySelector("#edit-clear").remove();
    }
  }

  fixMenuItem() {
    if (this.isMenuItem()) {
      this.removeBreadcrumbs();
      this.fixMenuParentSelect();
    }
  }

  fixGroupHome() {
    if (this.isGroupHome()) {
      this.removeLocalTasksBlock();
    }
  }

  fixGroupDashboard() {
    if (this.isGroupDashboard()) {
      this.fixUSWDSPaginationInTabs();
      this.fixFilterFormButtonsInTabs();
      this.fixTableSortLinksInTabs();
    }
  }

  fixGroupNotes() {
    if (this.isGroupNotes()) {
      this.fixUSWDSPaginationInTabs();
      this.fixTableSortLinksInTabs();
    }
  }

  fixGroupNodeCreate() {
    if (this.isGroupNodeCreate()) {
      this.addHeading(`Add new content to ${this.getGroupName()}`);
      this.fixContentTypeList();
    }
  }

  //#endregion

  fix() {
    if (!this.isAdminTheme()) {
      this.fixAdminContent();
      this.fixAdminMedia();
      this.fixNodeCreate();
      this.fixNodeEdit();

      this.fixMediaCreate();
      this.fixMediaCreateBulk();
      this.fixMediaEdit();

      this.fixMenu();
      this.fixMenuItem();

      this.fixGroupHome();
      this.fixGroupDashboard();
      this.fixGroupNotes();
      this.fixGroupNodeCreate();
    }
  }
}

window.addEventListener("load", (event) => {
  let cm = new FSRDContentManagement();
  cm.fix();
});