<?php

namespace Datalumo\Update;

use stdClass;
use WP_Upgrader;

class PluginUpdater
{
    private string $updateUrl;
    private string $cacheKey = 'datalumo_updater';

    public function __construct()
    {
        $baseUrl = datalumo_get_base_url();

        if (empty($baseUrl)) {
            $baseUrl = 'https://datalumo.app';
        }

        $this->updateUrl = rtrim($baseUrl, '/') . '/api/wordpress/update-check';

        add_filter('plugins_api', [$this, 'pluginInfo'], 20, 3);
        add_filter('site_transient_update_plugins', [$this, 'checkUpdate']);
        add_action('upgrader_process_complete', [$this, 'purgeCache'], 10, 2);
    }

    private function fetchUpdateData(): object|false
    {
        $cached = get_transient($this->cacheKey);

        if ($cached === 'error') {
            return false;
        }

        if ($cached !== false) {
            $decoded = json_decode($cached);

            return ($decoded instanceof \stdClass) ? $decoded : false;
        }

        $response = wp_remote_get($this->updateUrl, [
            'timeout'   => 10,
            'sslverify' => defined('DATALUMO_SSL_VERIFY') ? DATALUMO_SSL_VERIFY : true,
        ]);

        if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) {
            set_transient($this->cacheKey, 'error', 10 * MINUTE_IN_SECONDS);

            return false;
        }

        $body = wp_remote_retrieve_body($response);

        if (empty($body)) {
            set_transient($this->cacheKey, 'error', 10 * MINUTE_IN_SECONDS);

            return false;
        }

        set_transient($this->cacheKey, $body, DAY_IN_SECONDS);

        $decoded = json_decode($body);

        return ($decoded instanceof \stdClass) ? $decoded : false;
    }

    public function pluginInfo(object|array|bool $result, string $action, object $args): object|bool
    {
        if ($action !== 'plugin_information' || ($args->slug ?? '') !== 'datalumo') {
            return $result;
        }

        $remote = $this->fetchUpdateData();

        if (! $remote || empty($remote->version)) {
            return $result;
        }

        $pluginData = get_plugin_data(DATALUMO_FILE);

        $info = clone $remote;
        $info->name = $pluginData['Name'];
        $info->slug = 'datalumo';
        $info->sections = (array) ($info->sections ?? []);

        return $info;
    }

    public function checkUpdate(object|bool $transient): object|bool
    {
        if (empty($transient->checked)) {
            return $transient;
        }

        $pluginId = 'datalumo/datalumo.php';

        $res = (object) [
            'id'            => $pluginId,
            'slug'          => 'datalumo',
            'plugin'        => $pluginId,
            'new_version'   => DATALUMO_VERSION,
            'url'           => '',
            'package'       => '',
            'icons'         => [],
            'banners'       => [],
            'banners_rtl'   => [],
            'tested'        => '',
            'requires_php'  => '',
            'compatibility' => new stdClass(),
        ];

        $remote = $this->fetchUpdateData();

        if ($remote && ! empty($remote->version)
            && version_compare(DATALUMO_VERSION, $remote->version, '<')
        ) {
            $res->new_version = $remote->version;
            $res->package = $remote->download_url ?? '';
            $res->tested = $remote->tested ?? '';
            $res->requires_php = $remote->requires_php ?? '';

            $transient->response[$pluginId] = $res;
        } else {
            $transient->no_update[$pluginId] = $res;
        }

        return $transient;
    }

    public function purgeCache(WP_Upgrader $upgrader, array $options): void
    {
        if ($options['action'] !== 'update' || $options['type'] !== 'plugin') {
            return;
        }

        foreach ($options['plugins'] ?? [] as $plugin) {
            if ($plugin === 'datalumo/datalumo.php') {
                delete_transient($this->cacheKey);

                return;
            }
        }
    }
}
