<?php

if (!defined('ABSPATH')) {
    exit;
}

/**
 * Integration with Yet Another Stars Rating (YASR) plugin.
 *
 * Provides an option to disable schema markup generated by YASR
 * to avoid duplicate or conflicting structured data.
 *
 * Version detection:
 *  - YASR < 3.0  — microdata-based schema: disables via `yasr_enable_schema_markup`
 *  - YASR >= 3.0 — JSON-LD rich snippets:  disables via `yasr_enable_schema_markup`
 *                  AND `yasr_enable_rich_snippets` (introduced in 3.x)
 */
class SEO_Fury_YASR_Integration {

    /**
     * Returns true when YASR is currently active.
     */
    public static function is_active() {
        // Check known YASR constants (name varies across versions)
        if (defined('YASR_VERSION') || defined('YASR_PLUGIN_VERSION') || defined('YASR_PLUGIN_URL')) {
            return true;
        }

        // YASR < 3.0 registered a legacy widget function
        if (function_exists('yasr_register_widget')) {
            return true;
        }

        // Most reliable fallback: check if the plugin file is active
        if (function_exists('is_plugin_active')) {
            return is_plugin_active('yet-another-stars-rating/yet-another-stars-rating.php');
        }

        return false;
    }

    /**
     * Returns the installed YASR version string, or '0' when not found.
     */
    public static function get_version() {
        if (defined('YASR_VERSION')) {
            return YASR_VERSION;
        }

        if (defined('YASR_PLUGIN_VERSION')) {
            return YASR_PLUGIN_VERSION;
        }

        // Fallback: read plugin header directly (works even before YASR loads)
        $plugin_file = WP_PLUGIN_DIR . '/yet-another-stars-rating/yet-another-stars-rating.php';
        if (file_exists($plugin_file) && function_exists('get_plugin_data')) {
            $data = get_plugin_data($plugin_file, false, false);
            if (!empty($data['Version'])) {
                return $data['Version'];
            }
        }

        return '0';
    }

    public function __construct() {
        // Apply the schema-disable filters on init (frontend + admin AJAX)
        add_action('init', array($this, 'maybe_disable_yasr_schema'), 5);

        // Inject YASR aggregate rating into SEO Fury Product schema nodes
        add_filter('seo_fury_schema_all_nodes', array($this, 'inject_yasr_aggregate_rating'), 10, 2);
    }

    /**
     * Hooks into YASR's schema output if the option is enabled.
     *
     * Uses the version-appropriate filters:
     *  - YASR < 3.0  : yasr_enable_schema_markup
     *  - YASR >= 3.0 : yasr_enable_schema_markup + yasr_enable_rich_snippets
     *                  + direct remove_filter / remove_action fallback (YASR 3.4+)
     */
    public function maybe_disable_yasr_schema() {
        if (!get_option('seo_fury_disable_yasr_schema', 0)) {
            return;
        }

        if (!self::is_active()) {
            return;
        }

        $version = self::get_version();

        if (version_compare($version, '3.0', '<')) {
            // YASR < 3.0: microdata schema is controlled by a single filter
            add_filter('yasr_enable_schema_markup', '__return_false');
        } else {
            // YASR >= 3.0: try both filter-based approach and direct hook removal.
            // The filter approach covers older 3.x builds; the wp hook covers YASR 3.4+
            // where the filters may be bypassed in favour of direct the_content / wp_footer hooks.
            add_filter('yasr_enable_schema_markup', '__return_false');
            add_filter('yasr_enable_rich_snippets', '__return_false');

            // Fallback: remove the actual callbacks registered by $yasr_additional_rich_fields.
            // Must run at 'wp' (after YASR's init) so the global is already populated.
            add_action('wp', array($this, 'remove_yasr_schema_hooks'), 1);
        }
    }

    /**
     * Directly removes the schema hooks registered by YASR 3.4+ via $yasr_additional_rich_fields.
     * Called on the 'wp' action so that YASR's init has already run and the global is set.
     */
    public function remove_yasr_schema_hooks() {
        global $yasr_additional_rich_fields;

        if (!isset($yasr_additional_rich_fields)) {
            return;
        }

        remove_filter('the_content', array($yasr_additional_rich_fields, 'addSchema'), 99);
        remove_action('wp_footer', array($yasr_additional_rich_fields, 'addSchema'));
    }

