<?php
/**
 * WordChat Pro Plugin Updater
 *
 * Handles automatic updates for Pro customers with license verification
 *
 * Features:
 * - Check for updates from WordChat backend
 * - Verify license before downloading
 * - Display update notices in WordPress admin
 * - Handle background updates
 * - Track update success/failure
 *
 * @package WordChat
 * @subpackage Pro
 * @since 0.1.27
 */

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

class WordChat_Pro_Updater {

    /**
     * Plugin slug
     */
    private $plugin_slug;

    /**
     * Plugin file path
     */
    private $plugin_file;

    /**
     * Current plugin version
     */
    private $version;

    /**
     * License key
     */
    private $license_key;

    /**
     * API endpoint for update checks
     */
    private $api_url;

    /**
     * Site ID
     */
    private $site_id;

    /**
     * Cache key for transients
     */
    private $cache_key;

    /**
     * Cache duration (12 hours)
     */
    private $cache_duration = 43200;

    /**
     * Constructor
     *
     * @param string $plugin_file Plugin file path
     * @param string $version Current plugin version
     * @param string $api_url Backend API URL
     */
    public function __construct($plugin_file, $version, $api_url) {
        $this->plugin_file = $plugin_file;
        $this->plugin_slug = plugin_basename($plugin_file);
        $this->version = $version;
        $this->api_url = rtrim($api_url, '/');
        $this->cache_key = 'wordchat_update_' . md5($this->plugin_slug);

        // Get license and site ID from options
        $this->license_key = get_option('wordchat_license_key');
        $this->site_id = get_option('wordchat_site_id');

        // Hook into WordPress update system
        $this->init_hooks();
    }

    /**
     * Initialize WordPress hooks
     */
    private function init_hooks() {
        // Check for updates
        add_filter('pre_set_site_transient_update_plugins', array($this, 'check_for_updates'));

        // Provide plugin info for update details
        add_filter('plugins_api', array($this, 'plugin_info'), 10, 3);

        // After update, clear cache and log success
        add_action('upgrader_process_complete', array($this, 'after_update'), 10, 2);

        // Add license activation notices
        add_action('admin_notices', array($this, 'license_notices'));

        // Add manual update check button
        add_filter('plugin_row_meta', array($this, 'add_check_update_link'), 10, 2);

        // Handle manual update check
        add_action('admin_init', array($this, 'handle_manual_check'));
    }

    /**
     * Check for plugin updates
     *
     * Called by WordPress update system periodically
     *
     * @param object $transient Update transient
     * @return object Modified transient
     */
    public function check_for_updates($transient) {
        if (empty($transient->checked)) {
            return $transient;
        }

        // Check if license is active
        if (!$this->license_key || !$this->site_id) {
            // No license - skip update check
            return $transient;
        }

        // Get cached update info
        $update_info = get_transient($this->cache_key);

        // If no cache or manual check requested, fetch from API
        if ($update_info === false || isset($_GET['wordchat_check_update'])) {
            $update_info = $this->fetch_update_info();

            if ($update_info) {
                // Cache for 12 hours
                set_transient($this->cache_key, $update_info, $this->cache_duration);
            }
        }

        // Add update to transient if available
        if ($update_info && isset($update_info->update_available) && $update_info->update_available) {
            $transient->response[$this->plugin_slug] = $update_info;
        } else {
            // No update available - add to no_update to prevent WordPress.org check
            $transient->no_update[$this->plugin_slug] = (object) array(
                'id'            => $this->plugin_slug,
                'slug'          => dirname($this->plugin_slug),
                'plugin'        => $this->plugin_slug,
                'new_version'   => $this->version,
                'url'           => '',
                'package'       => '',
                'icons'         => array(),
                'banners'       => array(),
                'banners_rtl'   => array(),
                'tested'        => ''
            );
        }

        return $transient;
    }

