<?php
/**
 * Plugin Name: Instant Indexing & Check
 * Description: Forcez l'indexation instantanée de vos contenus. Google API (Gratuit) & Premium Force Index (90% Success Rate).
 * Version: 1.1.3
 * Author: Arthur SEO
 * Author URI: https://wp-instant-indexing.com
 * License: GPLv2 or later
 * License URI: http://www.gnu.org/licenses/gpl-2.0.html
 */

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

// --- CONFIGURATION ---
define('IIC_CHECK_VERSION', '1.1.3');
define('IIC_CHECK_SALES_URL', 'https://wp-instant-indexing.com');
define('IIC_CHECK_API_URL', 'https://wp-instant-indexing.com/check_license.php');
define('IIC_CHECK_RELAY_URL', 'https://wp-instant-indexing.com/relay_ralfy.php');
define('IIC_CHECK_UPDATE_URL', 'https://wp-instant-indexing.com/metadata.json');

if (file_exists(plugin_dir_path(__FILE__) . 'vendor/autoload.php')) {
    require_once plugin_dir_path(__FILE__) . 'vendor/autoload.php';
}

// --- INIT AUTO-UPDATE ---
// Auto-update removed for WordPress.org compliance
// add_action('init', function () { ... });

add_action('admin_menu', function () {
    add_menu_page('Instant Index', 'Instant Index', 'manage_options', 'instant-indexing-check', function () {
        echo '<div id="sip-root"></div>';
    }, 'dashicons-google', 30);
});

// --- ENQUEUE SCRIPTS & DATA ---
add_action('admin_enqueue_scripts', function ($hook) {
    if ($hook != 'toplevel_page_instant-indexing-check')
        return;

    $ver = time(); // Force le rafraîchissement

    wp_enqueue_style('iic-style', plugin_dir_url(__FILE__) . 'admin-style.css', [], $ver);
    wp_enqueue_script('iic-app', plugin_dir_url(__FILE__) . 'admin-app.js', [], $ver, true);

    $google_key = get_option('iic_check_google_json_key');
    $auto_mode = get_option('iic_check_auto_index_mode', 'disabled');

    // Données chargées : Historique et Crédits
    $history = get_option('iic_check_premium_history', []);
    $credits = get_option('iic_check_user_credits', 0);

    wp_localize_script('iic-app', 'iic_check_config', [
        'ajaxUrl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('iic_check_security_token'),
        'hasKey' => (!empty($google_key) && !empty(get_option('iic_check_gsc_site_url'))),
        'autoMode' => $auto_mode,
        'siteUrl' => site_url(),
        'status' => get_option('iic_check_saas_status', false),
        'credits' => $credits, // On envoie le solde au JS
        'pluginUrl' => plugin_dir_url(__FILE__),
        'salesUrl' => IIC_CHECK_SALES_URL,
        'history' => $history,
        'locale' => get_option('iic_check_locale', get_locale()), // Prefer user setting, fallback to WP
    ]);
});

function iic_check_send_json($data, $success = true)
{
    // Clean buffer before sending JSON to avoid invalid response
    while (ob_get_level()) {
        ob_end_clean();
    }

    if ($success)
        wp_send_json_success($data);
    else
        wp_send_json_error($data);
}

// --- APPEL API DISTANT (RELAY) ---
function iic_check_call_premium_relay($url)
{
    $license_key = get_option('iic_check_saas_license_key');
    if (empty($license_key))
        return ['status' => 'error', 'message' => 'Licence manquante'];

    $response = wp_remote_post(IIC_CHECK_RELAY_URL, [
        'body' => ['license_key' => $license_key, 'url' => esc_url_raw($url)],
        'timeout' => 20
    ]);

    if (is_wp_error($response))
        return ['status' => 'error', 'message' => 'Erreur Relais : ' . $response->get_error_message()];
    return json_decode(wp_remote_retrieve_body($response), true);
}