    /**
     * Injects YASR aggregate rating data into any Product schema node built by SEO Fury.
     *
     * Hooked to seo_fury_schema_all_nodes (priority 10).
     * Only runs when the option seo_fury_yasr_inject_aggregate_rating is enabled.
     *
     * @param array    $nodes Full list of schema nodes about to be output.
     * @param \WP_Post $post  Current post object.
     * @return array
     */
    public function inject_yasr_aggregate_rating($nodes, $post) {
        if (!get_option('seo_fury_yasr_inject_aggregate_rating', 0)) {
            return $nodes;
        }

        if (!self::is_active()) {
            return $nodes;
        }

        if (!is_singular()) {
            return $nodes;
        }

        // Abort early if there is no Product node to enrich
        $has_product = false;
        foreach ($nodes as $node) {
            if (isset($node['@type']) && $node['@type'] === 'Product') {
                $has_product = true;
                break;
            }
        }
        if (!$has_product) {
            return $nodes;
        }

        global $wpdb;
        $table = $wpdb->prefix . 'yasr_log';

        // Verify the table exists before querying it
        if ($wpdb->get_var("SHOW TABLES LIKE '" . esc_sql($table) . "'") !== $table) {
            return $nodes;
        }

        $result = $wpdb->get_row($wpdb->prepare(
            "SELECT SUM(vote) AS sum_votes, COUNT(*) AS total_votes FROM `{$table}` WHERE post_id = %d",
            $post->ID
        ));

        if (!$result || empty($result->total_votes) || (int) $result->total_votes === 0) {
            return $nodes;
        }

        $rating_value    = round((float) $result->sum_votes / (float) $result->total_votes, 1);
        $aggregate_rating = array(
            '@type'       => 'AggregateRating',
            'ratingValue' => (string) $rating_value,
            'ratingCount' => (int) $result->total_votes,
            'bestRating'  => 5,
            'worstRating' => 1,
        );

        foreach ($nodes as $key => $node) {
            // Only fill in a rating the Product node doesn't already declare —
            // don't clobber one the schema generator (or another source) set.
            if (isset($node['@type']) && $node['@type'] === 'Product' && empty($node['aggregateRating'])) {
                $nodes[$key]['aggregateRating'] = $aggregate_rating;
            }
        }

        return $nodes;
    }

    /**
     * Register the settings fields inside the existing General settings group.
     * Called from SEO_Fury_Admin::register_settings().
     */
    public function register_settings() {
        if (!self::is_active()) {
            return;
        }

        register_setting('seo_fury_general_settings', 'seo_fury_disable_yasr_schema', array(
            'type'              => 'boolean',
            'default'           => 0,
            'sanitize_callback' => array($this, 'sanitize_checkbox'),
        ));

        register_setting('seo_fury_general_settings', 'seo_fury_yasr_inject_aggregate_rating', array(
            'type'              => 'boolean',
            'default'           => 0,
            'sanitize_callback' => array($this, 'sanitize_checkbox'),
        ));

        add_settings_section(
            'seo_fury_integrations_section',
            __('Third-party Integrations', 'seo-fury'),
            array($this, 'render_section_description'),
            'seo_fury_general_settings'
        );

        add_settings_field(
            'seo_fury_disable_yasr_schema',
            __('YASR Schema Markup', 'seo-fury'),
            array($this, 'render_field'),
            'seo_fury_general_settings',
            'seo_fury_integrations_section'
        );

        add_settings_field(
            'seo_fury_yasr_inject_aggregate_rating',
            __('YASR AggregateRating in Product Schema', 'seo-fury'),
            array($this, 'render_inject_field'),
            'seo_fury_general_settings',
            'seo_fury_integrations_section'
        );
    }

    public function render_section_description() {
        echo '<p>' . esc_html__('Settings for plugins installed alongside SEO Fury.', 'seo-fury') . '</p>';
    }

    public function render_field() {
        $enabled = (bool) get_option('seo_fury_disable_yasr_schema', 0);
        $version = self::get_version();
        $version_label = ($version !== '0') ? $version : __('unknown', 'seo-fury');

        $hook_info = version_compare($version, '3.0', '<')
            ? '<code>yasr_enable_schema_markup</code>'
            : '<code>yasr_enable_schema_markup</code> + <code>yasr_enable_rich_snippets</code> + <code>remove_action(wp_footer)</code>';
        ?>
        <label>
            <input type="checkbox"
                   name="seo_fury_disable_yasr_schema"
                   value="1"
                   <?php checked($enabled); ?>>
            <?php esc_html_e('Disable schema markup generated by YASR', 'seo-fury'); ?>
        </label>
        <p class="description">
            <?php
            printf(
                /* translators: 1: YASR version, 2: filter/action hook name(s) used to suppress schema */
                esc_html__('YASR %1$s detected. When enabled, schema markup output is suppressed via %2$s.', 'seo-fury'),
                esc_html($version_label),
                wp_kses($hook_info, array('code' => array()))
            );
            ?>
        </p>
        <?php
    }

    public function render_inject_field() {
        $enabled = (bool) get_option('seo_fury_yasr_inject_aggregate_rating', 0);
        ?>
        <label>
            <input type="checkbox"
                   name="seo_fury_yasr_inject_aggregate_rating"
                   value="1"
                   <?php checked($enabled); ?>>
            <?php esc_html_e('Add AggregateRating to the generated Product schema', 'seo-fury'); ?>
        </label>
        <p class="description">
            <?php esc_html_e('When enabled, SEO Fury reads the visitor ratings stored by YASR and injects an AggregateRating block into every Product schema node it outputs on singular pages. Requires YASR to be installed and at least one rating recorded for the post.', 'seo-fury'); ?>
        </p>
        <?php
    }

    public function sanitize_checkbox($input) {
        return ($input == 1) ? 1 : 0;
    }
}