    /**
     * Fetch update information from backend API
     *
     * @return object|false Update info object or false on failure
     */
    private function fetch_update_info() {
        $response = wp_remote_post($this->api_url . '/updates/check', array(
            'headers' => array('Content-Type' => 'application/json'),
            'body' => json_encode(array(
                'license_key'     => $this->license_key,
                'site_id'         => $this->site_id,
                'current_version' => $this->version,
                'domain'          => get_site_url(),
                'plugin_version'  => $this->version,
                'plugin_slug'     => WORDCHAT_PLUGIN_SLUG,
                'wp_version'      => get_bloginfo('version'),
                'php_version'     => PHP_VERSION
            )),
            'timeout' => 15
        ));

        if (is_wp_error($response)) {
            error_log('WordChat update check failed: ' . $response->get_error_message());
            return false;
        }

        $code = wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);

        if ($code !== 200) {
            error_log('WordChat update check returned ' . $code . ': ' . $body);

            // If license is invalid, show notice
            if ($code === 403) {
                set_transient('wordchat_license_invalid', true, DAY_IN_SECONDS);
            }

            return false;
        }

        $data = json_decode($body, true);

        if (!$data || !isset($data['authorized'])) {
            error_log('WordChat update check: Invalid response format');
            return false;
        }

        if (!$data['authorized']) {
            error_log('WordChat update check: Not authorized - ' . ($data['error'] ?? 'unknown'));
            set_transient('wordchat_license_invalid', true, DAY_IN_SECONDS);
            return false;
        }

        // License is valid - clear any invalid notices
        delete_transient('wordchat_license_invalid');

        if (!$data['update_available']) {
            // No update available
            return (object) array(
                'update_available' => false,
                'current_version' => $this->version
            );
        }

