var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
import { InjectVegaTelemetrySlimmer } from 'vega-slimmer/core';
import { VegaSkeletonRuntimeMetricsPayloadDefinition } from '../../constants/runtime-metrics-payload-definition/public-api/VegaSkeletonLoader/runtime-metrics-payload-definition';
import { generateUUID } from '../../utils/misc';
import { createPublicAPIRuntimeMetricsSlimmer } from '../slimmers/runtime-metrics/create-public-api-runtime-metrics-slimmer';
/**
 * Vega Skeleton Loader Controller to show skeletons in the target elements
 */
class VegaSkeletonLoaderController {
  constructor() {
    this.vegaPublicAPIRuntimeMetricsSlimmer = createPublicAPIRuntimeMetricsSlimmer(VegaSkeletonLoaderController, ['load', 'unLoad', 'unLoadAll'], VegaSkeletonRuntimeMetricsPayloadDefinition);
    this.loaderMap = new Map();
  }
  /**
   * Load the skeletons in the target elements
   *
   * @param { VegaSkeletonLoaderConfig } config - Configuration for the loading function
   * @param {string} config.target - Target elements to show the skeletons.
   * @param {VegaSkeletonLoaderConfig.type} [config.type = 'text'] - Type of the skeleton.
   * @param {VegaSkeletonLoaderConfig.width} config.width - Width of the skeleton.
   * @param {VegaSkeletonLoaderConfig.height} config.height - Height of the skeleton.
   * @param {VegaSkeletonLoaderConfig.items} config.items - Configuration for multiple skeleton items.
   * @param {VegaSkeletonLoaderConfig.layout} config.layout - Layout of the skeleton items.
   * @returns { string } - Key of the loaded skeleton items.
   * @vegaVersion 2.16.0
   */
  load({ target, type = 'text', width, height, items, layout }) {
    // eslint-disable-next-line no-restricted-globals
    const targets = Array.from(document.body.querySelectorAll(target));
    const key = `vega-skeleton-loader-${generateUUID()}`;
    const loaderItems = [];
    targets.forEach((target) => {
      const skeletonsLoaders = !items
        ? [this.createSkeleton({ type, width, height })]
        : items.map(this.createSkeleton);
      const itemsWithKey = (layout ? [this.wrapLayout(skeletonsLoaders, layout)] : skeletonsLoaders).map((item) => {
        item.dataset[VegaSkeletonLoaderController.LOADER_DATA_SET_KEY] = key;
        return item;
      });
      loaderItems.push(...itemsWithKey);
      target.append(...itemsWithKey);
    });
    this.loaderMap.set(key, loaderItems);
    return key;
  }
  /**
   * Remove the skeletons from the dom.
   *
   * @param {string} key - The key returned from {@link VegaSkeletonLoaderController.load}.
   * @vegaVersion 2.16.0
   */
  unLoad(key) {
    if (this.loaderMap.has(key)) {
      this.loaderMap.get(key).forEach((item) => item.remove());
      this.loaderMap.delete(key);
    }
  }
  /**
   * Remove all the skeletons from the dom.
   *
   * @vegaVersion 2.16.0
   */
  unLoadAll() {
    for (const items of this.loaderMap.values()) {
      items.forEach((item) => item.remove());
    }
    this.loaderMap.clear();
  }
  /**
   * Create a skeleton item. The skeleton animated always be true
   *
   * @param {VegaSkeletonLoaderItem} config - Configuration for the skeleton item.
   * @returns {HTMLVegaSkeletonElement} - Skeleton item.
   */
  createSkeleton(config) {
    const { type, width, height } = config;
    // eslint-disable-next-line no-restricted-globals
    const skeleton = document.createElement('vega-skeleton');
    Object.assign(skeleton, { animated: true, type, width, height });
    return skeleton;
  }
  /**
   * Wrap the flex layout for the skeletons.
   *
   * @param {HTMLElement[]} skeletons - Skeleton elements of the loader.
   * @param {VegaSkeletonLoaderLayout} layout - Flex properties for the layout.
   * @returns {HTMLVegaFlexElement} - Container wrapping the skeletons in the specified flex layout.
   */
  wrapLayout(skeletons, layout) {
    // eslint-disable-next-line no-restricted-globals
    const skeletonContainer = document.createElement('vega-flex');
    Object.assign(skeletonContainer, Object.assign({ className: 'vega-skeleton-loader-template-container' }, layout.props));
    Object.assign(skeletonContainer.style, layout.style);
    skeletonContainer.append(...skeletons);
    return skeletonContainer;
  }
}
VegaSkeletonLoaderController.LOADER_DATA_SET_KEY = 'vegaSkeletonLoaderKey';
__decorate([
  InjectVegaTelemetrySlimmer()
], VegaSkeletonLoaderController.prototype, "vegaPublicAPIRuntimeMetricsSlimmer", void 0);
export const VegaSkeletonLoader = new VegaSkeletonLoaderController();
