/**
 * @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
 * For licensing, see LICENSE.md.
 */

'use strict';

const cheerio = require( 'cheerio' );
const renderPugComponent = require( '../../../utils/pug-renderer/render-pug-component' );
const hexoManager = require( '../../../../src/hexo-manager' );

/**
 * Enforce priority 30 to run it after apply design doc classes filter.
 */
hexo.extend.filter.register( 'after_post_render', page => {
	if ( page.projectTheme !== 'gloria' ) {
		return page;
	}

	const $ = cheerio.load( page.content, null, false );

	// Do not process h1 tags as it's processed further by Umberto and may be removed.
	$( 'h2, h3, h4, h5, h6' ).each( ( _, heading ) => {
		const $heading = $( heading );

		if ( hasClassOrParentWithClass( $heading, 'no-transform' ) ) {
			return;
		}

		removeAllEmptyAnchors( $, heading );

		const headingId = $( heading ).attr( 'id' );
		const $container = $( '<div class="doc b-heading"></div>' );

		// Create the copy button
		const button = renderButton( {
			hexo: hexoManager.hexo,
			page,
			headingId
		} );

		// Place the heading element before the container in the DOM
		$( heading ).before( $container );

		$container.append( $( heading ) );
		$container.append( $( button ) );
	} );

	page.content = $.html();

	return page;
}, 30 );

/**
 * Renders the button using Pug template.
 */
function renderButton( { hexo, page, headingId } ) {
	return renderPugComponent( {
		hexo,
		requires: [
			'_components/svg/index',
			'_components/icon/index',
			'_components/tooltip-popover/index',
			'_components/heading-link/index'
		],
		mixinContextVars: {
			page
		},
		component: 'heading-link',
		componentAttrs: {
			headingId
		}
	} );
}

/**
 * Removes all empty anchors that were created to hold the heading links buttons.
 */
function removeAllEmptyAnchors( $, heading ) {
	$( heading ).find( 'a' ).each( ( _, anchor ) => {
		const $anchor = $( anchor );
		const text = $anchor.text().trim().replace( '#', '' );

		if ( !$anchor.children().length && !text ) {
			$anchor.remove();
		}
	} );
}

/**
 * Checks if the element itself or any of its parents has the specified class.
 *
 * @param $element - The jQuery element to check.
 * @param className - The class name to look for.
 * @returns True if the element or any parent has the class, false otherwise.
 */
function hasClassOrParentWithClass( $element, className ) {
	return $element.hasClass( className ) || $element.parents( `.${ className }` ).length > 0;
}
