<?php
/**
 * Monthly Horoscope Block Renderer
 *
 * @package EZHoroscope
 */

defined( 'ABSPATH' ) || exit;

// Track block usage (first render only).
if ( function_exists( 'ezhp_track_block_usage' ) ) {
    ezhp_track_block_usage( 'monthly-horoscope', $attributes );
}

// Sanitize inputs.
$ezhp_sign     = isset( $attributes['sign'] ) ? sanitize_text_field( $attributes['sign'] ) : 'aries';
$ezhp_language = isset( $attributes['language'] ) ? sanitize_text_field( $attributes['language'] ) : 'en';
$ezhp_date     = isset( $attributes['horoscopeDate'] ) ? sanitize_text_field( $attributes['horoscopeDate'] ) : '';
$ezhp_api_key  = sanitize_text_field( get_option( 'ezhp_horoscope_activation_guid', '' ) );

// If no date specified, use current date.
if ( empty( $ezhp_date ) ) {
    $ezhp_date = gmdate( 'Y-m-d' );
}

// RTL language detection.
$ezhp_rtl_languages = array( 'ar', 'he', 'fa', 'ur', 'yi', 'ps', 'sd' );
$ezhp_is_rtl        = in_array( $ezhp_language, $ezhp_rtl_languages, true );

// Section visibility attributes.
$ezhp_show_theme       = isset( $attributes['showThemeSection'] ) ? (bool) $attributes['showThemeSection'] : true;
$ezhp_show_key_dates   = isset( $attributes['showKeyDatesSection'] ) ? (bool) $attributes['showKeyDatesSection'] : true;
$ezhp_show_focus_areas = isset( $attributes['showFocusAreasSection'] ) ? (bool) $attributes['showFocusAreasSection'] : true;
$ezhp_show_practices   = isset( $attributes['showPracticesSection'] ) ? (bool) $attributes['showPracticesSection'] : true;
$ezhp_show_mantra      = isset( $attributes['showMantraSection'] ) ? (bool) $attributes['showMantraSection'] : true;

// CTA attributes (sanitized).
$ezhp_cta1_enabled         = ! empty( $attributes['cta1Enabled'] );
$ezhp_cta1_position        = isset( $attributes['cta1Position'] ) ? sanitize_text_field( $attributes['cta1Position'] ) : 'after-theme';
$ezhp_cta1_header_text     = isset( $attributes['cta1HeaderText'] ) ? sanitize_text_field( $attributes['cta1HeaderText'] ) : '';
$ezhp_cta1_header_level    = isset( $attributes['cta1HeaderLevel'] ) ? sanitize_text_field( $attributes['cta1HeaderLevel'] ) : 'h3';
$ezhp_cta1_text            = isset( $attributes['cta1Text'] ) ? sanitize_text_field( $attributes['cta1Text'] ) : '';
$ezhp_cta1_image_url       = isset( $attributes['cta1ImageUrl'] ) ? esc_url( $attributes['cta1ImageUrl'] ) : '';
$ezhp_cta1_image_alt       = isset( $attributes['cta1ImageAlt'] ) ? sanitize_text_field( $attributes['cta1ImageAlt'] ) : '';
$ezhp_cta1_image_max_width = isset( $attributes['cta1ImageMaxWidth'] ) ? sanitize_text_field( $attributes['cta1ImageMaxWidth'] ) : '100%';
$ezhp_cta1_url             = isset( $attributes['cta1Url'] ) ? esc_url( $attributes['cta1Url'] ) : '';
$ezhp_cta1_link_type       = isset( $attributes['cta1LinkType'] ) ? sanitize_text_field( $attributes['cta1LinkType'] ) : 'button';
$ezhp_cta1_link_text       = isset( $attributes['cta1LinkText'] ) ? sanitize_text_field( $attributes['cta1LinkText'] ) : '';
$ezhp_cta1_image_clickable = ! empty( $attributes['cta1ImageClickable'] );
$ezhp_cta1_element_id      = isset( $attributes['cta1ElementId'] ) ? sanitize_html_class( $attributes['cta1ElementId'] ) : '';
$ezhp_cta1_alignment       = isset( $attributes['cta1Alignment'] ) ? sanitize_text_field( $attributes['cta1Alignment'] ) : 'center';

