<?php
/**
 * Critical CSS Generator and Inline Loader
 *
 * This file provides functionality to inline critical CSS for above-the-fold content,
 * improving First Contentful Paint (FCP) and Largest Contentful Paint (LCP).
 *
 * IMPORTANT: This feature is DISABLED by default. Enable it via Customizer.
 *
 * How it works:
 * 1. When enabled, critical CSS is inlined in the <head>
 * 2. Main stylesheet is loaded asynchronously after page load
 * 3. Improves Core Web Vitals by reducing render-blocking CSS
 *
 * @package ROI_Theme
 * @since 1.0.0
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Check if Critical CSS is enabled
 *
 * @since 1.0.0
 * @return bool
 */
function roi_is_critical_css_enabled() {
	return get_theme_mod( 'roi_enable_critical_css', false );
}

/**
 * Get Critical CSS Content
 *
 * Returns the critical CSS for the current page type.
 * You can customize this based on page types (home, single, archive, etc.)
 *
 * @since 1.0.0
 * @return string Critical CSS content
 */
function roi_get_critical_css() {
	// Define critical CSS based on page type
	$critical_css = '';

	// Get transient to cache critical CSS
	$transient_key = 'roi_critical_css_' . roi_get_page_type();
	$cached_css = get_transient( $transient_key );

	if ( false !== $cached_css ) {
		return $cached_css;
	}

	// Generate critical CSS based on page type
	if ( is_front_page() || is_home() ) {
		$critical_css = roi_get_home_critical_css();
	} elseif ( is_single() ) {
		$critical_css = roi_get_single_critical_css();
	} elseif ( is_archive() || is_category() || is_tag() ) {
		$critical_css = roi_get_archive_critical_css();
	} else {
		$critical_css = roi_get_default_critical_css();
	}

	// Cache for 24 hours
	set_transient( $transient_key, $critical_css, DAY_IN_SECONDS );

	return $critical_css;
}

/**
 * Get current page type for caching
 *
 * @since 1.0.0
 * @return string Page type identifier
 */
function roi_get_page_type() {
	if ( is_front_page() ) {
		return 'home';
	} elseif ( is_single() ) {
		return 'single';
	} elseif ( is_archive() ) {
		return 'archive';
	} elseif ( is_search() ) {
		return 'search';
	} elseif ( is_404() ) {
		return '404';
	} else {
		return 'page';
	}
}

/**
 * Critical CSS for Homepage
 *
 * @since 1.0.0
 * @return string
 */