// --- GESTION HISTORIQUE ---
function iic_check_add_history($url)
{
    $history = get_option('iic_check_premium_history', []);
    $history[$url] = time();
    // Garde max 2000 entrées pour ne pas surcharger
    if (count($history) > 2000) {
        array_shift($history);
    }
    update_option('iic_check_premium_history', $history);
}

// --- AJAX : MARQUER COMME ENVOYÉ ---
add_action('wp_ajax_iic_check_mark_premium', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    check_ajax_referer('iic_check_security_token', 'nonce');
    // Sanitization issue fixed
    if (!isset($_POST['url'])) {
        iic_check_send_json('Missing URL', false);
        return;
    }
    $url = esc_url_raw(wp_unslash($_POST['url']));
    iic_check_add_history($url);
    iic_check_send_json('OK');
});

// --- AUTO-INDEX ---
add_action('transition_post_status', 'iic_check_auto_index_logic', 10, 3);
function iic_check_auto_index_logic($new, $old, $post)
{
    if ($new === 'publish' && $old !== 'publish') {
        if (get_option('iic_check_saas_status') !== 'premium')
            return;
        $mode = get_option('iic_check_auto_index_mode', 'disabled');
        if ($mode === 'disabled')
            return;

        $url = get_permalink($post->ID);

        if ($mode === 'google') {
            $json = get_option('iic_check_google_json_key');
            if ($json && $url) {
                try {
                    $client = new Google_Client();
                    $client->setAuthConfig($json);
                    $client->addScope('https://www.googleapis.com/auth/indexing');
                    $service = new Google_Service_Indexing($client);
                    $body = new Google_Service_Indexing_UrlNotification();
                    $body->setUrl($url);
                    $body->setType('URL_UPDATED');
                    $service->urlNotifications->publish($body);
                    iic_check_log("[AUTO-GOOGLE] Envoyé : $url", 'success');
                } catch (Exception $e) {
                    iic_check_log("[AUTO-GOOGLE] Erreur", 'error');
                }
            }
        }

        if ($mode === 'premium') {
            $res = iic_check_call_premium_relay($url);
            if (isset($res['status']) && $res['status'] === 'ok') {
                iic_check_add_history($url);
                // Si le serveur renvoie le nouveau solde, on le met à jour
                if (isset($res['new_credits'])) {
                    update_option('iic_check_user_credits', $res['new_credits']);
                }
                iic_check_log("[AUTO-PREMIUM] 💎 Envoyé : $url", 'success');
            } else {
                iic_check_log("[AUTO-PREMIUM] Erreur", 'error');
            }
        }
    }
}

// --- AJAX HANDLERS ---

add_action('wp_ajax_iic_check_fetch_urls', function () {
    if (!current_user_can('manage_options'))
        wp_die();

    // Unclosed ob_start issue fixed - using it just to catch unexpected output, then clean
    ob_start();
    check_ajax_referer('iic_check_security_token', 'nonce');

    $filter = isset($_GET['filter']) ? sanitize_key(wp_unslash($_GET['filter'])) : '30days';

    if (get_option('iic_check_saas_status') !== 'premium') {
        if ($filter == '90days' || $filter == 'all')
            $filter = '30days';
    }

    $paged = isset($_GET['paged']) ? intval($_GET['paged']) : 1;
    $limit = isset($_GET['limit']) ? intval($_GET['limit']) : 20;

    $args = [
        'post_type' => ['page', 'post'],
        'post_status' => 'publish',
        'posts_per_page' => $limit,
        'paged' => $paged,
        'orderby' => 'modified',
        'order' => 'DESC'
    ];

    if ($filter !== 'all') {
        $map = ['7days' => '7 days ago', '30days' => '30 days ago', '90days' => '90 days ago'];
        if (isset($map[$filter]))
            $args['date_query'] = [['column' => 'post_modified_gmt', 'after' => $map[$filter]]];
    }

    $data = [];
    $q = new WP_Query($args);
    if ($q->have_posts()) {
        while ($q->have_posts()) {
            $q->the_post();
            $post_id = get_the_ID();
            $status = get_post_meta($post_id, '_sip_index_status', true);
            if (empty($status)) {
                $status = 'unknown';
            }
            $data[] = [
                'id' => $post_id,
                'title' => get_the_title(),
                'url' => get_permalink(),
                'date' => get_the_modified_date('d/m/Y'),
                'saved_status' => $status
            ];
        }
    }
    wp_reset_postdata();

    // Clean any accidental output before sending JSON
    ob_end_clean();

    iic_check_send_json([
        'items' => $data,
        'total' => $q->found_posts,
        'pages' => $q->max_num_pages,
        'current_page' => $paged
    ]);
});

