import { TagSelectElement } from './tag-select-element';
import { CategorySelectElement } from './category-select-element';
import { SubCategorySelectElement } from './sub-category-select-element';
import { RelatedEntryEditorElement } from './related-entry-editor-element';
import { UnitEditorElement } from './unit-editor-element';
import { UnitInplaceEditorElement } from './unit-inplace-editor-element';
import { UnitConfigEditorElement } from './unit-config-editor-element';
import { BlockEditorElement } from './block-editor-element';
import { BlockEditorMenuTypeSelectElement } from './block-editor-menu-type-select-element';

const ELEMENTS: ReadonlyArray<readonly [string, CustomElementConstructor]> = [
  ['acms-tag-select', TagSelectElement],
  ['acms-category-select', CategorySelectElement],
  ['acms-sub-category-select', SubCategorySelectElement],
  ['acms-related-entry-editor', RelatedEntryEditorElement],
  ['acms-unit-editor', UnitEditorElement],
  ['acms-unit-inplace-editor', UnitInplaceEditorElement],
  ['acms-unit-config-editor', UnitConfigEditorElement],
  ['acms-block-editor', BlockEditorElement],
  ['acms-block-editor-menu-type-select', BlockEditorMenuTypeSelectElement],
];

const HOST_DISPLAY_CONTENTS_STYLE_ID = 'acms-elements-host-display-contents';

/**
 * 各カスタム要素は Light DOM に描画するだけの「マウント地点」で、要素自身に見た目の意味を
 * 持たせない設計のため、host に display: contents を当てて自身のボックスをレイアウトから
 * 除外する（子孫の描画結果だけが親の flex/grid 等に直接参加する）。Shadow DOM 専用の
 * `:host` 疑似クラスは Light DOM では使えないため、ELEMENTS（登録に必須の唯一の情報源）から
 * タグ名一覧を組み立てて `<style>` を1つ注入する。新しい要素を ELEMENTS に追加すれば
 * define と同時にこのスタイルにも自動で追従し、別ファイルでのタグ列挙は不要になる。
 */
function ensureHostDisplayContentsStyle(tagNames: readonly string[]): void {
  if (document.getElementById(HOST_DISPLAY_CONTENTS_STYLE_ID)) {
    return;
  }
  const style = document.createElement('style');
  style.id = HOST_DISPLAY_CONTENTS_STYLE_ID;
  style.textContent = `${tagNames.join(', ')} { display: contents; }`;
  document.head.append(style);
}

/**
 * 9つの管理画面カスタム要素（acms-tag-select / acms-category-select /
 * acms-sub-category-select / acms-related-entry-editor / acms-unit-editor / acms-unit-inplace-editor /
 * acms-unit-config-editor / acms-block-editor / acms-block-editor-menu-type-select）を登録する。
 *
 * admin.js の読み込み時に一度だけ呼び出す想定。customElements.get() で登録済みかどうかを
 * 確認してから define するため、誤って複数回呼び出しても例外にならない（冪等）。
 */
export function registerAcmsElements(): void {
  ELEMENTS.forEach(([tagName, elementClass]) => {
    if (!customElements.get(tagName)) {
      customElements.define(tagName, elementClass);
    }
  });
  ensureHostDisplayContentsStyle(ELEMENTS.map(([tagName]) => tagName));
}
