import {Controller} from "@hotwired/stimulus";

/**
 * Polyfill for declarative shadow DOM (`<template shadowrootmode>`) on
 * JS-inserted HTML, e.g. after Turbo navigations.
 *
 * The browser only consumes `<template shadowrootmode>` during the initial
 * HTML parse. Markup arriving via fetch/Turbo never triggers the parser path,
 * so the templates sit inert in the DOM and the host element stays empty.
 *
 * This controller walks the host's subtree on connect, manually attaches a
 * shadow root for every such template, moves the template's content into it,
 * and removes the template — the same end state the browser would produce on
 * a cold load. On cold loads the templates are already gone, so this is a
 * no-op.
 */
export default class extends Controller {
  connect() {
    this.adopt(this.element);
  }

  adopt(root) {
    const templates = root.querySelectorAll("template[shadowrootmode]");
    templates.forEach((template) => {
      const host = template.parentElement;
      if (!host || host.shadowRoot) return;

      try {
        const mode = template.getAttribute("shadowrootmode") || "open";
        const shadow = host.attachShadow({ mode });
        shadow.appendChild(template.content);
        template.remove();
        // Handle nested declarative shadow roots inside the freshly attached one.
        this.adopt(shadow);
      } catch {
        // Host already has a shadow root, or attachShadow not allowed — leave it.
      }
    });
  }
}