$ezhp_cta2_enabled         = ! empty( $attributes['cta2Enabled'] );
$ezhp_cta2_position        = isset( $attributes['cta2Position'] ) ? sanitize_text_field( $attributes['cta2Position'] ) : 'after-key-dates';
$ezhp_cta2_header_text     = isset( $attributes['cta2HeaderText'] ) ? sanitize_text_field( $attributes['cta2HeaderText'] ) : '';
$ezhp_cta2_header_level    = isset( $attributes['cta2HeaderLevel'] ) ? sanitize_text_field( $attributes['cta2HeaderLevel'] ) : 'h3';
$ezhp_cta2_text            = isset( $attributes['cta2Text'] ) ? sanitize_text_field( $attributes['cta2Text'] ) : '';
$ezhp_cta2_image_url       = isset( $attributes['cta2ImageUrl'] ) ? esc_url( $attributes['cta2ImageUrl'] ) : '';
$ezhp_cta2_image_alt       = isset( $attributes['cta2ImageAlt'] ) ? sanitize_text_field( $attributes['cta2ImageAlt'] ) : '';
$ezhp_cta2_image_max_width = isset( $attributes['cta2ImageMaxWidth'] ) ? sanitize_text_field( $attributes['cta2ImageMaxWidth'] ) : '100%';
$ezhp_cta2_url             = isset( $attributes['cta2Url'] ) ? esc_url( $attributes['cta2Url'] ) : '';
$ezhp_cta2_link_type       = isset( $attributes['cta2LinkType'] ) ? sanitize_text_field( $attributes['cta2LinkType'] ) : 'button';
$ezhp_cta2_link_text       = isset( $attributes['cta2LinkText'] ) ? sanitize_text_field( $attributes['cta2LinkText'] ) : '';
$ezhp_cta2_image_clickable = ! empty( $attributes['cta2ImageClickable'] );
$ezhp_cta2_element_id      = isset( $attributes['cta2ElementId'] ) ? sanitize_html_class( $attributes['cta2ElementId'] ) : '';
$ezhp_cta2_alignment       = isset( $attributes['cta2Alignment'] ) ? sanitize_text_field( $attributes['cta2Alignment'] ) : 'center';

$ezhp_cta3_enabled         = ! empty( $attributes['cta3Enabled'] );
$ezhp_cta3_position        = isset( $attributes['cta3Position'] ) ? sanitize_text_field( $attributes['cta3Position'] ) : 'after-focus-areas';
$ezhp_cta3_header_text     = isset( $attributes['cta3HeaderText'] ) ? sanitize_text_field( $attributes['cta3HeaderText'] ) : '';
$ezhp_cta3_header_level    = isset( $attributes['cta3HeaderLevel'] ) ? sanitize_text_field( $attributes['cta3HeaderLevel'] ) : 'h3';
$ezhp_cta3_text            = isset( $attributes['cta3Text'] ) ? sanitize_text_field( $attributes['cta3Text'] ) : '';
$ezhp_cta3_image_url       = isset( $attributes['cta3ImageUrl'] ) ? esc_url( $attributes['cta3ImageUrl'] ) : '';
$ezhp_cta3_image_alt       = isset( $attributes['cta3ImageAlt'] ) ? sanitize_text_field( $attributes['cta3ImageAlt'] ) : '';
$ezhp_cta3_image_max_width = isset( $attributes['cta3ImageMaxWidth'] ) ? sanitize_text_field( $attributes['cta3ImageMaxWidth'] ) : '100%';
$ezhp_cta3_url             = isset( $attributes['cta3Url'] ) ? esc_url( $attributes['cta3Url'] ) : '';
$ezhp_cta3_link_type       = isset( $attributes['cta3LinkType'] ) ? sanitize_text_field( $attributes['cta3LinkType'] ) : 'button';
$ezhp_cta3_link_text       = isset( $attributes['cta3LinkText'] ) ? sanitize_text_field( $attributes['cta3LinkText'] ) : '';
$ezhp_cta3_image_clickable = ! empty( $attributes['cta3ImageClickable'] );
$ezhp_cta3_element_id      = isset( $attributes['cta3ElementId'] ) ? sanitize_html_class( $attributes['cta3ElementId'] ) : '';
$ezhp_cta3_alignment       = isset( $attributes['cta3Alignment'] ) ? sanitize_text_field( $attributes['cta3Alignment'] ) : 'center';

