<?php
/**
 * Self-hosted plugin updater for WordPress
 */
namespace BWDK\Support;

use stdClass;

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

class BWDK_Updater {

    private $plugin_file;
    private $slug;
    private $current_version;
    private $metadata_url;

    public function __construct($args) {
        $this->plugin_file     = $args['plugin_file'];
        $this->slug            = dirname($this->plugin_file);
        $this->current_version = $args['current_version'];
        $this->metadata_url    = $args['metadata_url'];

        // Hook into update system
        add_filter('pre_set_site_transient_update_plugins', [$this, 'check_for_update']);
        add_filter('plugins_api',                           [$this, 'plugins_api'], 10, 3);
        add_filter('site_transient_update_plugins',         [$this, 'fix_forced_check']);

        add_filter('plugin_action_links_' . $this->plugin_file, [$this, 'action_links']);

        add_action('admin_init', [$this, 'maybe_force_check']);
    }

    /** Fetch remote JSON safely */
    private function get_remote_metadata() {
        $resp = wp_remote_get($this->metadata_url, [
            'timeout' => 10,
            'headers' => [
                'Accept' => 'application/json',
            ],
        ]);

        if (is_wp_error($resp)) return false;

        $code = wp_remote_retrieve_response_code($resp);
        if ($code !== 200) return false;

        $body = wp_remote_retrieve_body($resp);
        $data = json_decode($body, true);
        if (!is_array($data)) return false;

        // Expected keys: name, version, download_url, requires, tested, homepage, description, changelog
        $required_keys = ['name','version','download_url'];
        foreach ($required_keys as $k) {
            if (!isset($data[$k]) || empty($data[$k])) return false;
        }

        return $data;
    }

    /** Tell WP when an update is available */
    public function check_for_update($transient) {
        if (empty($transient) || !is_object($transient)) {
            $transient = new stdClass();
        }

        // If we're mid-check and have data already, proceed
        $meta = $this->get_remote_metadata();
        if (!$meta) return $transient;

        $remote_version = $meta['version'];

        // compare versions
        if (version_compare($this->current_version, $remote_version, '<')) {
            $obj = new stdClass();
            $obj->slug        = $this->slug;
            $obj->plugin      = $this->plugin_file;
            $obj->new_version = $remote_version;
            $obj->url         = !empty($meta['homepage']) ? $meta['homepage'] : '';
            $obj->package     = $meta['download_url']; // ZIP file URL

            // Nice-to-haves
            if (!empty($meta['tested']))   $obj->tested   = $meta['tested'];
            if (!empty($meta['requires'])) $obj->requires = $meta['requires'];
            if (!empty($meta['banners']) && is_array($meta['banners'])) $obj->banners = $meta['banners'];

            $transient->response[$this->plugin_file] = $obj;
        } else {
            // Up to date
            $obj = new stdClass();
            $obj->slug        = $this->slug;
            $obj->plugin      = $this->plugin_file;
            $obj->new_version = $remote_version;
            $obj->url         = !empty($meta['homepage']) ? $meta['homepage'] : '';
            $obj->package     = ''; // no package offered if already the latest
            $transient->no_update[$this->plugin_file] = $obj;
        }

        return $transient;
    }

    /** Provide details in the modal (View details) */
    public function plugins_api($false, $action, $args) {
        if ($action !== 'plugin_information') return $false;
        if (empty($args->slug) || $args->slug !== $this->slug) return $false;

        $meta = $this->get_remote_metadata();
        if (!$meta) return $false;

        $res = new stdClass();
        $res->name          = $meta['name'];
        $res->slug          = $this->slug;
        $res->version       = $meta['version'];
        $res->author        = !empty($meta['author']) ? $meta['author'] : '';
        $res->author_profile= !empty($meta['author_profile']) ? $meta['author_profile'] : '';
        $res->homepage      = !empty($meta['homepage']) ? $meta['homepage'] : '';
        $res->requires      = !empty($meta['requires']) ? $meta['requires'] : '';
        $res->tested        = !empty($meta['tested']) ? $meta['tested'] : '';
        $res->last_updated  = !empty($meta['last_updated']) ? $meta['last_updated'] : '';
        $res->download_link = $meta['download_url'];

        // sections: description/changelog/installation
        $res->sections = [
            'description' => !empty($meta['description']) ? $meta['description'] : '',
            'changelog'   => !empty($meta['changelog']) ? $meta['changelog'] : '',
        ];

        // icons/banners (optional)
        if (!empty($meta['icons']) && is_array($meta['icons']))     $res->icons   = $meta['icons'];
        if (!empty($meta['banners']) && is_array($meta['banners'])) $res->banners = $meta['banners'];

        return $res;
    }

    /** Let manual checks repopulate properly after clearing */
    public function fix_forced_check($transient) {
        return $transient;
    }

    /** Little helper link to force check */
    public function action_links($links) {
        $url = wp_nonce_url(add_query_arg([
            'bwdk_force_update_check' => 1,
            'plugin' => $this->plugin_file,
        ], admin_url('plugins.php')), 'bwdk_force_update_check');

        array_unshift($links, '<a href="' . esc_url($url) . '">' . esc_html__('Check for updates', 'bwdk') . '</a>');
        return $links;
    }

    /** Handle manual "Check for updates" */
    public function maybe_force_check() {
        if (empty($_GET['bwdk_force_update_check'])) return;
        if (!current_user_can('update_plugins')) return;
        if (!wp_verify_nonce($_GET['_wpnonce'] ?? '', 'bwdk_force_update_check')) return;

        // Clear transients and trigger a check
        delete_site_transient('update_plugins');
        wp_clean_plugins_cache(true);

        // redirect back to Plugins page to see result
        wp_safe_redirect(admin_url('plugins.php?bwdk_checked=1'));
        exit;
    }

    /** Show a short note under the plugin row when update exists */
    public function update_message($plugin_data, $response) {
        echo ' ' . esc_html__('تغییرات نسخه جدید:', 'bwdk') . ' ';
        $meta = $this->get_remote_metadata();
        if (!empty($meta['changelog'])) {
            // keep it short
            echo wp_kses_post($meta['changelog']);
        }
    }
}