        // Build update object for WordPress
        return (object) array(
            'id'            => $this->plugin_slug,
            'slug'          => dirname($this->plugin_slug),
            'plugin'        => $this->plugin_slug,
            'new_version'   => $data['latest_version'],
            'url'           => 'https://www.word.chat/',
            'package'       => $data['download_url'], // Signed URL from backend
            'icons'         => array(),
            'banners'       => array(),
            'banners_rtl'   => array(),
            'tested'        => $data['requires_wp_version'],
            'requires_php'  => $data['requires_php_version'],
            'update_available' => true,
            'changelog'     => $data['changelog']
        );
    }

    /**
     * Provide plugin information for update details modal
     *
     * @param false|object|array $result The result object or array
     * @param string $action The type of information being requested
     * @param object $args Plugin API arguments
     * @return false|object Modified result
     */
    public function plugin_info($result, $action, $args) {
        if ($action !== 'plugin_information') {
            return $result;
        }

        if (!isset($args->slug) || $args->slug !== dirname($this->plugin_slug)) {
            return $result;
        }

        // Get update info
        $update_info = get_transient($this->cache_key);

        if (!$update_info) {
            $update_info = $this->fetch_update_info();
        }

        if (!$update_info || !$update_info->update_available) {
            return $result;
        }

        // Build plugin info object
        return (object) array(
            'name'          => 'WordChat Pro',
            'slug'          => dirname($this->plugin_slug),
            'version'       => $update_info->new_version,
            'author'        => '<a href="https://www.word.chat/">Word.Chat</a>',
            'homepage'      => 'https://www.word.chat/',
            'requires'      => $update_info->tested,
            'requires_php'  => $update_info->requires_php,
            'tested'        => $update_info->tested,
            'downloaded'    => 0,
            'last_updated'  => date('Y-m-d'),
            'sections'      => array(
                'description' => 'WordChat Pro - AI-powered chatbot for WordPress with unlimited content and messages.',
                'changelog'   => $update_info->changelog ?? 'No changelog available.'
            ),
            'download_link' => $update_info->package
        );
    }

    /**
     * After update complete - log success and submit telemetry
     *
     * @param object $upgrader_object Plugin upgrader object
     * @param array $options Update options
     */
    public function after_update($upgrader_object, $options) {
        if ($options['action'] !== 'update' || $options['type'] !== 'plugin') {
            return;
        }

        if (!isset($options['plugins']) || !is_array($options['plugins'])) {
            return;
        }

        foreach ($options['plugins'] as $plugin) {
            if ($plugin === $this->plugin_slug) {
                // Clear update cache
                delete_transient($this->cache_key);

                // Get new version
                if (!function_exists('get_plugin_data')) {
                    require_once ABSPATH . 'wp-admin/includes/plugin.php';
                }
                $plugin_data = get_plugin_data(WP_PLUGIN_DIR . '/' . $this->plugin_slug);
                $new_version = $plugin_data['Version'];

                // Log success
                error_log("WordChat updated successfully from {$this->version} to {$new_version}");

                // Submit telemetry
                $this->submit_telemetry('update_success', $new_version);

                // Update version in options
                update_option('wordchat_current_version', $new_version);

                break;
            }
        }
    }

    /**
     * Submit telemetry data to backend
     *
     * @param string $event Event type (update_success, update_failure, etc.)
     * @param string $new_version New version (if applicable)
     */
    private function submit_telemetry($event, $new_version = null) {
        if (!$this->license_key || !$this->site_id) {
            return;
        }

        // Get site stats
        $post_count = wp_count_posts('post');
        $page_count = wp_count_posts('page');

        $telemetry_data = array(
            'license_key'             => $this->license_key,
            'site_id'                 => $this->site_id,
            'domain'                  => get_site_url(),
            'plugin_version'          => $new_version ?? $this->version,
            'wp_version'              => get_bloginfo('version'),
            'php_version'             => PHP_VERSION,
            'active_plugins'          => count(get_option('active_plugins', array())),
            'total_posts'             => $post_count->publish ?? 0,
            'total_pages'             => $page_count->publish ?? 0,
            'wordchat_messages_count' => (int) get_option('wordchat_total_messages', 0),
            'wordchat_content_count'  => (int) get_option('wordchat_total_content', 0),
            'metadata'                => array(
                'event' => $event,
                'previous_version' => $this->version,
                'new_version' => $new_version
            )
        );

        // Send async (non-blocking)
        wp_remote_post($this->api_url . '/telemetry/submit', array(
            'blocking' => false,
            'headers'  => array('Content-Type' => 'application/json'),
            'body'     => json_encode($telemetry_data),
            'timeout'  => 5
        ));
    }

    /**
     * Display license-related admin notices
     */
    public function license_notices() {
        // Invalid license notice
        if (get_transient('wordchat_license_invalid')) {
            ?>
            <div class="notice notice-error is-dismissible">
                <p>
                    <strong>WordChat Pro:</strong>
                    Your license key is invalid or has expired.
                    <a href="<?php echo admin_url('admin.php?page=wordchat-pro'); ?>">Update your license</a>
                    to continue receiving updates.
                </p>
            </div>
            <?php
        }

        // No license key entered
        if (!$this->license_key && get_option('wordchat_is_paid') === '1') {
            ?>
            <div class="notice notice-warning is-dismissible">
                <p>
                    <strong>WordChat Pro:</strong>
                    Please enter your license key in
                    <a href="<?php echo admin_url('admin.php?page=wordchat-pro'); ?>">plugin settings</a>
                    to enable automatic updates.
                </p>
            </div>
            <?php
        }

        // Update successful notice
        if (isset($_GET['wordchat_updated']) && $_GET['wordchat_updated'] === '1') {
            ?>
            <div class="notice notice-success is-dismissible">
                <p>
                    <strong>WordChat Pro</strong> has been updated successfully!
                </p>
            </div>
            <?php
        }
    }

    /**
     * Add "Check for Updates" link to plugin row
     *
     * @param array $links Plugin row meta links
     * @param string $file Plugin file
     * @return array Modified links
     */
    public function add_check_update_link($links, $file) {
        if ($file !== $this->plugin_slug) {
            return $links;
        }

        if ($this->license_key) {
            $check_url = add_query_arg(array(
                'wordchat_check_update' => '1',
                '_wpnonce' => wp_create_nonce('wordchat_check_update')
            ), admin_url('plugins.php'));

            $links[] = '<a href="' . esc_url($check_url) . '">Check for Updates</a>';
        }

        return $links;
    }

    /**
     * Handle manual update check request
     */
    public function handle_manual_check() {
        if (!isset($_GET['wordchat_check_update'])) {
            return;
        }

        // Verify nonce
        if (!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'wordchat_check_update')) {
            return;
        }

        // Clear cache to force fresh check
        delete_transient($this->cache_key);

        // Redirect back to plugins page
        wp_redirect(admin_url('plugins.php'));
        exit;
    }

    /**
     * Send daily telemetry check-in (called by cron)
     */
    public function daily_checkin() {
        $this->submit_telemetry('daily_checkin');
    }
}