add_action('wp_ajax_iic_check_activate_license', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    check_ajax_referer('iic_check_security_token', 'nonce');

    // Sanitization added
    $key = isset($_POST['key']) ? sanitize_text_field(wp_unslash($_POST['key'])) : '';
    $site_url = get_site_url();

    $r = wp_remote_post(IIC_CHECK_API_URL, ['body' => ['license_key' => $key, 'site_url' => $site_url]]);

    if (is_wp_error($r)) {
        iic_check_send_json(['msg' => 'Erreur API'], false);
        return;
    }

    $b = json_decode(wp_remote_retrieve_body($r), true);

    if ($b['status'] === 'active') {
        update_option('iic_check_saas_license_key', $key);
        // Use server-side premium status instead of key prefix
        $isPrem = !empty($b['is_premium']);
        
        if ($isPrem) {
            update_option('iic_check_saas_status', 'premium');
            update_option('iic_check_auto_index_enabled', true);
        } else {
            // User has a valid key but is not premium (e.g. CRED- key with credits only)
            $hasCredits = isset($b['credits']) && (int)$b['credits'] > 0;
            update_option('iic_check_saas_status', $hasCredits ? 'credits_only' : 'free');
        }

        // Sauvegarde des crédits récupérés
        if (isset($b['credits'])) {
            update_option('iic_check_user_credits', $b['credits']);
        }

        iic_check_send_json([
            'status' => $isPrem ? 'premium' : (isset($b['credits']) && (int)$b['credits'] > 0 ? 'credits_only' : 'free'),
            'credits' => isset($b['credits']) ? (int)$b['credits'] : 0
        ]);

    } elseif ($b['status'] === 'expired') {
        update_option('iic_check_saas_status', 'free');
        iic_check_send_json(['msg' => $b['message']], false);
    } else {
        iic_check_send_json(['msg' => 'Clé invalide'], false);
    }
});

add_action('wp_ajax_iic_check_go_free', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    update_option('iic_check_saas_status', 'free');
    wp_remote_post(IIC_CHECK_API_URL, [
        'body' => ['license_key' => 'FREE_TRACKING', 'site_url' => get_site_url()],
        'timeout' => 5,
        'blocking' => true
    ]);
    iic_check_send_json('OK');
});

add_action('wp_ajax_iic_check_request_indexing', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    ob_start();
    check_ajax_referer('iic_check_security_token', 'nonce');
    try {
        $client = new Google_Client();
        $client->setAuthConfig(get_option('iic_check_google_json_key'));
        $client->addScope('https://www.googleapis.com/auth/indexing');
        $service = new Google_Service_Indexing($client);
        if (!isset($_POST['url'])) {
            throw new Exception('Missing URL');
        }
        $url = esc_url_raw(wp_unslash($_POST['url']));

        $body = new Google_Service_Indexing_UrlNotification();
        $body->setUrl($url);
        $body->setType('URL_UPDATED');
        $service->urlNotifications->publish($body);

        $post_id = url_to_postid($url);
        if ($post_id) {
            update_post_meta($post_id, '_sip_index_status', 'waiting');
        }

        iic_check_log("Google Standard : {$url}", 'success');
        ob_end_clean();
        iic_check_send_json('OK');
    } catch (Exception $e) {
        ob_end_clean();
        $msg = $e->getMessage();
        iic_check_log("Google Std Error: " . $msg, 'error');
        iic_check_send_json(['msg' => $msg], false);
    }
});

