<?php
/**
 * Self-hosted plugin updater for WordPress
 * 
 * This updater expects:
 * - Plugin folder name: buy-with-digikala/ (NO version in folder name)
 * - ZIP filename on server: buy-with-digikala-{version}.zip (WITH version)
 * - Plugin slug: buy-with-digikala/buy-with-digikala.php
 * - Metadata URL: https://plugins.digifyprime.net/bwdk/metadata.json
 */
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) {
        // Plugin file must be: buy-with-digikala/buy-with-digikala.php
        $this->plugin_file     = $args['plugin_file'];
        
        // Slug is the directory name: buy-with-digikala
        $this->slug            = dirname($this->plugin_file);
        
        // Ensure slug is correct (should be 'buy-with-digikala')
        if ($this->slug !== 'buy-with-digikala') {
            // Fallback: extract from plugin_file if it contains the path
            if (strpos($this->plugin_file, 'buy-with-digikala') !== false) {
                $parts = explode('/', $this->plugin_file);
                if (!empty($parts[0])) {
                    $this->slug = $parts[0];
                }
            }
        }
        
        $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'], 10, 1);
        add_filter('plugins_api',                           [$this, 'plugins_api'], 10, 3);
        add_filter('site_transient_update_plugins',         [$this, 'fix_forced_check'], 10, 1);

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

        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;
        }

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

        // Normalize sections structure: support both old format (description/changelog at root)
        // and new format (sections.description, sections.changelog)
        if (isset($data['sections']) && is_array($data['sections'])) {
            // New format: sections.description and sections.changelog
            if (isset($data['sections']['description']) && !isset($data['description'])) {
                $data['description'] = $data['sections']['description'];
            }
            if (isset($data['sections']['changelog']) && !isset($data['changelog'])) {
                $data['changelog'] = $data['sections']['changelog'];
            }
        }

        return $data;
    }

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

        // Ensure response and no_update arrays exist
        if (!isset($transient->response)) {
            $transient->response = [];
        }
        if (!isset($transient->no_update)) {
            $transient->no_update = [];
        }

        // Fetch remote metadata
        $meta = $this->get_remote_metadata();
        if (!$meta) {
            return $transient;
        }

        $remote_version = $meta['version'];
        if (empty($remote_version)) {
            return $transient;
        }

        // Compare versions
        if (version_compare($this->current_version, $remote_version, '<')) {
            // Update available
            $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

            // Additional metadata
            if (!empty($meta['tested'])) {
                $obj->tested = $meta['tested'];
            }
            if (!empty($meta['requires'])) {
                $obj->requires = $meta['requires'];
            }
            if (!empty($meta['requires_php'])) {
                $obj->requires_php = $meta['requires_php'];
            }
            if (!empty($meta['banners']) && is_array($meta['banners'])) {
                $obj->banners = $meta['banners'];
            }

            $transient->response[$this->plugin_file] = $obj;
        } else {
            // Up to date - mark as no update needed
            if (isset($transient->response[$this->plugin_file])) {
                unset($transient->response[$this->plugin_file]);
            }
        }

        return $transient;
    }

    /** Provide details in the modal (View details) */
    public function plugins_api($false, $action, $args) {
        if ($action !== 'plugin_information') {
            return $false;
        }

        // Check if this is our plugin
        // WordPress typically passes the folder name as slug (e.g., "buy-with-digikala")
        $plugin_slug = $this->slug; // e.g., "buy-with-digikala"
        $plugin_file = $this->plugin_file; // e.g., "buy-with-digikala/buy-with-digikala.php"
        
        // Get metadata to check slug field
        $meta = $this->get_remote_metadata();
        if (!$meta) {
            return $false;
        }
        
        // Check slug from metadata.json if available
        $metadata_slug = !empty($meta['slug']) ? $meta['slug'] : '';
        
        // WordPress may pass slug as:
        // 1. Folder name: "buy-with-digikala"
        // 2. Full plugin file: "buy-with-digikala/buy-with-digikala.php" (less common)
        // 3. Metadata slug: from metadata.json "slug" field
        $is_our_plugin = false;
        if (!empty($args->slug)) {
            $requested_slug = $args->slug;
            if ($requested_slug === $plugin_slug || 
                $requested_slug === $plugin_file ||
                $requested_slug === 'buy-with-digikala' ||
                (!empty($metadata_slug) && $requested_slug === $metadata_slug) ||
                (!empty($metadata_slug) && $requested_slug === dirname($metadata_slug))) {
                $is_our_plugin = true;
            }
        }
        
        if (!$is_our_plugin) {
            return $false;
        }

        $res = new stdClass();
        $res->name          = !empty($meta['name']) ? $meta['name'] : 'Buy With Digikala';
        $res->slug          = $plugin_slug;
        $res->version       = !empty($meta['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->requires_php  = !empty($meta['requires_php']) ? $meta['requires_php'] : '';
        $res->last_updated  = !empty($meta['last_updated']) ? $meta['last_updated'] : '';
        $res->download_link = !empty($meta['download_url']) ? $meta['download_url'] : '';

        // Sections: description/changelog/installation
        // Support both formats: root level or nested in sections
        $description = '';
        $changelog = '';
        
        if (isset($meta['sections']) && is_array($meta['sections'])) {
            // New format: sections.description and sections.changelog
            $description = !empty($meta['sections']['description']) ? $meta['sections']['description'] : '';
            $changelog   = !empty($meta['sections']['changelog']) ? $meta['sections']['changelog'] : '';
        }
        
        // Fallback to root level if sections not found
        if (empty($description) && !empty($meta['description'])) {
            $description = $meta['description'];
        }
        if (empty($changelog) && !empty($meta['changelog'])) {
            $changelog = $meta['changelog'];
        }

        $res->sections = [
            'description' => $description,
            'changelog'   => $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) {
        // This filter allows us to ensure the transient is properly structured
        // when WordPress forces a check
        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']);
        }
    }
}
