import type { Plugin } from "../../core/types";
import { waitForElm } from "@/seqta/utils/waitForElm";
import { getAssessmentsData } from "./api";
import { renderErrorState, renderGrid, renderSkeletonLoader, teardownOverviewUi } from "./ui";
import styles from "./styles.css?inline";
import { delay } from "@/seqta/utils/delay";
import { isSeqtaEngageExperience } from "@/seqta/utils/isSeqtaEngage";
import {
  isEngageAssessmentOverviewRoute,
} from "@/seqta/utils/engageAssessmentStudent";
import { resolveEngageStudentId } from "./engageApi";

const OVERVIEW_MENU_CLASS = "betterseqta-assessments-overview-item";

function ensureOverviewMenuPosition(
  menu: HTMLElement,
  gridItem: HTMLElement,
) {
  if (menu.firstElementChild !== gridItem) {
    menu.insertBefore(gridItem, menu.firstChild);
  }
}

function isOverviewRoute() {
  if (isSeqtaEngageExperience()) {
    return isEngageAssessmentOverviewRoute();
  }
  return window.location.hash.includes("/assessments/overview");
}

async function waitForAssessmentsSubmenu(): Promise<HTMLElement> {
  if (!isSeqtaEngageExperience()) {
    return (await waitForElm(
      '[data-key="assessments"] > .sub > ul',
      true,
      100,
      60,
    )) as HTMLElement;
  }

  return (await waitForElm(
    '[data-key="assessments"] .sub ul, [data-key="assessments"] ul',
    true,
    100,
    350,
  )) as HTMLElement;
}

const assessmentsOverviewPlugin: Plugin<{}> = {
  id: "assessments-overview",
  name: "Assessments Overview",
  description:
    "Adds an overview option to the assessments page that organizes assessments by status",
  version: "1.0.0",
  settings: {},
  disableToggle: true,
  styles,

  run: async () => {
    const menu = await waitForAssessmentsSubmenu();
    const gridItem = document.createElement("li");
    gridItem.className = "item";
    gridItem.classList.add(OVERVIEW_MENU_CLASS);
    gridItem.dataset.betterseqta = "true";
    const label = document.createElement("label");
    label.textContent = "Overview";
    gridItem.appendChild(label);
    menu.insertBefore(gridItem, menu.firstChild);
    window.dispatchEvent(new CustomEvent("bsplus-native-menu-updated"));

    let loadRequestId = 0;

    const menuObserver = new MutationObserver(() => {
      const before = menu.firstElementChild;
      ensureOverviewMenuPosition(menu, gridItem);
      if (menu.firstElementChild !== before) {
        window.dispatchEvent(new CustomEvent("bsplus-native-menu-updated"));
      }
    });
    menuObserver.observe(menu, { childList: true });

    if (isOverviewRoute()) {
      void loadGridView();
    }

    const clickHandler = (e: Event) => {
      e.preventDefault();
      e.stopPropagation();
      e.stopImmediatePropagation();
      void loadGridView();
    };
    gridItem.addEventListener("click", clickHandler, true);

    const popstateHandler = () => {
      if (isOverviewRoute()) {
        void loadGridView();
      } else {
        loadRequestId += 1;
        teardownOverviewUi();
      }
    };
    window.addEventListener("popstate", popstateHandler);

    async function loadGridView() {
      const requestId = ++loadRequestId;
      await delay(1);

      if (isSeqtaEngageExperience()) {
        const studentId = await resolveEngageStudentId();
        window.history.pushState(
          {},
          "",
          `/#?page=/assessments/${studentId}/overview`,
        );
        document.title = "Overview ― SEQTA Engage";
      } else {
        window.history.pushState({}, "", "/#?page=/assessments/overview");
        document.title = "Overview ― SEQTA Learn";
      }

      const main = document.getElementById("main");
      if (!main || requestId !== loadRequestId) return;

      document
        .querySelectorAll('[data-key="assessments"] .item')
        .forEach((item) => {
          item.classList.remove("active");
        });
      gridItem.classList.add("active");
      document
        .querySelector('[data-key="assessments"]')
        ?.classList.add("active");

      main.innerHTML =
        '<div id="grid-view-container" class="bsplus-overview-host"></div>';
      const container = document.getElementById(
        "grid-view-container",
      ) as HTMLElement;

      if (requestId !== loadRequestId) return;

      renderSkeletonLoader(container);

      try {
        const data = await getAssessmentsData();
        if (requestId !== loadRequestId) return;
        renderGrid(container, data);
      } catch (err) {
        if (requestId !== loadRequestId) return;
        console.error("Failed to load assessments:", err);
        renderErrorState(
          container,
          err instanceof Error ? err.message : "Unknown error",
        );
      }
    }

    return () => {
      loadRequestId += 1;
      window.removeEventListener("popstate", popstateHandler);
      menuObserver.disconnect();
      gridItem.removeEventListener("click", clickHandler, true);
      teardownOverviewUi();
      gridItem.remove();
    };
  },
};

export default assessmentsOverviewPlugin;