add_action('wp_ajax_iic_check_premium_force', function () {
    if (!current_user_can('manage_options'))
        wp_die();

    // Fix output buffering
    ob_start();

    check_ajax_referer('iic_check_security_token', 'nonce');

    if (get_option('iic_check_saas_status') !== 'premium') {
        ob_end_clean();
        iic_check_send_json(['msg' => 'Premium Requis'], false);
        return;
    }

    if (!isset($_POST['url'])) {
        ob_end_clean();
        iic_check_send_json(['msg' => 'URL manquante'], false);
        return;
    }
    $url = esc_url_raw(wp_unslash($_POST['url']));
    $res = iic_check_call_premium_relay($url);

    // Clean buffer
    ob_end_clean();

    if (isset($res['status']) && $res['status'] === 'ok') {
        iic_check_add_history($url);

        // Mise à jour locale des crédits
        if (isset($res['new_credits'])) {
            update_option('iic_check_user_credits', $res['new_credits']);
        }

        $post_id = url_to_postid($url);
        if ($post_id) {
            update_post_meta($post_id, '_sip_index_status', 'waiting');
        }

        iic_check_log("💎 Premium Force : " . $url, 'success');
        // On renvoie les nouveaux crédits au JS
        iic_check_send_json(['status' => 'ok', 'new_credits' => $res['new_credits'] ?? null]);
    } else {
        $msg = $res['message'] ?? 'Erreur Inconnue';
        iic_check_log("Erreur Premium : " . $msg, 'error');
        iic_check_send_json(['msg' => $msg], false);
    }
});

add_action('wp_ajax_iic_check_save_auto_mode', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    check_ajax_referer('iic_check_security_token', 'nonce');
    if (get_option('iic_check_saas_status') !== 'premium') {
        iic_check_send_json(['msg' => 'Premium Only'], false);
        return;
    }
    $mode = isset($_POST['mode']) ? sanitize_text_field(wp_unslash($_POST['mode'])) : 'disabled';
    update_option('iic_check_auto_index_mode', $mode);
    iic_check_send_json('OK');
});

add_action('wp_ajax_iic_check_save_sys_config', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    check_ajax_referer('iic_check_security_token', 'nonce');
    $locale = isset($_POST['locale']) ? sanitize_text_field(wp_unslash($_POST['locale'])) : 'en_US';
    update_option('iic_check_locale', $locale);
    iic_check_send_json('OK');
});

add_action('wp_ajax_iic_check_save_key', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    check_ajax_referer('iic_check_security_token', 'nonce');
    $raw = isset($_POST['json_key']) ? wp_unslash($_POST['json_key']) : '';
    if (!empty(trim($raw))) {
        $dec = json_decode($raw, true);

        // Strict Validation & Sanitization against Google Service Account structure
        // Reviewer Note: We validate structure and sanitize individual fields instead of trusting raw json_decode
        if (is_array($dec) && isset($dec['type'], $dec['project_id'], $dec['private_key'], $dec['client_email'])) {
            $clean_key = [
                'type' => sanitize_text_field($dec['type']),
                'project_id' => sanitize_text_field($dec['project_id']),
                'private_key_id' => isset($dec['private_key_id']) ? sanitize_text_field($dec['private_key_id']) : '',
                'private_key' => $dec['private_key'], // Keep raw for RSA internal newlines (required for openssl)
                'client_email' => sanitize_email($dec['client_email']),
                'client_id' => isset($dec['client_id']) ? sanitize_text_field($dec['client_id']) : '',
                'auth_uri' => isset($dec['auth_uri']) ? esc_url_raw($dec['auth_uri']) : '',
                'token_uri' => isset($dec['token_uri']) ? esc_url_raw($dec['token_uri']) : '',
                'auth_provider_x509_cert_url' => isset($dec['auth_provider_x509_cert_url']) ? esc_url_raw($dec['auth_provider_x509_cert_url']) : '',
                'client_x509_cert_url' => isset($dec['client_x509_cert_url']) ? esc_url_raw($dec['client_x509_cert_url']) : ''
            ];
            update_option('iic_check_google_json_key', $clean_key);
        } else {
            iic_check_send_json(['msg' => 'Invalid JSON Structure (Missing Service Account fields)'], false);
            return;
        }
    }
    $gsc_url = isset($_POST['gsc_url']) ? esc_url_raw(wp_unslash($_POST['gsc_url'])) : '';
    update_option('iic_check_gsc_site_url', $gsc_url);
    iic_check_send_json('OK');
});

