import { Renderable } from '../core/renderable.js';
import { nodeFactory } from '../node/node-factory.js';

const PERMALINK_CONTENT_REGEX = /<!--\s*NO_PERMALINK_START\s*-->\s(?<content>[\s\S]*)\s<!--\s*NO_PERMALINK_END\s*-->/g;
const PREVENT_PERMALINKS_REGEX = /(?<permalinks><!--\s*NO_PERMALINK_START\s*-->\s(?:[\s\S]*)\s<!--\s*NO_PERMALINK_END\s*-->)/g;
const HEADING_REGEX = /<h(?<level>[2-6])(?<attrs>[^>]*)>(?<content>.*?)<\/h\1>/g;
const ATTRIBUTE_ID_REGEX = /\sid=["'](?<id>[^"']+)["']/;
const HEADING_BUTTON_CLASS = 'fr-btn--tooltip fr-btn fr-btn--sm fr-icon-link fr-btn--tertiary-no-outline dsfr-doc-anchor-heading__button';

const injectPermaLink = (match, level, attrs, content, fragments) => {
  const idMatch = attrs.match(ATTRIBUTE_ID_REGEX);
  if (!idMatch || !idMatch.groups?.id) return match;
  const copied = fragments?.button?.['link-copied'];
  const copy = fragments?.button?.['copy-link'];
  const buttonId = `${idMatch.groups.id}-anchor`;
  const anchorButton = `<button type="button" id="${buttonId}" title="${copy}" data-label-copied="${copied}" class="${HEADING_BUTTON_CLASS}"></button>`;
  return `<h${level}${attrs}>${content}${anchorButton}</h${level}>`;

};

class Template extends Renderable {
  constructor (data, hasPermaLinks = false) {
    super(data);
    this._fragments = data.fragments;
    nodeFactory.populate(data.fragments);
    this._hasPermaLinks = hasPermaLinks;
    this._content = nodeFactory.create({
      type: 'root',
      children: data.nodes
    });
  }

  get content () {
    return this._content;
  }

  get name () {
    return this.constructor.NAME;
  }

  async render () {
    const html = await this._content.render();
    if (!this._hasPermaLinks) return html;
    return this.addPermaLinks(html);
  }

  addPermaLinks (html) {
    return html.split(PREVENT_PERMALINKS_REGEX).map((part) => {
      const match = PERMALINK_CONTENT_REGEX.exec(part);
      if (match && match.groups && match.groups.content) {
        return match.groups.content;
      }

      return part.replace(HEADING_REGEX, (match, level, attrs, content) => {
        return injectPermaLink(match, level, attrs, content, this._fragments);
      });
    }).join('');
  }

  get text () {
    return this._content.text;
  }
}

export { Template };
