import '../scss/module-diagnostics.scss';

/**
 * Monitor.Cat — Diagnostics module.
 *
 * Auto-loads system diagnostics on page visit, renders health score ring,
 * actionable insights, tabbed detail sections, and full plugin listing.
 *
 * All dynamic content is inserted via safe DOM methods (textContent, createElement).
 *
 * @package MonitorCat
 */
( function () {
	'use strict';

	var api = window.MonitorCatAdmin;
	var cachedData = null;

	// ── Section metadata ────────────────────────────────────────────

	var SECTION_META = {
		php:           { icon: 'fa-code',         color: 'lavender', label: 'PHP' },
		server:        { icon: 'fa-server',       color: 'cyan',     label: 'Server' },
		wordpress:     { icon: 'fa-globe',        color: 'primary',  label: 'WordPress' },
		database:      { icon: 'fa-database',     color: 'mint',     label: 'Database' },
		plugins_theme: { icon: 'fa-puzzle-piece', color: 'lavender', label: 'Plugins & Theme' },
		health:        { icon: 'fa-heart-pulse',  color: 'coral',    label: 'Health Checks' },
	};

	// ── Actionable tips keyed by item label ─────────────────────────

	var INSIGHT_TIPS = {
		'Version':              'Contact your hosting provider to upgrade to the latest PHP version for better performance and security.',
		'Memory Limit':         'Increase PHP memory_limit in your php.ini or contact your hosting provider. Recommended: 256 MB or higher.',
		'cURL':                 'The cURL extension is required by WordPress for HTTP requests. Contact your hosting provider to enable it.',
		'WP_DEBUG':             'WP_DEBUG should be disabled on production sites. Set define(\'WP_DEBUG\', false) in wp-config.php.',
		'DISABLE_WP_CRON':     'WP-Cron is disabled. Set up a real server cron job to ensure scheduled tasks run reliably.',
		'WordPress Cron':       'WP-Cron is disabled. Set up a system cron job pointing to wp-cron.php for reliable scheduling.',
		'TLS/SSL':              'Your site is not using HTTPS. Install an SSL certificate and update your Site URL to use https://.',
		'HTTPS':                'Your site is not using HTTPS. Install an SSL certificate for better security and SEO.',
		'REST API':             'The REST API is not responding correctly. Check your .htaccess rules and server configuration.',
		'Permalink Structure':  'Plain permalinks are bad for SEO. Go to Settings \u2192 Permalinks and choose a descriptive structure.',
		'Inactive Plugins':     'Remove inactive plugins to reduce security risk and improve site performance.',
		'Active Plugins':       'You have a very large number of active plugins. Review and deactivate any that are not essential.',
		'.htaccess Writable':   'WordPress cannot write to .htaccess. Some features like pretty permalinks may not work correctly.',
		'wp-content Writable':  'The wp-content directory is not writable. Plugin/theme updates and file uploads will fail.',
	};

	// ── Helpers ─────────────────────────────────────────────────────

	/**
	 * Remove all child nodes from an element (safe alternative to innerHTML).
	 *
	 * @param {HTMLElement} el The element to clear.
	 */
	function clearChildren( el ) {
		while ( el.firstChild ) {
			el.removeChild( el.firstChild );
		}
	}

	/**
	 * Create an element with optional text and classes.
	 *
	 * @param {string} tag     HTML tag name.
	 * @param {string} text    Text content.
	 * @param {string} classes CSS class string.
	 * @return {HTMLElement}
	 */
	function createEl( tag, text, classes ) {
		var el = document.createElement( tag );
		if ( text ) {
			el.textContent = text;
		}
		if ( classes ) {
			el.className = classes;
		}
		return el;
	}

	/**
	 * Threshold for treating a value as "long" — will get gradient fade + copy.
	 */
	var LONG_VALUE_THRESHOLD = 30;

	/**
	 * Check whether a string value is long enough to need truncation treatment.
	 *
	 * @param {string} value The value to check.
	 * @return {boolean}
	 */
	function isLongValue( value ) {
		return typeof value === 'string' && value.length > LONG_VALUE_THRESHOLD;
	}

	/**
	 * Create a long-value element with gradient fade and copy button.
	 *
	 * @param {string} value Full text value.
	 * @return {HTMLElement}
	 */
	function createLongValue( value ) {
		var wrap = createEl( 'span', null, 'mc-sys-info-val-long' );

		var text = createEl( 'span', value, 'mc-sys-info-val-text' );
		text.title = value;
		wrap.appendChild( text );

		var btn = createEl( 'button', null, 'mc-sys-info-copy' );
		btn.type = 'button';
		btn.title = 'Copy to clipboard';
		btn.setAttribute( 'aria-label', 'Copy ' + value );
		btn.appendChild( createEl( 'i', null, 'fa-duotone fa-copy' ) );

		btn.addEventListener( 'click', function () {
			if ( navigator.clipboard && navigator.clipboard.writeText ) {
				navigator.clipboard.writeText( value ).then( function () {
					showCopied( btn );
				} );
			} else {
				var ta = document.createElement( 'textarea' );
				ta.value = value;
				ta.style.position = 'fixed';
				ta.style.opacity = '0';
				document.body.appendChild( ta );
				ta.select();
				document.execCommand( 'copy' );
				document.body.removeChild( ta );
				showCopied( btn );
			}
		} );

		wrap.appendChild( btn );
		return wrap;
	}

	/**
	 * Flash the copy button to a success state briefly.
	 *
	 * @param {HTMLButtonElement} btn The copy button.
	 */
	function showCopied( btn ) {
		var icon = btn.querySelector( 'i' );
		btn.classList.add( 'is-copied' );
		if ( icon ) {
			icon.className = 'fa-duotone fa-check';
		}
		setTimeout( function () {
			btn.classList.remove( 'is-copied' );
			if ( icon ) {
				icon.className = 'fa-duotone fa-copy';
			}
		}, 1500 );
	}

	/**
	 * Set a button to loading or normal state.
	 *
	 * @param {HTMLButtonElement} btn     The button element.
	 * @param {boolean}          loading Whether to enter loading state.
	 */
	function setLoading( btn, loading ) {
		if ( loading ) {
			btn.dataset.originalText = btn.textContent;
			btn.textContent = btn.dataset.loadingText || 'Loading...';
			btn.disabled = true;
			btn.classList.add( 'mc-btn-loading' );
		} else {
			btn.textContent = btn.dataset.originalText || btn.textContent;
			btn.disabled = false;
			btn.classList.remove( 'mc-btn-loading' );
		}
	}

	/**
	 * Return score class name.
	 *
	 * @param {number} score Score 0-100.
	 * @return {string}
	 */
	function scoreClass( score ) {
		if ( score >= 80 ) {
			return 'good';
		}
		if ( score >= 50 ) {
			return 'ok';
		}
		return 'bad';
	}

	/**
	 * Return score description message.
	 *
	 * @param {number} score Score 0-100.
	 * @return {string}
	 */
	function scoreMessage( score ) {
		if ( score >= 90 ) {
			return 'Excellent! Your site environment is in great shape.';
		}
		if ( score >= 80 ) {
			return 'Good health. A few minor items could be improved.';
		}
		if ( score >= 50 ) {
			return 'Some issues need attention to ensure optimal performance.';
		}
		return 'Several critical issues found that should be addressed.';
	}

	// ── Loading step animation ──────────────────────────────────────

	var stepTimer = null;
	var stepIndex = 0;

	function startLoadingSteps() {
		var steps = document.querySelectorAll( '.mc-diag-loading-step' );
		stepIndex = 0;

		if ( steps.length > 0 ) {
			steps[ 0 ].classList.add( 'is-active' );
			steps[ 0 ].querySelector( 'i' ).className = 'fa-duotone fa-spinner-third fa-spin';
		}

		stepTimer = setInterval( function () {
			if ( stepIndex < steps.length ) {
				steps[ stepIndex ].classList.remove( 'is-active' );
				steps[ stepIndex ].classList.add( 'is-done' );
				steps[ stepIndex ].querySelector( 'i' ).className = 'fa-duotone fa-circle-check';
			}

			stepIndex++;

			if ( stepIndex < steps.length ) {
				steps[ stepIndex ].classList.add( 'is-active' );
				steps[ stepIndex ].querySelector( 'i' ).className = 'fa-duotone fa-spinner-third fa-spin';
			} else {
				clearInterval( stepTimer );
			}
		}, 600 );
	}

	function stopLoadingSteps() {
		clearInterval( stepTimer );
		var steps = document.querySelectorAll( '.mc-diag-loading-step' );
		steps.forEach( function ( step ) {
			step.classList.remove( 'is-active' );
			step.classList.add( 'is-done' );
			step.querySelector( 'i' ).className = 'fa-duotone fa-circle-check';
		} );
	}

	function resetLoadingSteps() {
		clearInterval( stepTimer );
		var steps = document.querySelectorAll( '.mc-diag-loading-step' );
		steps.forEach( function ( step, i ) {
			step.classList.remove( 'is-active', 'is-done' );
			step.querySelector( 'i' ).className = i === 0
				? 'fa-duotone fa-spinner-third fa-spin'
				: 'fa-duotone fa-ellipsis';
		} );
	}

	// ── Score ring animation ────────────────────────────────────────

	var scoreAnimFrame = 0;

	function animateScoreRing( score ) {
		var ring   = document.getElementById( 'mc-diag-score-ring' );
		var fill   = ring ? ring.querySelector( '.mc-ring-fill' ) : null;
		var number = document.getElementById( 'mc-diag-score-number' );

		if ( ! ring || ! fill || ! number ) {
			return;
		}

		// Cancel any in-flight counter animation from a prior call.
		if ( scoreAnimFrame ) {
			cancelAnimationFrame( scoreAnimFrame );
			scoreAnimFrame = 0;
		}

		ring.classList.remove( 'mc-ring-good', 'mc-ring-ok', 'mc-ring-bad' );
		ring.classList.add( 'mc-ring-' + scoreClass( score ) );

		var circumference = 326.73;
		var offset = circumference - ( score / 100 ) * circumference;

		requestAnimationFrame( function () {
			fill.style.transition = 'stroke-dashoffset 1s cubic-bezier(0.16, 1, 0.3, 1)';
			fill.style.strokeDashoffset = offset;
		} );

		// Animate the number counter.
		var start = performance.now();
		var duration = 800;

		function tick( now ) {
			var elapsed  = now - start;
			var progress = Math.min( elapsed / duration, 1 );
			number.textContent = Math.round( progress * score );
			if ( progress < 1 ) {
				scoreAnimFrame = requestAnimationFrame( tick );
			} else {
				scoreAnimFrame = 0;
			}
		}

		scoreAnimFrame = requestAnimationFrame( tick );
	}

	// ── Hero badges ─────────────────────────────────────────────────

	function renderHeroBadges( summary ) {
		var container = document.getElementById( 'mc-diag-hero-badges' );
		if ( ! container ) {
			return;
		}

		clearChildren( container );

		var badges = [
			{ count: summary.good,     label: 'Passing',  cls: 'success', icon: 'fa-circle-check' },
			{ count: summary.warnings, label: 'Warnings', cls: 'warning', icon: 'fa-triangle-exclamation' },
			{ count: summary.critical, label: 'Critical', cls: 'error',   icon: 'fa-circle-xmark' },
		];

		badges.forEach( function ( b ) {
			if ( b.count === 0 ) {
				return;
			}
			var badge = createEl( 'span', null, 'mc-badge mc-badge-' + b.cls );
			badge.appendChild( createEl( 'i', null, 'fa-duotone ' + b.icon ) );
			badge.appendChild( document.createTextNode( ' ' + b.count + ' ' + b.label ) );
			container.appendChild( badge );
		} );
	}

	// ── Actionable insights ─────────────────────────────────────────

	function renderInsights( insights ) {
		var container  = document.getElementById( 'mc-diag-insights' );
		var list       = document.getElementById( 'mc-diag-insights-list' );
		var countBadge = document.getElementById( 'mc-diag-insight-count' );

		if ( ! container || ! list || ! countBadge ) {
			return;
		}

		if ( ! insights || insights.length === 0 ) {
			container.style.display = 'none';
			return;
		}

		clearChildren( list );
		countBadge.textContent = insights.length + ' item' + ( insights.length !== 1 ? 's' : '' );

		insights.forEach( function ( insight ) {
			var item = createEl( 'div', null, 'mc-diag-insight-item mc-diag-insight-' + insight.status );

			// Status icon.
			var iconWrap  = createEl( 'div', null, 'mc-diag-insight-icon' );
			var iconClass = insight.status === 'critical' ? 'fa-circle-xmark' : 'fa-triangle-exclamation';
			var iconColor = insight.status === 'critical' ? 'mc-fa-coral' : 'mc-fa-primary';
			iconWrap.appendChild( createEl( 'i', null, 'fa-duotone ' + iconClass + ' ' + iconColor ) );
			item.appendChild( iconWrap );

			// Content.
			var content = createEl( 'div', null, 'mc-diag-insight-content' );

			var header = createEl( 'div', null, 'mc-diag-insight-header' );
			header.appendChild( createEl( 'strong', insight.label ) );
			header.appendChild( createEl( 'span', insight.section_label, 'mc-diag-insight-section' ) );
			content.appendChild( header );

			content.appendChild( createEl( 'p', insight.value, 'mc-diag-insight-value' ) );

			// Tip.
			var tip = INSIGHT_TIPS[ insight.label ];
			if ( tip ) {
				var tipEl = createEl( 'div', null, 'mc-diag-insight-tip' );
				tipEl.appendChild( createEl( 'i', null, 'fa-duotone fa-lightbulb mc-fa-primary' ) );
				tipEl.appendChild( createEl( 'span', tip ) );
				content.appendChild( tipEl );
			}

			item.appendChild( content );
			list.appendChild( item );
		} );

		container.style.display = '';
	}

	// ── Detail card renderer ────────────────────────────────────────

	/**
	 * Render a single detail card with key-value rows.
	 *
	 * @param {string} sectionKey  Section key from API.
	 * @param {Object} section     Section data with label, icon, items.
	 * @return {HTMLElement}
	 */
	function renderDetailCard( sectionKey, section ) {
		var meta = SECTION_META[ sectionKey ] || { icon: 'fa-circle-info', color: 'lavender', label: sectionKey };

		var card = createEl( 'div', null, 'mc-card mc-card-spacious mc-diag-detail-card mc-diag-card-appear' );

		// Header.
		var header    = createEl( 'div', null, 'mc-diag-detail-header' );
		var titleWrap = createEl( 'div', null, 'mc-diag-detail-title' );
		var pedestal  = createEl( 'div', null, 'mc-pedestal mc-pedestal-sm mc-pedestal-' + meta.color );

		pedestal.appendChild( createEl( 'i', null, 'fa-duotone ' + meta.icon + ' mc-fa-' + meta.color ) );
		titleWrap.appendChild( pedestal );
		titleWrap.appendChild( createEl( 'h3', meta.label, 'mc-heading-sm' ) );
		header.appendChild( titleWrap );

		// Issue badge.
		if ( section.items ) {
			var issueCount = 0;
			section.items.forEach( function ( item ) {
				if ( item.status && item.status !== 'good' ) {
					issueCount++;
				}
			} );

			if ( issueCount > 0 ) {
				header.appendChild( createEl(
					'span',
					issueCount + ' issue' + ( issueCount !== 1 ? 's' : '' ),
					'mc-badge mc-badge-warning'
				) );
			} else {
				header.appendChild( createEl( 'span', 'All good', 'mc-badge mc-badge-success' ) );
			}
		}

		card.appendChild( header );

		// Key-value rows.
		if ( section.items && Array.isArray( section.items ) ) {
			var info = createEl( 'div', null, 'mc-sys-info' );

			section.items.forEach( function ( item ) {
				// Skip nested array values (handled separately).
				if ( Array.isArray( item.value ) ) {
					return;
				}

				var row = createEl( 'div', null, 'mc-sys-info-row' );

				if ( item.status ) {
					row.appendChild( createEl( 'span', null, 'mc-diag-dot mc-diag-dot-' + item.status ) );
				}

				row.appendChild( createEl( 'span', item.label || '', 'mc-sys-info-key' ) );

				var strVal = String( item.value || '' );

				if ( isLongValue( strVal ) ) {
					row.appendChild( createLongValue( strVal ) );
				} else {
					var val = createEl( 'span', strVal, 'mc-sys-info-val' );
					if ( item.status === 'critical' ) {
						val.classList.add( 'mc-val-critical' );
					} else if ( item.status === 'warning' ) {
						val.classList.add( 'mc-val-warning' );
					} else if ( item.status === 'good' ) {
						val.classList.add( 'mc-val-good' );
					}
					row.appendChild( val );
				}

				info.appendChild( row );
			} );

			card.appendChild( info );
		}

		return card;
	}

	// ── Tab renderers ───────────────────────────────────────────────

	function renderEnvironmentTab( sections ) {
		var grid = document.getElementById( 'mc-diag-env-grid' );
		if ( ! grid ) {
			return;
		}
		clearChildren( grid );

		if ( sections.php ) {
			grid.appendChild( renderDetailCard( 'php', sections.php ) );
		}
		if ( sections.server ) {
			grid.appendChild( renderDetailCard( 'server', sections.server ) );
		}
	}

	function renderWordPressTab( sections ) {
		var grid = document.getElementById( 'mc-diag-wp-grid' );
		if ( ! grid ) {
			return;
		}
		clearChildren( grid );

		if ( sections.wordpress ) {
			grid.appendChild( renderDetailCard( 'wordpress', sections.wordpress ) );
		}
		if ( sections.database ) {
			grid.appendChild( renderDetailCard( 'database', sections.database ) );
		}
	}

	function renderHealthTab( sections ) {
		var grid = document.getElementById( 'mc-diag-health-grid' );
		if ( ! grid ) {
			return;
		}
		clearChildren( grid );

		if ( sections.health ) {
			grid.appendChild( renderDetailCard( 'health', sections.health ) );
		}
	}

	// ── Plugins & Theme tab ─────────────────────────────────────────

	function renderPluginsTab( sections ) {
		var container = document.getElementById( 'mc-diag-plugins-grid' );
		if ( ! container ) {
			return;
		}
		clearChildren( container );

		var ptSection = sections.plugins_theme;
		if ( ! ptSection ) {
			return;
		}

		// Theme card.
		if ( ptSection.items && ptSection.items.length > 0 ) {
			var themeCard   = createEl( 'div', null, 'mc-card mc-card-spacious mc-diag-detail-card mc-diag-card-appear' );
			var themeHeader = createEl( 'div', null, 'mc-diag-detail-header' );
			var themeTitleW = createEl( 'div', null, 'mc-diag-detail-title' );
			var themePed    = createEl( 'div', null, 'mc-pedestal mc-pedestal-sm mc-pedestal-lavender' );

			themePed.appendChild( createEl( 'i', null, 'fa-duotone fa-palette mc-fa-lavender' ) );
			themeTitleW.appendChild( themePed );
			themeTitleW.appendChild( createEl( 'h3', 'Theme & Overview', 'mc-heading-sm' ) );
			themeHeader.appendChild( themeTitleW );
			themeCard.appendChild( themeHeader );

			var themeInfo = createEl( 'div', null, 'mc-sys-info' );

			ptSection.items.forEach( function ( item ) {
				if ( Array.isArray( item.value ) ) {
					return;
				}

				var row = createEl( 'div', null, 'mc-sys-info-row' );

				if ( item.status ) {
					row.appendChild( createEl( 'span', null, 'mc-diag-dot mc-diag-dot-' + item.status ) );
				}

				row.appendChild( createEl( 'span', item.label || '', 'mc-sys-info-key' ) );

				var themeStrVal = String( item.value || '' );

				if ( isLongValue( themeStrVal ) ) {
					row.appendChild( createLongValue( themeStrVal ) );
				} else {
					var val = createEl( 'span', themeStrVal, 'mc-sys-info-val' );
					if ( item.status === 'warning' ) {
						val.classList.add( 'mc-val-warning' );
					} else if ( item.status === 'good' ) {
						val.classList.add( 'mc-val-good' );
					}
					row.appendChild( val );
				}

				themeInfo.appendChild( row );
			} );

			themeCard.appendChild( themeInfo );
			container.appendChild( themeCard );
		}

		// Plugin lists.
		if ( ! ptSection.plugins ) {
			return;
		}

		var plugins = ptSection.plugins;

		if ( plugins.active && plugins.active.length > 0 ) {
			container.appendChild(
				renderPluginTable( 'Active Plugins', plugins.active, 'fa-plug-circle-check', 'mint', plugins.counts.active )
			);
		}

		if ( plugins.inactive && plugins.inactive.length > 0 ) {
			container.appendChild(
				renderPluginTable( 'Inactive Plugins', plugins.inactive, 'fa-plug-circle-xmark', 'coral', plugins.counts.inactive )
			);
		}

		if ( plugins.mu && plugins.mu.length > 0 ) {
			container.appendChild(
				renderPluginTable( 'Must-Use Plugins', plugins.mu, 'fa-plug-circle-bolt', 'cyan', plugins.counts.mu )
			);
		}
	}

	/**
	 * Render a plugin table card.
	 *
	 * @param {string} title    Card title.
	 * @param {Array}  plugins  Plugin list.
	 * @param {string} icon     FontAwesome icon class.
	 * @param {string} color    Color name.
	 * @param {number} count    Plugin count.
	 * @return {HTMLElement}
	 */
	function renderPluginTable( title, plugins, icon, color, count ) {
		var card = createEl( 'div', null, 'mc-card mc-card-spacious mc-diag-plugin-card mc-diag-card-appear' );

		// Header.
		var header    = createEl( 'div', null, 'mc-diag-detail-header' );
		var titleWrap = createEl( 'div', null, 'mc-diag-detail-title' );
		var pedestal  = createEl( 'div', null, 'mc-pedestal mc-pedestal-sm mc-pedestal-' + color );

		pedestal.appendChild( createEl( 'i', null, 'fa-duotone ' + icon + ' mc-fa-' + color ) );
		titleWrap.appendChild( pedestal );
		titleWrap.appendChild( createEl( 'h3', title, 'mc-heading-sm' ) );
		header.appendChild( titleWrap );

		var badgeCls = color === 'coral' ? 'warning' : 'neutral';
		header.appendChild( createEl( 'span', String( count ), 'mc-badge mc-badge-' + badgeCls ) );
		card.appendChild( header );

		// Plugin list.
		var table = createEl( 'div', null, 'mc-diag-plugin-list' );

		// Table header.
		var thead = createEl( 'div', null, 'mc-diag-plugin-row mc-diag-plugin-row-header' );
		thead.appendChild( createEl( 'span', 'Plugin', 'mc-diag-plugin-name' ) );
		thead.appendChild( createEl( 'span', 'Version', 'mc-diag-plugin-version' ) );
		thead.appendChild( createEl( 'span', 'Author', 'mc-diag-plugin-author' ) );
		table.appendChild( thead );

		// Plugin rows.
		plugins.forEach( function ( plugin ) {
			var row = createEl( 'div', null, 'mc-diag-plugin-row' );
			row.appendChild( createEl( 'span', plugin.name, 'mc-diag-plugin-name' ) );
			row.appendChild( createEl( 'span', 'v' + plugin.version, 'mc-diag-plugin-version' ) );
			row.appendChild( createEl( 'span', plugin.author || '\u2014', 'mc-diag-plugin-author' ) );
			table.appendChild( row );
		} );

		card.appendChild( table );
		return card;
	}

	// ── Tab badge counts ────────────────────────────────────────────

	function updateTabBadges( sections ) {
		var tabMap = {
			environment: [ 'php', 'server' ],
			wordpress:   [ 'wordpress', 'database' ],
			plugins:     [ 'plugins_theme' ],
			health:      [ 'health' ],
		};

		Object.keys( tabMap ).forEach( function ( tabKey ) {
			var issueCount = 0;
			tabMap[ tabKey ].forEach( function ( sectionKey ) {
				var section = sections[ sectionKey ];
				if ( ! section || ! section.items ) {
					return;
				}
				section.items.forEach( function ( item ) {
					if ( item.status && item.status !== 'good' ) {
						issueCount++;
					}
				} );
			} );

			var tab = document.querySelector( '.mc-tab[data-tab-target="' + tabKey + '"]' );
			if ( ! tab ) {
				return;
			}

			// Remove old badge.
			var oldBadge = tab.querySelector( '.mc-tab-count' );
			if ( oldBadge ) {
				tab.removeChild( oldBadge );
			}

			if ( issueCount > 0 ) {
				var badge = createEl( 'span', String( issueCount ), 'mc-tab-count mc-tab-count-warning' );
				tab.appendChild( badge );
			}
		} );
	}

	// ── Render all results ──────────────────────────────────────────

	function renderResults( data ) {
		stopLoadingSteps();

		var loadingEl = document.getElementById( 'mc-diag-loading' );
		var resultsEl = document.getElementById( 'mc-diag-results' );

		if ( loadingEl ) {
			loadingEl.style.display = 'none';
		}
		if ( resultsEl ) {
			resultsEl.style.display = '';
		}

		// Hero score ring.
		animateScoreRing( data.health_score );

		var heroTitle = document.getElementById( 'mc-diag-hero-title' );
		var heroDesc  = document.getElementById( 'mc-diag-hero-desc' );
		if ( heroTitle ) {
			heroTitle.textContent = 'Your Site Health';
		}
		if ( heroDesc ) {
			heroDesc.textContent = scoreMessage( data.health_score );
		}

		renderHeroBadges( data.summary );

		// Insights.
		renderInsights( data.insights );

		// Tab content.
		renderEnvironmentTab( data.sections );
		renderWordPressTab( data.sections );
		renderPluginsTab( data.sections );
		renderHealthTab( data.sections );

		// Tab badges.
		updateTabBadges( data.sections );
	}

	// ── Load diagnostics ────────────────────────────────────────────

	var refreshBtn = null;

	function loadDiagnostics( force ) {
		var loadingEl = document.getElementById( 'mc-diag-loading' );
		var resultsEl = document.getElementById( 'mc-diag-results' );
		var emptyEl   = document.getElementById( 'mc-diag-empty' );

		if ( loadingEl ) {
			loadingEl.style.display = '';
		}
		if ( resultsEl ) {
			resultsEl.style.display = 'none';
		}
		if ( emptyEl ) {
			emptyEl.style.display = 'none';
		}

		resetLoadingSteps();
		startLoadingSteps();

		var url = '/diagnostics/info';
		if ( force ) {
			url += '?force=1';
		}

		api.apiFetch( url, { method: 'GET' } )
			.then( function ( data ) {
				cachedData = data;
				renderResults( data );

				if ( refreshBtn ) {
					setLoading( refreshBtn, false );
				}

				if ( force ) {
					api.notify( 'Diagnostics refreshed successfully.', 'success' );
				}
			} )
			.catch( function ( err ) {
				stopLoadingSteps();

				if ( loadingEl ) {
					loadingEl.style.display = 'none';
				}
				if ( emptyEl ) {
					emptyEl.style.display = '';
				}

				if ( refreshBtn ) {
					setLoading( refreshBtn, false );
				}

				api.notify( err.message || 'Failed to load diagnostics.', 'error' );
			} );
	}

	// ── Copy to clipboard ───────────────────────────────────────────

	/**
	 * Format diagnostic data as markdown text for clipboard.
	 *
	 * @param {Object} data Diagnostics response data.
	 * @return {string}
	 */
	function formatAsText( data ) {
		if ( ! data ) {
			return '';
		}

		var lines = [ '# Site Diagnostics Report by Monitor.Cat', '' ];

		lines.push( 'Health Score: ' + data.health_score + '/100' );
		lines.push( 'Status: ' + data.health_status );
		lines.push( '' );

		// Insights.
		if ( data.insights && data.insights.length > 0 ) {
			lines.push( '## Issues' );
			lines.push( '' );
			data.insights.forEach( function ( insight ) {
				lines.push( '- [' + insight.status.toUpperCase() + '] ' + insight.label + ': ' + insight.value );
			} );
			lines.push( '' );
		}

		// Sections.
		var sections = data.sections || {};
		Object.keys( sections ).forEach( function ( key ) {
			var section = sections[ key ];
			if ( typeof section !== 'object' || section === null ) {
				return;
			}

			lines.push( '## ' + ( section.label || key ) );
			lines.push( '' );

			if ( Array.isArray( section.items ) ) {
				section.items.forEach( function ( item ) {
					if ( Array.isArray( item.value ) ) {
						return;
					}
					var status = item.status ? ' [' + item.status.toUpperCase() + ']' : '';
					lines.push( ( item.label || '' ) + ': ' + String( item.value || '' ) + status );
				} );
			}

			// Plugins.
			if ( section.plugins ) {
				var pg = section.plugins;

				if ( pg.active && pg.active.length > 0 ) {
					lines.push( '' );
					lines.push( '### Active Plugins (' + pg.counts.active + ')' );
					pg.active.forEach( function ( p ) {
						lines.push( '- ' + p.name + ' v' + p.version + ( p.author ? ' by ' + p.author : '' ) );
					} );
				}

				if ( pg.inactive && pg.inactive.length > 0 ) {
					lines.push( '' );
					lines.push( '### Inactive Plugins (' + pg.counts.inactive + ')' );
					pg.inactive.forEach( function ( p ) {
						lines.push( '- ' + p.name + ' v' + p.version );
					} );
				}

				if ( pg.mu && pg.mu.length > 0 ) {
					lines.push( '' );
					lines.push( '### Must-Use Plugins (' + pg.counts.mu + ')' );
					pg.mu.forEach( function ( p ) {
						lines.push( '- ' + p.name + ' v' + p.version );
					} );
				}
			}

			lines.push( '' );
		} );

		return lines.join( '\n' );
	}

	function copyToClipboard() {
		var btn  = document.getElementById( 'mc-diag-copy-btn' );
		var text = formatAsText( cachedData );

		if ( ! text ) {
			api.notify( 'No data to copy. Run diagnostics first.', 'warning' );
			return;
		}

		if ( navigator.clipboard && navigator.clipboard.writeText ) {
			navigator.clipboard.writeText( text )
				.then( function () {
					if ( btn ) {
						var orig = btn.textContent;
						btn.textContent = btn.dataset.successText || 'Copied!';
						setTimeout( function () {
							btn.textContent = orig;
						}, 2000 );
					}
					api.notify( 'Diagnostics copied to clipboard.', 'success' );
				} )
				.catch( function () {
					api.notify( 'Failed to copy to clipboard.', 'error' );
				} );
		} else {
			// Fallback for older browsers.
			try {
				var textarea = document.createElement( 'textarea' );
				textarea.value = text;
				textarea.style.position = 'fixed';
				textarea.style.opacity = '0';
				document.body.appendChild( textarea );
				textarea.select();
				document.execCommand( 'copy' );
				document.body.removeChild( textarea );
				api.notify( 'Diagnostics copied to clipboard.', 'success' );
			} catch ( err ) {
				api.notify( 'Failed to copy to clipboard.', 'error' );
			}
		}
	}

	// ── Tab switching ───────────────────────────────────────────────

	function initTabs() {
		var tabContainer = document.querySelector( '.mc-diag-tabs' );
		if ( ! tabContainer ) {
			return;
		}

		var tabs   = tabContainer.querySelectorAll( '.mc-tab' );
		var panels = tabContainer.querySelectorAll( '.mc-tab-panel' );

		tabs.forEach( function ( tab ) {
			tab.addEventListener( 'click', function () {
				var target = tab.dataset.tabTarget;

				tabs.forEach( function ( t ) {
					t.classList.remove( 'is-active' );
				} );
				panels.forEach( function ( p ) {
					p.classList.remove( 'is-active' );
				} );

				tab.classList.add( 'is-active' );

				var panel = tabContainer.querySelector( '[data-tab-panel="' + target + '"]' );
				if ( panel ) {
					panel.classList.add( 'is-active' );
				}
			} );
		} );
	}

	// ── Init ────────────────────────────────────────────────────────

	document.addEventListener( 'DOMContentLoaded', function () {
		var page = document.querySelector( '.mc-diagnostics-page' );
		if ( ! page ) {
			return;
		}

		initTabs();
		loadDiagnostics( false );

		// Refresh button.
		refreshBtn = document.getElementById( 'mc-diag-refresh-btn' );
		if ( refreshBtn ) {
			refreshBtn.addEventListener( 'click', function () {
				setLoading( refreshBtn, true );
				loadDiagnostics( true );
			} );
		}

		// Copy to clipboard.
		var copyBtn = document.getElementById( 'mc-diag-copy-btn' );
		if ( copyBtn ) {
			copyBtn.addEventListener( 'click', function () {
				copyToClipboard();
			} );
		}
	} );
} )();
