<?php

declare(strict_types=1);

namespace CloudXM\SDK\Services;

use CloudXM\SDK\Contracts\ConfigurationInterface;
use CloudXM\SDK\Support\HasLogger;

/**
 * Abstract Update Service
 *
 * Provides core functionality for plugin update checking using Plugin Update Checker.
 * Plugin-specific implementations should extend this class and implement
 * the abstract getUpdateServerUrl() method.
 */
abstract class AbstractUpdateService
{
    use HasLogger;

    protected ConfigurationInterface $config;

    public function __construct(ConfigurationInterface $config)
    {
        $this->config = $config;
        $this->log()->debug('AbstractUpdateService initialized', ['plugin_file' => $config->getPluginFilePath()]);
    }

    /**
     * Initialize the update checker; call early in plugin lifecycle
     */
    public function initUpdateChecker(): void
    {
        if ($this->isPucLoaded()) {
            $this->log()->debug('Update checker already initialized');
            return;
        }

        if (!$this->loadPuc()) {
            $this->log()->error('Failed to load Plugin Update Checker');
            return;
        }

        if (!$this->initializePuc()) {
            $this->log()->error('Failed to initialize update checker');
            return;
        }

        define('CLOUDXM_PUC_LOADED_' . $this->config->getPluginFilePath(), true);
        $this->log()->debug('Update checker initialized successfully');
    }

    protected function isPucLoaded(): bool
    {
        return defined('CLOUDXM_PUC_LOADED_' . $this->config->getPluginFilePath());
    }

    protected function loadPuc(): bool
    {
        return class_exists('YahnisElsts\PluginUpdateChecker\v5\PucFactory');
    }

    protected function initializePuc(): bool
    {
        try {
            $updateUrl = $this->getUpdateServerUrl();
            $pluginFile = $this->config->getPluginFilePath();
            $slug = basename($pluginFile, '.php');

            // Verify the plugin file exists and is readable
            if (!file_exists($pluginFile) || !is_readable($pluginFile)) {
                $this->log()->error('Plugin file not found or not readable', [
                    'path' => $pluginFile,
                    'exists' => file_exists($pluginFile),
                    'readable' => is_readable($pluginFile)
                ]);
                return false;
            }

            $checker = \YahnisElsts\PluginUpdateChecker\v5\PucFactory::buildUpdateChecker(
                $updateUrl,
                $pluginFile,
                $slug
            );

            if (!$checker) {
                $this->log()->error('PUC factory returned null checker');
                return false;
            }

            $this->log()->debug('PUC instance built', ['url' => $updateUrl, 'slug' => $slug, 'file' => $pluginFile]);
            return true;
        } catch (\Throwable $e) {
            $this->log()->error('PUC init error', ['msg' => $e->getMessage(), 'trace' => $e->getTraceAsString()]);
            return false;
        }
    }

    /**
     * Get update URL depending on environment (dev or prod)
     */
    abstract public function getUpdateServerUrl(): string;

    /**
     * Check if current environment is development
     */
    protected function isDevelopmentEnvironment(string $site): bool
    {
        return (
            (defined('WP_DEBUG') && WP_DEBUG) ||
            (defined('WP_ENVIRONMENT_TYPE') && constant('WP_ENVIRONMENT_TYPE') === 'development') ||
            (defined('CLOUDXM_FORCE_DEV_MODE') && constant('CLOUDXM_FORCE_DEV_MODE')) ||
            strpos($site, 'localhost') !== false ||
            strpos($site, '.local') !== false ||
            strpos($site, 'dev.') !== false ||
            strpos($site, '-dev.') !== false ||
            strpos($site, 'staging') !== false ||
            strpos($site, 'destilus.com.br') !== false
        );
    }
}