// Check if user can use premium code.
$ezhp_is_premium = function_exists( 'ezhp_fs' ) && ezhp_fs()->can_use_premium_code__premium_only();

// Build cache key.
$ezhp_cache_key_parts = 'monthly_' . $ezhp_sign . '_' . $ezhp_language . '_' . $ezhp_date . '_' .
    ( isset( $attributes['heroImageUrl'] ) ? $attributes['heroImageUrl'] : '' ) . '_' .
    ( isset( $attributes['heroImageDisplayMode'] ) ? $attributes['heroImageDisplayMode'] : '' ) . '_' .
    ( isset( $attributes['heroImageAlignment'] ) ? $attributes['heroImageAlignment'] : '' ) . '_' .
    ( isset( $attributes['heroImageTextWrap'] ) ? $attributes['heroImageTextWrap'] : '' ) . '_' .
    ( isset( $attributes['heroImageOverlayOpacity'] ) ? $attributes['heroImageOverlayOpacity'] : '' ) . '_' .
    ( isset( $attributes['heroImageOverlayColor'] ) ? $attributes['heroImageOverlayColor'] : '' ) . '_' .
    ( isset( $attributes['heroImageMaxWidth'] ) ? $attributes['heroImageMaxWidth'] : '' ) . '_' .
    ( isset( $attributes['suppressHeading'] ) ? $attributes['suppressHeading'] : '' );

// Add section visibility to cache key.
$ezhp_cache_key_parts .= '_' .
    ( $ezhp_show_theme ? '1' : '0' ) . '_' .
    ( $ezhp_show_key_dates ? '1' : '0' ) . '_' .
    ( $ezhp_show_focus_areas ? '1' : '0' ) . '_' .
    ( $ezhp_show_practices ? '1' : '0' ) . '_' .
    ( $ezhp_show_mantra ? '1' : '0' );

// Add CTA settings to cache key for premium users.
if ( $ezhp_is_premium ) {
    $ezhp_cache_key_parts .= '_' .
        ( $ezhp_cta1_enabled ? '1' : '0' ) . '_' . $ezhp_cta1_position . '_' .
        ( $ezhp_cta2_enabled ? '1' : '0' ) . '_' . $ezhp_cta2_position . '_' .
        ( $ezhp_cta3_enabled ? '1' : '0' ) . '_' . $ezhp_cta3_position;
}

$ezhp_cache_key = 'ezhp_monthly_' . md5( $ezhp_cache_key_parts );

// Skip cache in REST context (block editor preview).
$ezhp_is_rest = defined( 'REST_REQUEST' ) && REST_REQUEST;

if ( ! $ezhp_is_rest ) {
    $ezhp_cached = get_transient( $ezhp_cache_key );
    if ( $ezhp_cached && false === strpos( $ezhp_cached, 'error' ) ) {
        echo wp_kses_post( $ezhp_cached );
        return;
    }
}

// Build API URL.
$ezhp_api_url = sprintf(
    'https://api.ezhoroscope.com/api/MonthlyHoroscope/western-monthly?zodiacSign=%s&date=%s&apikey=%s&language=%s',
    rawurlencode( $ezhp_sign ),
    rawurlencode( $ezhp_date ),
    rawurlencode( $ezhp_api_key ),
    rawurlencode( $ezhp_language )
);

// Fetch API data.
$ezhp_response = wp_remote_get(
    $ezhp_api_url,
    array(
        'timeout' => 30,
        'headers' => array( 'Accept' => 'application/json' ),
    )
);

if ( is_wp_error( $ezhp_response ) ) {
    echo '<div class="ez-horoscope-block-error">' . esc_html__( 'Unable to retrieve horoscope at this time.', 'ez-horoscope' ) . '</div>';
    return;
}

