<?php
if (!defined('ABSPATH')) {
    exit;
}

class BMTQB_Update_Manager {
    const HOST = 'https://plugins.bettermousetrap.ca';

    private $license_manager;
    private $plugins = [];

    public function __construct(BMTQB_License_Manager $license_manager) {
        $this->license_manager = $license_manager;

        $this->register([
            'slug' => 'better-mousetrap-quote-base',
            'name' => 'Better Mousetrap Quote Base',
            'plugin_file' => plugin_basename(BMTQB_FILE),
            'version' => BMTQB_VERSION,
            'manifest_url' => self::HOST . '/manifests/better-mousetrap-quote-base.json',
        ]);

        add_filter('pre_set_site_transient_update_plugins', [$this, 'filter_update_transient']);
        add_filter('plugins_api', [$this, 'filter_plugins_api'], 10, 3);
        add_action('upgrader_process_complete', [$this, 'clear_cache']);
    }

    public function register_industry(BMTQB_Industry_Interface $industry) {
        $slug = dirname(plugin_basename($industry->plugin_file()));

        $this->register([
            'slug' => $slug,
            'name' => $industry->label(),
            'plugin_file' => plugin_basename($industry->plugin_file()),
            'version' => $industry->version(),
            'manifest_url' => self::HOST . '/manifests/' . $slug . '.json',
        ]);
    }

    public function register(array $plugin) {
        if (empty($plugin['slug']) || empty($plugin['plugin_file'])) {
            return;
        }

        $this->plugins[$plugin['plugin_file']] = $plugin;
    }

    public function filter_update_transient($transient) {
        if (empty($transient) || !is_object($transient)) {
            return $transient;
        }

        if (!$this->license_manager->has_license_code()) {
            return $transient;
        }

        foreach ($this->plugins as $plugin_file => $plugin) {
            $manifest = $this->manifest($plugin);
            if (!$manifest || empty($manifest['version'])) {
                continue;
            }

            if (version_compare($manifest['version'], $plugin['version'], '<=')) {
                continue;
            }

            $transient->response[$plugin_file] = (object) [
                'slug' => $plugin['slug'],
                'plugin' => $plugin_file,
                'new_version' => $manifest['version'],
                'url' => $manifest['homepage'] ?? self::HOST,
                'package' => $manifest['download_url'] ?? '',
                'tested' => $manifest['tested'] ?? '',
                'requires' => $manifest['requires'] ?? '',
                'requires_php' => $manifest['requires_php'] ?? '',
            ];
        }

        return $transient;
    }

    public function filter_plugins_api($result, $action, $args) {
        if ($action !== 'plugin_information' || empty($args->slug)) {
            return $result;
        }

        $plugin = $this->plugin_by_slug($args->slug);
        if (!$plugin) {
            return $result;
        }

        $manifest = $this->manifest($plugin);
        if (!$manifest) {
            return $result;
        }

        return (object) [
            'name' => $manifest['name'] ?? $plugin['name'],
            'slug' => $plugin['slug'],
            'version' => $manifest['version'] ?? $plugin['version'],
            'author' => $manifest['author'] ?? 'Better Mousetrap',
            'homepage' => $manifest['homepage'] ?? self::HOST,
            'requires' => $manifest['requires'] ?? '',
            'tested' => $manifest['tested'] ?? '',
            'requires_php' => $manifest['requires_php'] ?? '',
            'sections' => $manifest['sections'] ?? [],
            'download_link' => $manifest['download_url'] ?? '',
        ];
    }

    public function clear_cache() {
        foreach ($this->plugins as $plugin) {
            delete_site_transient('bmtqb_update_manifest_' . md5($plugin['manifest_url']));
        }
    }

    private function plugin_by_slug($slug) {
        foreach ($this->plugins as $plugin) {
            if ($plugin['slug'] === $slug) {
                return $plugin;
            }
        }

        return null;
    }

    private function manifest(array $plugin) {
        $cache_key = 'bmtqb_update_manifest_' . md5($plugin['manifest_url']);
        $cached = get_site_transient($cache_key);
        if (is_array($cached)) {
            return $cached;
        }

        $url = add_query_arg([
            'version' => $plugin['version'],
            'channel' => $this->license_manager->channel(),
        ], $plugin['manifest_url']);

        $response = wp_remote_get($url, [
            'timeout' => 10,
            'headers' => [
                'Authorization' => 'Bearer ' . $this->license_manager->license_code(),
                'X-Quote-Site' => home_url(),
            ],
        ]);

        if (is_wp_error($response)) {
            return null;
        }

        $code = wp_remote_retrieve_response_code($response);
        if ($code < 200 || $code >= 300) {
            return null;
        }

        $manifest = json_decode(wp_remote_retrieve_body($response), true);
        if (!is_array($manifest)) {
            return null;
        }

        set_site_transient($cache_key, $manifest, 6 * HOUR_IN_SECONDS);

        return $manifest;
    }
}
