<?php

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

class WNC_Plugin_Updater {

    const SLUG = 'where-next-connector';
    const PLUGIN_FILE = 'where-next-connector/where-next-connector.php';
    const UPDATE_URI = 'https://wherenext.dev/wordpress-connector/';
    const MANIFEST_URL = 'https://wherenext.dev/download-files/latest/wordpress/where-next-connector.json';
    const CACHE_KEY = 'wnc_plugin_update_manifest';

    public static function init() {
        add_filter('update_plugins_wherenext.dev', [__CLASS__, 'filter_update'], 10, 4);
        add_filter('plugins_api', [__CLASS__, 'plugin_information'], 20, 3);
        add_action('upgrader_process_complete', [__CLASS__, 'clear_cache_after_update'], 10, 2);
    }

    public static function filter_update($update, $plugin_data, $plugin_file, $locales) {
        if ($plugin_file !== self::PLUGIN_FILE) {
            return $update;
        }

        $manifest = self::get_manifest();

        if (!$manifest || empty($manifest['version']) || empty($manifest['download_url'])) {
            return false;
        }

        return [
            'id'           => self::UPDATE_URI,
            'slug'         => self::SLUG,
            'version'      => $manifest['version'],
            'url'          => $manifest['homepage'] ?? self::UPDATE_URI,
            'package'      => $manifest['download_url'],
            'tested'       => $manifest['tested'] ?? '',
            'requires'     => $manifest['requires'] ?? '',
            'requires_php' => $manifest['requires_php'] ?? '',
            'icons'        => is_array($manifest['icons'] ?? null) ? $manifest['icons'] : [],
            'banners'      => is_array($manifest['banners'] ?? null) ? $manifest['banners'] : [],
        ];
    }

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

        $manifest = self::get_manifest();

        if (!$manifest) {
            return $result;
        }

        $sections = [];

        foreach ((array) ($manifest['sections'] ?? []) as $key => $content) {
            $sections[sanitize_key($key)] = wp_kses_post((string) $content);
        }

        return (object) [
            'name'          => 'Where Next Connector',
            'slug'          => self::SLUG,
            'version'       => $manifest['version'] ?? WNC_VERSION,
            'author'        => '<a href="https://wherenext.dev/">Where Next</a>',
            'homepage'      => $manifest['homepage'] ?? self::UPDATE_URI,
            'requires'      => $manifest['requires'] ?? '6.0',
            'tested'        => $manifest['tested'] ?? '',
            'requires_php'  => $manifest['requires_php'] ?? '8.0',
            'last_updated'  => $manifest['last_updated'] ?? '',
            'download_link' => $manifest['download_url'] ?? '',
            'sections'      => $sections,
            'icons'         => is_array($manifest['icons'] ?? null) ? $manifest['icons'] : [],
            'banners'       => is_array($manifest['banners'] ?? null) ? $manifest['banners'] : [],
        ];
    }

    public static function get_manifest($force = false) {
        if (!$force) {
            $cached = get_site_transient(self::CACHE_KEY);

            if (is_array($cached)) {
                return $cached;
            }
        }

        $response = wp_remote_get(self::MANIFEST_URL, [
            'timeout' => 10,
            'redirection' => 3,
            'headers' => [
                'Accept' => 'application/json',
                'User-Agent' => 'WhereNextConnector/' . WNC_VERSION,
            ],
        ]);

        if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) {
            return false;
        }

        $manifest = json_decode(wp_remote_retrieve_body($response), true);

        if (!self::valid_manifest($manifest)) {
            return false;
        }

        set_site_transient(self::CACHE_KEY, $manifest, 6 * HOUR_IN_SECONDS);

        return $manifest;
    }

    private static function valid_manifest($manifest) {
        if (!is_array($manifest) || empty($manifest['version']) || empty($manifest['download_url'])) {
            return false;
        }

        if (!preg_match('/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/', (string) $manifest['version'])) {
            return false;
        }

        $download_url = esc_url_raw($manifest['download_url']);
        $scheme = wp_parse_url($download_url, PHP_URL_SCHEME);
        $host = wp_parse_url($download_url, PHP_URL_HOST);

        return $scheme === 'https' && $host === 'wherenext.dev';
    }

    public static function clear_cache_after_update($upgrader, $options) {
        if (($options['action'] ?? '') !== 'update' || ($options['type'] ?? '') !== 'plugin') {
            return;
        }

        $plugins = isset($options['plugins']) ? (array) $options['plugins'] : [];

        if (in_array(self::PLUGIN_FILE, $plugins, true)) {
            delete_site_transient(self::CACHE_KEY);
        }
    }
}