$ezhp_body = wp_remote_retrieve_body( $ezhp_response );
$ezhp_data = json_decode( $ezhp_body, true );

// Graceful fallback if API response invalid.
if ( empty( $ezhp_data ) || ! isset( $ezhp_data['horoscopeText'] ) ) {
    echo '<div class="ez-horoscope-block-error">' . esc_html__( 'No horoscope data available for this month.', 'ez-horoscope' ) . '</div>';
    return;
}

// Get the horoscope HTML.
$ezhp_html = $ezhp_data['horoscopeText'];

// Hero Image Config.
$ezhp_hero_url     = isset( $attributes['heroImageUrl'] ) ? $attributes['heroImageUrl'] : '';
$ezhp_hero_mode    = isset( $attributes['heroImageDisplayMode'] ) ? $attributes['heroImageDisplayMode'] : 'inline';
$ezhp_hero_align   = isset( $attributes['heroImageAlignment'] ) ? $attributes['heroImageAlignment'] : 'center';
$ezhp_hero_wrap    = isset( $attributes['heroImageTextWrap'] ) ? $attributes['heroImageTextWrap'] : 'none';
$ezhp_hero_alt     = isset( $attributes['heroImageAlt'] ) ? esc_attr( $attributes['heroImageAlt'] ) : '';
$ezhp_hero_opacity = isset( $attributes['heroImageOverlayOpacity'] ) ? floatval( $attributes['heroImageOverlayOpacity'] ) : 0;
$ezhp_hero_color   = isset( $attributes['heroImageOverlayColor'] ) ? $attributes['heroImageOverlayColor'] : 'black';
$ezhp_hero_width   = isset( $attributes['heroImageMaxWidth'] ) ? $attributes['heroImageMaxWidth'] : '40%';

// Process hero image if set.
if ( ! empty( $ezhp_hero_url ) ) {
    if ( 'background' === $ezhp_hero_mode ) {
        // Build background CSS.
        $ezhp_style  = "background-image:url('" . esc_url( $ezhp_hero_url ) . "');";
        $ezhp_style .= 'background-size:cover;background-repeat:no-repeat;background-position:' . esc_attr( $ezhp_hero_align ) . ';';
        $ezhp_style .= 'display:block;min-height:300px;position:relative;';

        // Inject style into .ez-monthly-header.
        $ezhp_html = preg_replace(
            '/(<header[^>]*class="[^"]*\bez-monthly-header\b[^"]*"[^>]*)(>)/is',
            '$1 style="' . $ezhp_style . '"$2',
            $ezhp_html,
            1
        );

        // Overlay logic.
        $ezhp_hero_opacity = max( 0, min( 100, $ezhp_hero_opacity ) );

        if ( $ezhp_hero_opacity > 0 ) {
            $ezhp_opacity_css   = $ezhp_hero_opacity / 100;
            $ezhp_overlay_color = ( 'white' === $ezhp_hero_color ) ? '255,255,255' : '0,0,0';
            $ezhp_overlay_class = ( 'white' === $ezhp_hero_color ) ? 'ez-hero-overlay light' : 'ez-hero-overlay dark';
            $ezhp_overlay_style = sprintf(
                'background-color:rgba(%s,%.2f);opacity:1;position:absolute;top:0;left:0;right:0;bottom:0;pointer-events:none;z-index:1;',
                $ezhp_overlay_color,
                $ezhp_opacity_css
            );
            $ezhp_overlay_html = '<div class="' . esc_attr( $ezhp_overlay_class ) . '" style="' . esc_attr( $ezhp_overlay_style ) . '"></div>';

            // Insert overlay after header opening tag.
            $ezhp_html = preg_replace(
                '/(<header[^>]*class="[^"]*\bez-monthly-header\b[^"]*"[^>]*>)/is',
                '$1' . $ezhp_overlay_html,
                $ezhp_html,
                1
            );
        }
    } elseif ( 'inline' === $ezhp_hero_mode ) {
        // Determine float/margin.
        switch ( $ezhp_hero_wrap ) {
            case 'left':
                $ezhp_float_style = 'float:left;margin:0 1rem 1rem 0;';
                break;
            case 'right':
                $ezhp_float_style = 'float:right;margin:0 0 1rem 1rem;';
                break;
            default:
                $ezhp_float_style = 'display:block;margin-left:auto;margin-right:auto;margin-bottom:1rem;';
                break;
        }

        $ezhp_inline_html  = '<div class="ez-monthly-inline-image" style="position:relative;max-width:' . esc_attr( $ezhp_hero_width ) . ';' . esc_attr( $ezhp_float_style ) . '">';
        $ezhp_inline_html .= '<img src="' . esc_url( $ezhp_hero_url ) . '" alt="' . esc_attr( $ezhp_hero_alt ) . '" ';
        $ezhp_inline_html .= 'style="width:100%;height:auto;border-radius:8px;display:block;">';

        if ( $ezhp_hero_opacity > 0 ) {
            $ezhp_overlay_color = ( 'white' === $ezhp_hero_color ) ? '255,255,255' : '0,0,0';
            $ezhp_inline_html  .= '<div class="ez-hero-overlay" style="position:absolute;inset:0;';
            $ezhp_inline_html  .= 'background-color:rgba(' . $ezhp_overlay_color . ',' . ( $ezhp_hero_opacity / 100 ) . ');border-radius:8px;pointer-events:none;"></div>';
        }
        $ezhp_inline_html .= '</div>';

        // Insert inline image at the beginning of the theme section content.
        // This ensures the float is contained within the theme section only.
        $ezhp_html = preg_replace(
            '/(<div[^>]*class="[^"]*ez-monthly-theme-content[^"]*"[^>]*>)/is',
            '$1' . $ezhp_inline_html,
            $ezhp_html,
            1
        );
    }
}

