<?php
/**
 * MG_Updates — Notification de mise à jour (v2.9.131)
 *
 * Combo trois niveaux, du plus discret au plus visible :
 *  1. Badge header pulsant (dans le plugin) — clic = panneau changelog + Télécharger + Plus tard
 *  2. Compteur sur le menu latéral « Maintenance GENIUS ① »
 *  3. Notice dismissible sur le Tableau de bord uniquement
 *
 * Mécanique :
 *  - Vérification quotidienne silencieuse de l'endpoint version.json (transient 24 h,
 *    déclenchée au chargement de wp-admin — AUCUNE dépendance à WP-Cron, souvent désactivé)
 *  - Dismiss par version (site-wide) : tout s'éteint jusqu'à la release suivante
 *  - Extinction automatique si le plugin est géré par WordPress.org (les MAJ natives prennent le relais)
 *
 * @package Maintenance_GENIUS
 */

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

class MG_Updates {

    const ENDPOINT       = 'https://maintenancegenius.ca/api/version.json';
    const CHECK_TRANSIENT = 'mg_update_check';       // cache 24 h du dernier résultat
    const DISMISS_OPTION  = 'mg_update_dismissed';   // version dismissée (site-wide)

    public static function init() {
        if (!is_admin()) {
            return;
        }
        add_action('admin_init', [__CLASS__, 'maybe_check'], 30);
        add_action('admin_menu', [__CLASS__, 'menu_badge'], 999);
        add_action('admin_notices', [__CLASS__, 'dashboard_notice']);
        add_action('wp_ajax_mg_dismiss_update', [__CLASS__, 'ajax_dismiss']);
    }

    /**
     * Vérification quotidienne silencieuse (transient 24 h).
     * Ne bloque jamais l'admin : timeout court, échec = on réessaie dans 24 h.
     */
    public static function maybe_check() {
        if (!current_user_can('manage_options')) {
            return;
        }
        if (self::is_wporg_managed()) {
            return; // WordPress.org gère les MAJ — on ne vérifie même plus
        }
        if (get_transient(self::CHECK_TRANSIENT) !== false) {
            return; // déjà vérifié dans les dernières 24 h
        }

        // Verrou immédiat AVANT la requête : même en cas d'échec réseau,
        // on ne martèle pas l'endpoint à chaque chargement d'admin.
        set_transient(self::CHECK_TRANSIENT, ['checked_at' => time()], DAY_IN_SECONDS);

        $response = wp_remote_get(self::ENDPOINT, [
            'timeout'   => 5,
            'sslverify' => true,
        ]);
        if (is_wp_error($response)) {
            return;
        }

        $data = json_decode(wp_remote_retrieve_body($response), true);
        if (empty($data['version'])) {
            return;
        }

        set_transient(self::CHECK_TRANSIENT, [
            'checked_at'   => time(),
            'version'      => sanitize_text_field($data['version']),
            'changelog'    => sanitize_textarea_field($data['changelog'] ?? ''),
            'download_url' => esc_url_raw($data['download_url'] ?? 'https://maintenancegenius.ca/telechargements/'),
            'date'         => sanitize_text_field($data['date'] ?? ''),
        ], DAY_IN_SECONDS);
    }

    /**
     * Infos de MAJ disponible, ou null (à jour / dismissée / gérée par WP.org).
     *
     * @return array|null {version, changelog, download_url, date}
     */
    public static function get_available_update() {
        if (self::is_wporg_managed()) {
            return null;
        }
        $check = get_transient(self::CHECK_TRANSIENT);
        if (empty($check['version'])) {
            return null;
        }
        if (!version_compare($check['version'], MG_VERSION, '>')) {
            return null;
        }
        if (get_option(self::DISMISS_OPTION) === $check['version']) {
            return null;
        }
        return $check;
    }

    /**
     * Le plugin est-il géré par WordPress.org ?
     * Après acceptation sur WP.org, l'API officielle référence le slug dans le
     * transient update_plugins (response OU no_update) : les MAJ natives prennent
     * le relais et nos notifications maison s'éteignent d'elles-mêmes.
     */
    public static function is_wporg_managed() {
        $basename = plugin_basename(MG_PLUGIN_FILE);
        $updates  = get_site_transient('update_plugins');
        if (!is_object($updates)) {
            return false;
        }
        if (!empty($updates->response) && isset($updates->response[$basename])) {
            return true;
        }
        if (!empty($updates->no_update) && isset($updates->no_update[$basename])) {
            return true;
        }
        return false;
    }

    /**
     * Niveau 2 — Compteur sur le menu latéral (langage natif WP, comme Extensions ②).
     */
    public static function menu_badge() {
        $update = self::get_available_update();
        if (!$update) {
            return;
        }
        global $menu;
        if (!is_array($menu)) {
            return;
        }
        foreach ($menu as $i => $item) {
            if (isset($item[2]) && $item[2] === 'maintenance-genius') {
                $menu[$i][0] .= ' <span class="update-plugins count-1"><span class="plugin-count">1</span></span>';
                break;
            }
        }
    }

    /**
     * Niveau 3 — Notice dismissible, Tableau de bord UNIQUEMENT (zéro harcèlement).
     */
    public static function dashboard_notice() {
        $screen = function_exists('get_current_screen') ? get_current_screen() : null;
        if (!$screen || $screen->id !== 'dashboard') {
            return;
        }
        $update = self::get_available_update();
        if (!$update || !current_user_can('manage_options')) {
            return;
        }
        $nonce = wp_create_nonce('mg_nonce');
        ?>
        <div class="notice notice-info is-dismissible" id="mg-update-notice" data-version="<?php echo esc_attr($update['version']); ?>" data-nonce="<?php echo esc_attr($nonce); ?>" style="border-left-color:#F97316;">
            <p>
                <strong>🔧 Maintenance GENIUS</strong> —
                <?php
                printf(
                    /* translators: 1: new version number, 2: current version number */
                    esc_html__('Version %1$s available (you have %2$s).', 'maintenance-genius'),
                    esc_html($update['version']),
                    esc_html(MG_VERSION)
                );
                ?>
                <a href="<?php echo esc_url($update['download_url']); ?>" target="_blank" rel="noopener"><?php esc_html_e('Download the update', 'maintenance-genius'); ?></a>
                &middot;
                <a href="<?php echo esc_url(admin_url('admin.php?page=maintenance-genius')); ?>"><?php esc_html_e('See what\'s new', 'maintenance-genius'); ?></a>
            </p>
        </div>
        <script>
        jQuery(function($){
            $(document).on('click', '#mg-update-notice .notice-dismiss', function(){
                var $n = $('#mg-update-notice');
                $.post(ajaxurl, {
                    action: 'mg_dismiss_update',
                    nonce: $n.data('nonce'),
                    version: $n.data('version')
                });
            });
        });
        </script>
        <?php
    }

    /**
     * AJAX — dismiss par version (site-wide). Le badge, le compteur et la notice
     * s'éteignent ensemble jusqu'à la prochaine release.
     */
    public static function ajax_dismiss() {
        check_ajax_referer('mg_nonce', 'nonce');
        if (!current_user_can('manage_options')) {
            wp_send_json_error(['message' => 'Permission denied']);
        }
        $version = isset($_POST['version']) ? sanitize_text_field(wp_unslash($_POST['version'])) : '';
        if ($version) {
            update_option(self::DISMISS_OPTION, $version, false);
        }
        wp_send_json_success();
    }
}
