import commentWidgetThemeStyle from "../styles/devcm-comment-widget.css?raw";

const injectShadowStyle = (root: ShadowRoot | null | undefined, id: string, css: string) => {
  if (!root || root.querySelector(`#${id}`)) {
    return;
  }

  const style = document.createElement("style");
  style.id = id;
  style.textContent = css;
  root.appendChild(style);
};

const themeCommentRoot = (root: ParentNode | null | undefined) => {
  if (!root) {
    return;
  }

  root.querySelectorAll<HTMLElement>("*").forEach((element) => {
    if (element.shadowRoot) {
      injectShadowStyle(element.shadowRoot, "devcm-comment-widget-theme", commentWidgetThemeStyle);
      themeCommentRoot(element.shadowRoot);
    }
  });
};

const commentScopeSelector = ".devcm-comments, .devcm-moment-comments";

const getCommentScopes = (root: ParentNode) => {
  const scopes = Array.from(root.querySelectorAll<HTMLElement>(commentScopeSelector));
  if (root instanceof HTMLElement && root.matches(commentScopeSelector)) {
    scopes.unshift(root);
  }
  return scopes;
};

const themeCommentWidget = (root: ParentNode) => {
  const commentScopes = getCommentScopes(root);
  if (!commentScopes.length) {
    return;
  }

  commentScopes.forEach((comments) => {
    themeCommentRoot(comments);

    comments.querySelectorAll<HTMLElement>("comment-widget").forEach((widget) => {
      injectShadowStyle(widget.shadowRoot, "devcm-comment-widget-theme", commentWidgetThemeStyle);

      const form = widget.shadowRoot?.querySelector<HTMLElement>("comment-form");
      injectShadowStyle(form?.shadowRoot, "devcm-comment-form-theme", commentWidgetThemeStyle);

      const baseForm = form?.shadowRoot?.querySelector<HTMLElement>("base-form");
      injectShadowStyle(baseForm?.shadowRoot, "devcm-comment-base-form-theme", commentWidgetThemeStyle);
    });
  });
};

type ThemeCommentState = {
  $el: HTMLElement;
  observer: MutationObserver | null;
  timers: number[];
  init: () => void;
  destroy: () => void;
  refresh: () => void;
};

export const themeComment = (): ThemeCommentState => ({
  $el: null as unknown as HTMLElement,
  observer: null,
  timers: [],
  init() {
    this.refresh();
    this.timers = [120, 500, 1200, 2400].map((delay) => window.setTimeout(() => this.refresh(), delay));

    this.observer = new MutationObserver(() => this.refresh());
    this.observer.observe(this.$el, {
      childList: true,
      subtree: true,
    });
  },
  destroy() {
    this.observer?.disconnect();
    this.timers.forEach((timer) => window.clearTimeout(timer));
  },
  refresh() {
    themeCommentWidget(this.$el);
  },
});