// H1 suppression.
if ( ! empty( $attributes['suppressHeading'] ) && $attributes['suppressHeading'] ) {
    $ezhp_html = preg_replace( '/<h1[^>]*class="[^"]*ez-monthly-title[^"]*"[^>]*>.*?<\/h1>/is', '', $ezhp_html );
}

// Use DOMDocument for section hiding.
if ( ! $ezhp_show_theme || ! $ezhp_show_key_dates || ! $ezhp_show_focus_areas || ! $ezhp_show_practices || ! $ezhp_show_mantra ) {

    $ezhp_dom = new DOMDocument();
    libxml_use_internal_errors( true );
    $ezhp_dom->loadHTML( '<?xml encoding="UTF-8"?>' . $ezhp_html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD );
    libxml_clear_errors();

    $ezhp_xpath             = new DOMXPath( $ezhp_dom );
    $ezhp_elements_to_remove = array();

    // Hide Theme Section.
    if ( ! $ezhp_show_theme ) {
        $ezhp_nodes = $ezhp_xpath->query( '//section[contains(@class, "ez-monthly-theme")]' );
        foreach ( $ezhp_nodes as $ezhp_node ) {
            $ezhp_elements_to_remove[] = $ezhp_node;
        }
    }

    // Hide Key Dates Section.
    if ( ! $ezhp_show_key_dates ) {
        $ezhp_nodes = $ezhp_xpath->query( '//section[contains(@class, "ez-monthly-key-dates")]' );
        foreach ( $ezhp_nodes as $ezhp_node ) {
            $ezhp_elements_to_remove[] = $ezhp_node;
        }
    }

    // Hide Focus Areas Section.
    if ( ! $ezhp_show_focus_areas ) {
        $ezhp_nodes = $ezhp_xpath->query( '//section[contains(@class, "ez-monthly-focus-areas")]' );
        foreach ( $ezhp_nodes as $ezhp_node ) {
            $ezhp_elements_to_remove[] = $ezhp_node;
        }
    }

    // Hide Practices Section.
    if ( ! $ezhp_show_practices ) {
        $ezhp_nodes = $ezhp_xpath->query( '//section[contains(@class, "ez-monthly-practices")]' );
        foreach ( $ezhp_nodes as $ezhp_node ) {
            $ezhp_elements_to_remove[] = $ezhp_node;
        }
    }

    // Hide Mantra Section.
    if ( ! $ezhp_show_mantra ) {
        $ezhp_nodes = $ezhp_xpath->query( '//section[contains(@class, "ez-monthly-mantra")]' );
        foreach ( $ezhp_nodes as $ezhp_node ) {
            $ezhp_elements_to_remove[] = $ezhp_node;
        }
    }

    // Remove all collected elements.
    foreach ( $ezhp_elements_to_remove as $ezhp_element ) {
        if ( $ezhp_element && $ezhp_element->parentNode ) {
            $ezhp_element->parentNode->removeChild( $ezhp_element );
        }
    }

    // Get the processed HTML back.
    $ezhp_html = $ezhp_dom->saveHTML();

    // Remove the XML declaration we added.
    $ezhp_html = preg_replace( '/^<\?xml encoding="UTF-8"\?>\s*/i', '', $ezhp_html );
}