add_action('wp_ajax_iic_check_check_url', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    ob_start();
    check_ajax_referer('iic_check_security_token', 'nonce');
    try {
        if (!isset($_POST['url']))
            throw new Exception('URL Manquante');
        $url = esc_url_raw(wp_unslash($_POST['url']));

        $client = new Google_Client();
        $client->setAuthConfig(get_option('iic_check_google_json_key'));
        $client->addScope('https://www.googleapis.com/auth/webmasters.readonly');
        $service = new Google_Service_SearchConsole($client);
        $req = new Google_Service_SearchConsole_InspectUrlIndexRequest();
        $req->setInspectionUrl($url);
        $req->setSiteUrl(get_option('iic_check_gsc_site_url'));
        $res = $service->urlInspection_index->inspect($req);
        $v = $res->inspectionResult->indexStatusResult->verdict;

        ob_end_clean();

        $post_id = url_to_postid($url);

        if (is_null($v)) {
            if ($post_id)
                update_post_meta($post_id, '_sip_index_status', 'not_indexed');
            iic_check_send_json(['status' => 'not_indexed', 'msg' => 'Non Indexée (Null Verdict)']);
        } elseif ($v === 'PASS') {
            if ($post_id)
                update_post_meta($post_id, '_sip_index_status', 'indexed');
            iic_check_send_json(['status' => 'indexed']);
        } else {
            if ($post_id)
                update_post_meta($post_id, '_sip_index_status', 'not_indexed');
            iic_check_send_json(['status' => 'not_indexed', 'msg' => 'Non Indexée']);
        }
    } catch (Exception $e) {
        ob_end_clean();
        $msg = $e->getMessage();
        iic_check_log("Check Status Error: " . $msg, 'error');
        iic_check_send_json(['status' => 'error', 'msg' => $msg], false);
    }
});

add_action('wp_ajax_iic_check_logout', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    delete_option('iic_check_saas_status');
    delete_option('iic_check_saas_license_key');
    delete_option('iic_check_user_credits');
    iic_check_send_json('OK');
});

add_action('wp_ajax_iic_check_get_credits', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    check_ajax_referer('iic_check_security_token', 'nonce');
    
    $credits = get_option('iic_check_user_credits', 0);
    $status = get_option('iic_check_saas_status', false);
    
    iic_check_send_json([
        'credits' => (int) $credits,
        'status' => $status
    ]);
});

add_action('wp_ajax_iic_check_debug_api', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    iic_check_send_json(['logs' => ['✅ Test OK']]);
});

function iic_check_log($msg, $type)
{
    $l = get_option('iic_check_logs', []);
    if (!is_array($l))
        $l = [];
    array_unshift($l, ['date' => gmdate('d/m H:i'), 'msg' => $msg, 'type' => $type]);
    if (count($l) > 50)
        array_pop($l);
    update_option('iic_check_logs', $l);
}

add_action('wp_ajax_iic_check_get_logs', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    ob_start();
    $logs = get_option('iic_check_logs', []);
    if (!is_array($logs))
        $logs = [];
    ob_end_clean();
    iic_check_send_json($logs);
});
add_action('wp_ajax_iic_check_clear_logs', function () {
    if (!current_user_can('manage_options'))
        wp_die();
    update_option('iic_check_logs', []);
    iic_check_send_json('OK');
});