<?php

declare(strict_types=1);

namespace ReallySimplePlugins\RSS\Core\Features\Vulnerability\Dtos;

/**
 * Immutable data transfer object representing a locally installed WordPress component.
 *
 * A component can be a plugin, theme, or WordPress core. This DTO captures the
 * *runtime installation state* of that component and is primarily used to:
 * - Enrich vulnerability data with local context (installed version, update availability).
 * - Decide whether actions such as updates or notifications are relevant.
 *
 * This object contains state only:
 * - No persistence logic
 * - No vulnerability or policy logic
 * - No WordPress hook or scheduling concerns
 */
final class InstalledComponentDto
{
    /**
     * @var string Component type (`plugin`, `theme`, or `core`)
     */
    private string $type;

    /**
     * @var string Unique identifier used to match vulnerabilities
     */
    public string $slug;

    /**
     * @var string Human-readable component name
     */
    private string $name;

    /**
     * @var string Currently installed version
     */
    private string $installedVersion;

    /**
     * @var string|null Latest available version (null if unknown)
     */
    private ?string $latestVersion;

    /**
     * @var string Plugin file path (empty for themes/core)
     */
    private string $file;

    /**
     * @var bool Whether the component is currently active
     */
    private bool $isActive;

    /**
     * InstalledComponentDto constructor.
     *
     * @param string      $type           The type of the component (plugin, theme, or core)
     * @param string      $slug           Unique identifier for matching vulnerabilities
     * @param string      $name           Human-readable name of the component
     * @param string      $version        Currently installed version of the component
     * @param string|null $pluginFile     Plugin file path, or null if not applicable
     * @param bool        $isActive       Whether the component is currently active
     * @param string|null $latestVersion  Latest available version, or null if unknown
     */
    public function __construct(
        string $type,
        string $slug,
        string $name,
        string $version,
        ?string $pluginFile,
        bool $isActive,
        ?string $latestVersion
    ) {
        $this->type = $type;
        $this->slug = $slug;
        $this->name = $name;
        $this->installedVersion = $version;
        $this->file = $pluginFile ?? '';
        $this->isActive = $isActive;
        $this->latestVersion = $latestVersion;
    }

    /**
     * Get the component type.
     */
    public function getType(): string
    {
        return $this->type;
    }

    /**
     * Get the unique slug identifier.
     */
    public function getSlug(): string
    {
        return $this->slug;
    }

    /**
     * Get the human-readable component name.
     */
    public function getName(): string
    {
        return $this->name;
    }

    /**
     * Get the installed version of the component.
     */
    public function getInstalledVersion(): string
    {
        return $this->installedVersion;
    }

    /**
     * Get the latest available version of the component, or null if unknown.
     */
    public function getLatestVersion(): ?string
    {
        return $this->latestVersion;
    }

    /**
     * Determine if an update is available by comparing installed and latest versions.
     */
    public function hasUpdate(): bool
    {
        if ($this->latestVersion === null) {
            return false;
        }

        return version_compare(
            $this->installedVersion,
            $this->latestVersion,
            '<'
        );
    }

    /**
     * Get the plugin file path (empty string if not applicable).
     */
    public function getFile(): string
    {
        return $this->file;
    }

    /**
     * Check if the component is currently active.
     */
    public function isActive(): bool
    {
        return $this->isActive;
    }
}