if ( ! function_exists( 'ezhp_monthly_build_cta' ) ) {
    /**
     * Build CTA HTML.
     *
     * @param int    $ezhp_slot_num        CTA slot number.
     * @param string $ezhp_header_text     Header text.
     * @param string $ezhp_header_level    Header level (h2, h3, h4).
     * @param string $ezhp_text            Body text.
     * @param string $ezhp_image_url       Image URL.
     * @param string $ezhp_image_alt       Image alt text.
     * @param string $ezhp_image_max_width Image max width CSS value.
     * @param string $ezhp_url             Link URL.
     * @param string $ezhp_link_type       Link type (button, text, image).
     * @param string $ezhp_link_text       Link text.
     * @param bool   $ezhp_image_clickable Whether image is clickable.
     * @param string $ezhp_element_id      Element ID.
     * @param string $ezhp_alignment       Alignment (left, center, right).
     * @return string CTA HTML.
     */
    function ezhp_monthly_build_cta( $ezhp_slot_num, $ezhp_header_text, $ezhp_header_level, $ezhp_text, $ezhp_image_url, $ezhp_image_alt, $ezhp_image_max_width, $ezhp_url, $ezhp_link_type, $ezhp_link_text, $ezhp_image_clickable, $ezhp_element_id, $ezhp_alignment ) {
        $ezhp_valid_levels = array( 'h2', 'h3', 'h4' );
        $ezhp_header_level = in_array( $ezhp_header_level, $ezhp_valid_levels, true ) ? $ezhp_header_level : 'h3';

        $ezhp_valid_alignments = array( 'left', 'center', 'right' );
        $ezhp_alignment        = in_array( $ezhp_alignment, $ezhp_valid_alignments, true ) ? $ezhp_alignment : 'center';

        // Sanitize image max width.
        $ezhp_image_max_width = ! empty( $ezhp_image_max_width ) ? $ezhp_image_max_width : '100%';

        $ezhp_cta_html  = '<div class="ez-monthly-cta ez-monthly-cta-' . esc_attr( $ezhp_slot_num ) . ' ez-monthly-cta-' . esc_attr( $ezhp_alignment ) . '"';
        if ( ! empty( $ezhp_element_id ) ) {
            $ezhp_cta_html .= ' id="' . esc_attr( $ezhp_element_id ) . '"';
        }
        $ezhp_cta_html .= '>';

        // Header.
        if ( ! empty( $ezhp_header_text ) ) {
            $ezhp_cta_html .= '<' . esc_attr( $ezhp_header_level ) . ' class="ez-monthly-cta-header">' . esc_html( $ezhp_header_text ) . '</' . esc_attr( $ezhp_header_level ) . '>';
        }

        // Text.
        if ( ! empty( $ezhp_text ) ) {
            $ezhp_cta_html .= '<p class="ez-monthly-cta-text">' . esc_html( $ezhp_text ) . '</p>';
        }

        // Image.
        if ( ! empty( $ezhp_image_url ) ) {
            $ezhp_img_style = 'max-width:' . esc_attr( $ezhp_image_max_width ) . ';height:auto;';
            $ezhp_img_tag   = '<img src="' . esc_url( $ezhp_image_url ) . '" alt="' . esc_attr( $ezhp_image_alt ) . '" class="ez-monthly-cta-image" style="' . $ezhp_img_style . '">';

            if ( 'image' === $ezhp_link_type || $ezhp_image_clickable ) {
                $ezhp_cta_html .= '<a href="' . esc_url( $ezhp_url ) . '" target="_blank" rel="noopener noreferrer" class="ez-monthly-cta-image-link">' . $ezhp_img_tag . '</a>';
            } else {
                $ezhp_cta_html .= $ezhp_img_tag;
            }
        }

        // Link/Button.
        if ( 'image' !== $ezhp_link_type && ! empty( $ezhp_link_text ) ) {
            $ezhp_link_class = ( 'button' === $ezhp_link_type ) ? 'wp-element-button ez-monthly-cta-button' : 'ez-monthly-cta-link';
            $ezhp_cta_html  .= '<a href="' . esc_url( $ezhp_url ) . '" target="_blank" rel="noopener noreferrer" class="' . esc_attr( $ezhp_link_class ) . '">' . esc_html( $ezhp_link_text ) . '</a>';
        }

        $ezhp_cta_html .= '</div>';

        return $ezhp_cta_html;
    }
}