function roi_get_home_critical_css() {
	return '
		/* Reset and Base */
		*,*::before,*::after{box-sizing:border-box}
		body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;line-height:1.6;color:#333;background:#fff}
		img{max-width:100%;height:auto;display:block}
		a{color:#0066cc;text-decoration:none}

		/* Header */
		.site-header{background:#fff;border-bottom:1px solid #e5e5e5;position:sticky;top:0;z-index:1000}
		.site-header .container{max-width:1200px;margin:0 auto;padding:1rem}
		.site-branding{display:flex;align-items:center}
		.site-title{margin:0;font-size:1.5rem;font-weight:700}

		/* Hero Section */
		.hero-section{padding:3rem 1rem;text-align:center;background:#f8f9fa}
		.hero-title{font-size:2.5rem;margin:0 0 1rem;font-weight:700;line-height:1.2}
		.hero-description{font-size:1.125rem;color:#666;max-width:600px;margin:0 auto}

		/* Container */
		.container{max-width:1200px;margin:0 auto;padding:0 1rem}

		/* Featured Posts Grid */
		.featured-posts{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:2rem;margin:2rem 0}
		.post-card{background:#fff;border:1px solid #e5e5e5;border-radius:8px;overflow:hidden;transition:transform .2s}
		.post-card:hover{transform:translateY(-4px)}

		/* Skip to content */
		.skip-link{position:absolute;left:-999px;top:0;background:#0066cc;color:#fff;padding:.5rem 1rem;text-decoration:none}
		.skip-link:focus{left:0}
	';
}

/**
 * Critical CSS for Single Post/Page
 *
 * @since 1.0.0
 * @return string
 */
function roi_get_single_critical_css() {
	return '
		/* Reset and Base */
		*,*::before,*::after{box-sizing:border-box}
		body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;line-height:1.6;color:#333;background:#fff}
		img{max-width:100%;height:auto;display:block}
		a{color:#0066cc;text-decoration:none}
		h1,h2,h3,h4,h5,h6{margin:1.5rem 0 1rem;font-weight:700;line-height:1.3}
		h1{font-size:2.5rem}
		h2{font-size:2rem}
		h3{font-size:1.5rem}
		p{margin:0 0 1.5rem}

		/* Header */
		.site-header{background:#fff;border-bottom:1px solid #e5e5e5;position:sticky;top:0;z-index:1000}
		.site-header .container{max-width:1200px;margin:0 auto;padding:1rem}

		/* Article */
		.entry-header{margin:2rem 0}
		.entry-title{font-size:2.5rem;margin:0 0 1rem;line-height:1.2}
		.entry-meta{color:#666;font-size:.875rem}
		.entry-content{max-width:800px;margin:0 auto;font-size:1.125rem;line-height:1.8}
		.featured-image{margin:2rem 0}

		/* Container */
		.container{max-width:1200px;margin:0 auto;padding:0 1rem}

		/* Skip to content */
		.skip-link{position:absolute;left:-999px;top:0;background:#0066cc;color:#fff;padding:.5rem 1rem;text-decoration:none}
		.skip-link:focus{left:0}
	';
}

/**
 * Critical CSS for Archive Pages
 *
 * @since 1.0.0
 * @return string
 */
function roi_get_archive_critical_css() {
	return '
		/* Reset and Base */
		*,*::before,*::after{box-sizing:border-box}
		body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;line-height:1.6;color:#333;background:#fff}
		img{max-width:100%;height:auto;display:block}
		a{color:#0066cc;text-decoration:none}

		/* Header */
		.site-header{background:#fff;border-bottom:1px solid #e5e5e5;position:sticky;top:0;z-index:1000}
		.site-header .container{max-width:1200px;margin:0 auto;padding:1rem}

		/* Archive Header */
		.archive-header{padding:2rem 1rem;background:#f8f9fa;border-bottom:1px solid #e5e5e5}
		.archive-title{margin:0;font-size:2rem;font-weight:700}
		.archive-description{margin:1rem 0 0;color:#666;font-size:1.125rem}

		/* Posts Grid */
		.posts-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:2rem;margin:2rem 0}
		.post-card{background:#fff;border:1px solid #e5e5e5;border-radius:8px;overflow:hidden}

		/* Container */
		.container{max-width:1200px;margin:0 auto;padding:0 1rem}

		/* Skip to content */
		.skip-link{position:absolute;left:-999px;top:0;background:#0066cc;color:#fff;padding:.5rem 1rem;text-decoration:none}
		.skip-link:focus{left:0}
	';
}

/**
 * Critical CSS for Default Pages
 *
 * @since 1.0.0
 * @return string
 */
function roi_get_default_critical_css() {
	return '
		/* Reset and Base */
		*,*::before,*::after{box-sizing:border-box}
		body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;line-height:1.6;color:#333;background:#fff}
		img{max-width:100%;height:auto;display:block}
		a{color:#0066cc;text-decoration:none}

		/* Header */
		.site-header{background:#fff;border-bottom:1px solid #e5e5e5;position:sticky;top:0;z-index:1000}
		.site-header .container{max-width:1200px;margin:0 auto;padding:1rem}

		/* Container */
		.container{max-width:1200px;margin:0 auto;padding:0 1rem}

		/* Content */
		.site-content{min-height:50vh;padding:2rem 0}

		/* Skip to content */
		.skip-link{position:absolute;left:-999px;top:0;background:#0066cc;color:#fff;padding:.5rem 1rem;text-decoration:none}
		.skip-link:focus{left:0}
	';
}

/**
 * Output Critical CSS inline in head
 *
 * @since 1.0.0
 */
function roi_output_critical_css() {
	if ( ! roi_is_critical_css_enabled() ) {
		return;
	}

	$critical_css = roi_get_critical_css();

	if ( empty( $critical_css ) ) {
		return;
	}

	// Minify CSS (remove extra whitespace and newlines)
	$critical_css = preg_replace( '/\s+/', ' ', $critical_css );
	$critical_css = trim( $critical_css );

	// Output inline critical CSS
	echo '<style id="roi-critical-css">' . $critical_css . '</style>' . "\n";
}
add_action( 'wp_head', 'roi_output_critical_css', 1 );

/**
 * Load main stylesheet asynchronously when critical CSS is enabled
 *
 * @since 1.0.0
 */
function roi_async_main_stylesheet() {
	if ( ! roi_is_critical_css_enabled() ) {
		return;
	}

	// Dequeue main stylesheet to prevent render-blocking
	wp_dequeue_style( 'roi-theme-style' );

	// Enqueue with media="print" and onload to load asynchronously
	wp_enqueue_style(
		'roi-theme-style-async',
		get_stylesheet_uri(),
		array(),
		ROI_VERSION,
		'print'
	);

	// Add onload attribute to switch media to "all"
	add_filter( 'style_loader_tag', 'roi_add_async_attribute', 10, 2 );
}
add_action( 'wp_enqueue_scripts', 'roi_async_main_stylesheet', 999 );

/**
 * Add async loading attributes to stylesheet
 *
 * @since 1.0.0
 * @param string $html   The link tag for the enqueued style.
 * @param string $handle The style's registered handle.
 * @return string Modified link tag
 */
function roi_add_async_attribute( $html, $handle ) {
	if ( 'roi-theme-style-async' !== $handle ) {
		return $html;
	}

	// Add onload attribute to switch media to "all"
	$html = str_replace(
		"media='print'",
		"media='print' onload=\"this.media='all'\"",
		$html
	);

	// Add noscript fallback
	$html .= '<noscript><link rel="stylesheet" href="' . get_stylesheet_uri() . '"></noscript>';

	return $html;
}

/**
 * Add Customizer setting for Critical CSS
 *
 * @since 1.0.0
 * @param WP_Customize_Manager $wp_customize Theme Customizer object.
 */
function roi_critical_css_customizer( $wp_customize ) {
	// Add Performance section
	$wp_customize->add_section(
		'roi_performance',
		array(
			'title'    => __( 'Performance Optimization', 'roi-theme' ),
			'priority' => 130,
		)
	);

	// Critical CSS Enable/Disable
	$wp_customize->add_setting(
		'roi_enable_critical_css',
		array(
			'default'           => false,
			'sanitize_callback' => 'roi_sanitize_checkbox',
			'transport'         => 'refresh',
		)
	);

	$wp_customize->add_control(
		'roi_enable_critical_css',
		array(
			'label'       => __( 'Enable Critical CSS', 'roi-theme' ),
			'description' => __( 'Inline critical CSS and load main stylesheet asynchronously. This can improve Core Web Vitals but may cause a flash of unstyled content (FOUC). Test thoroughly before enabling in production.', 'roi-theme' ),
			'section'     => 'roi_performance',
			'type'        => 'checkbox',
		)
	);
}
add_action( 'customize_register', 'roi_critical_css_customizer' );

/**
 * Clear critical CSS cache when theme is updated
 *
 * @since 1.0.0
 */
function roi_clear_critical_css_cache() {
	$page_types = array( 'home', 'single', 'archive', 'search', '404', 'page' );

	foreach ( $page_types as $type ) {
		delete_transient( 'roi_critical_css_' . $type );
	}
}
add_action( 'after_switch_theme', 'roi_clear_critical_css_cache' );
add_action( 'customize_save_after', 'roi_clear_critical_css_cache' );

/**
 * Output Hero Section Critical CSS
 *
 * This CSS is ALWAYS injected in the <head> to prevent CLS (Cumulative Layout Shift)
 * by reserving space for the hero section BEFORE it renders.
 *
 * The min-height values match the actual rendered height (~260px on desktop)
 * to prevent any layout shift when the dynamic CSS loads.
 *
 * @since 1.0.21
 * @see Public/Hero/Infrastructure/Ui/HeroRenderer.php
 */
function roi_output_hero_critical_css() {
	// Only output on single posts where hero is displayed
	if ( ! is_single() ) {
		return;
	}

	// Check if hero is enabled (read from database)
	$is_enabled = roi_get_component_setting( 'hero', 'visibility', 'is_enabled', true );
	if ( ! $is_enabled ) {
		return;
	}

	$critical_css = '
		/* Hero Critical CSS - Prevent CLS */
		.hero-section {
			min-height: 260px;
			background: linear-gradient(135deg, #1e3a5f 0%, #2c5282 100%);
			padding: 3rem 0;
			margin-bottom: 1.5rem;
			box-sizing: border-box;
		}
		.hero-section__title {
			min-height: 3.5rem;
			margin-bottom: 0;
		}
		.hero-section__badge {
			min-height: 32px;
			display: inline-block;
		}
		@media (max-width: 767.98px) {
			.hero-section {
				min-height: 200px;
			}
			.hero-section__title {
				min-height: 2.5rem;
			}
		}
	';

	// Minify CSS
	$critical_css = preg_replace( '/\s+/', ' ', $critical_css );
	$critical_css = trim( $critical_css );

	echo '<style id="roi-hero-critical-css">' . $critical_css . '</style>' . "\n";
}
add_action( 'wp_head', 'roi_output_hero_critical_css', 2 );