if ( ! function_exists( 'ezhp_monthly_insert_cta' ) ) {
    /**
     * Insert CTA at specified position.
     *
     * @param string $ezhp_html     The HTML content.
     * @param string $ezhp_position Position identifier.
     * @param string $ezhp_cta_html CTA HTML to insert.
     * @return string Modified HTML.
     */
    function ezhp_monthly_insert_cta( $ezhp_html, $ezhp_position, $ezhp_cta_html ) {
        $ezhp_section_map = array(
            'before-theme'       => array( 'pattern' => '/(<section[^>]*class="[^"]*ez-monthly-theme[^"]*")/is', 'before' => true ),
            'after-theme'        => array( 'pattern' => '/(<\/section>)(\s*<section[^>]*class="[^"]*ez-monthly-key-dates)/is', 'replace' => '$1' . $ezhp_cta_html . '$2' ),
            'before-key-dates'   => array( 'pattern' => '/(<section[^>]*class="[^"]*ez-monthly-key-dates[^"]*")/is', 'before' => true ),
            'after-key-dates'    => array( 'pattern' => '/(<\/section>)(\s*<section[^>]*class="[^"]*ez-monthly-focus-areas)/is', 'replace' => '$1' . $ezhp_cta_html . '$2' ),
            'before-focus-areas' => array( 'pattern' => '/(<section[^>]*class="[^"]*ez-monthly-focus-areas[^"]*")/is', 'before' => true ),
            'after-focus-areas'  => array( 'pattern' => '/(<\/section>)(\s*<section[^>]*class="[^"]*ez-monthly-practices)/is', 'replace' => '$1' . $ezhp_cta_html . '$2' ),
            'before-practices'   => array( 'pattern' => '/(<section[^>]*class="[^"]*ez-monthly-practices[^"]*")/is', 'before' => true ),
            'after-practices'    => array( 'pattern' => '/(<\/section>)(\s*<section[^>]*class="[^"]*ez-monthly-mantra)/is', 'replace' => '$1' . $ezhp_cta_html . '$2' ),
            'before-mantra'      => array( 'pattern' => '/(<section[^>]*class="[^"]*ez-monthly-mantra[^"]*")/is', 'before' => true ),
            'after-mantra'       => array( 'pattern' => '/(<section[^>]*class="[^"]*ez-monthly-mantra[^"]*"[^>]*>.*?<\/section>)/is', 'after' => true ),
        );

        if ( ! isset( $ezhp_section_map[ $ezhp_position ] ) ) {
            return $ezhp_html;
        }

        $ezhp_config = $ezhp_section_map[ $ezhp_position ];

        if ( isset( $ezhp_config['before'] ) && $ezhp_config['before'] ) {
            $ezhp_html = preg_replace( $ezhp_config['pattern'], $ezhp_cta_html . '$1', $ezhp_html, 1 );
        } elseif ( isset( $ezhp_config['after'] ) && $ezhp_config['after'] ) {
            $ezhp_html = preg_replace( $ezhp_config['pattern'], '$1' . $ezhp_cta_html, $ezhp_html, 1 );
        } elseif ( isset( $ezhp_config['replace'] ) ) {
            $ezhp_html = preg_replace( $ezhp_config['pattern'], $ezhp_config['replace'], $ezhp_html, 1 );
        }

        return $ezhp_html;
    }
}

// Insert CTAs based on position.
$ezhp_should_output_cta = false;

// Editor preview: All users can see CTAs.
if ( $ezhp_is_rest ) {
    $ezhp_should_output_cta = true;
}

// Frontend: Only premium users.
if ( function_exists( 'ezhp_fs' ) && ezhp_fs()->can_use_premium_code__premium_only() ) {
    $ezhp_should_output_cta = true;
}

if ( $ezhp_should_output_cta ) {
    // CTA 1.
    if ( $ezhp_cta1_enabled ) {
        $ezhp_cta1_html = ezhp_monthly_build_cta(
            1,
            $ezhp_cta1_header_text,
            $ezhp_cta1_header_level,
            $ezhp_cta1_text,
            $ezhp_cta1_image_url,
            $ezhp_cta1_image_alt,
            $ezhp_cta1_image_max_width,
            $ezhp_cta1_url,
            $ezhp_cta1_link_type,
            $ezhp_cta1_link_text,
            $ezhp_cta1_image_clickable,
            $ezhp_cta1_element_id,
            $ezhp_cta1_alignment
        );
        $ezhp_html = ezhp_monthly_insert_cta( $ezhp_html, $ezhp_cta1_position, $ezhp_cta1_html );
    }

    // CTA 2.
    if ( $ezhp_cta2_enabled ) {
        $ezhp_cta2_html = ezhp_monthly_build_cta(
            2,
            $ezhp_cta2_header_text,
            $ezhp_cta2_header_level,
            $ezhp_cta2_text,
            $ezhp_cta2_image_url,
            $ezhp_cta2_image_alt,
            $ezhp_cta2_image_max_width,
            $ezhp_cta2_url,
            $ezhp_cta2_link_type,
            $ezhp_cta2_link_text,
            $ezhp_cta2_image_clickable,
            $ezhp_cta2_element_id,
            $ezhp_cta2_alignment
        );
        $ezhp_html = ezhp_monthly_insert_cta( $ezhp_html, $ezhp_cta2_position, $ezhp_cta2_html );
    }

    // CTA 3.
    if ( $ezhp_cta3_enabled ) {
        $ezhp_cta3_html = ezhp_monthly_build_cta(
            3,
            $ezhp_cta3_header_text,
            $ezhp_cta3_header_level,
            $ezhp_cta3_text,
            $ezhp_cta3_image_url,
            $ezhp_cta3_image_alt,
            $ezhp_cta3_image_max_width,
            $ezhp_cta3_url,
            $ezhp_cta3_link_type,
            $ezhp_cta3_link_text,
            $ezhp_cta3_image_clickable,
            $ezhp_cta3_element_id,
            $ezhp_cta3_alignment
        );
        $ezhp_html = ezhp_monthly_insert_cta( $ezhp_html, $ezhp_cta3_position, $ezhp_cta3_html );
    }
}

// Wrap & output safely.
$ezhp_dir_attr = $ezhp_is_rtl ? ' dir="rtl"' : '';
$ezhp_output   = '<div class="ez-horoscope-block ez-monthly-horoscope-block"' . $ezhp_dir_attr . '>';
$ezhp_output  .= $ezhp_html;
$ezhp_output  .= '</div>';

// Only cache successful, non-error responses (skip in REST context).
if ( ! $ezhp_is_rest && ! empty( $ezhp_html ) && false === strpos( $ezhp_html, 'error' ) ) {
    set_transient( $ezhp_cache_key, $ezhp_output, HOUR_IN_SECONDS );
}

echo wp_kses_post( $ezhp_output );