<?php

declare(strict_types=1);

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

/**
 * Immutable data transfer object representing the highest-severity vulnerability
 * for a specific installed component.
 *
 * This DTO combines vulnerability data with local runtime context, such as:
 * - Which component is affected (plugin, theme, or core).
 * - The highest detected severity for that component.
 * - Whether an update is available for the installed version.
 *
 * It is primarily used to:
 * - Drive admin UI displays (tables, dashboards).
 * - Provide structured input for notification and policy decisions.
 *
 * This object contains data only:
 * - No persistence logic
 * - No policy or decision logic
 * - No WordPress hooks or scheduling concerns
 */
final class HighestSeverityContextDto
{
    /**
     * Normalized severity label (`low`, `medium`, `high`, `critical`).
     *
     * @var string
     */
    public string $severity;

    /**
     * Vulnerability identifier used for correlation and lookups.
     *
     * @var string
     */
    public string $lookup;

    /**
     * Component slug used to match installed components.
     *
     * @var string
     */
    public string $slug;

    /**
     * Component type (`plugin`, `theme`, or `core`).
     *
     * @var string
     */
    public string $type;

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

    /**
     * Latest known available version for this component.
     *
     * @var string
     */
    public string $latestVersion;

    /**
     * Whether an update is currently available.
     *
     * @var bool
     */
    public bool $hasUpdate;

    /**
     * Raw vulnerability payload as received from storage/API.
     *
     * @var array<string, mixed>
     */
    public array $vulnerability;

    /**
     * Constructor.
     *
     * @param string $severity Normalized severity label (`low`, `medium`, `high`, `critical`).
     * @param string $lookup Vulnerability identifier used for correlation and lookups.
     * @param string $slug Component slug used to match installed components.
     * @param string $type Component type (`plugin`, `theme`, or `core`).
     * @param string $name Human-readable component name.
     * @param string $latestVersion Latest known available version for this component.
     * @param bool $hasUpdate Whether an update is currently available.
     * @param array<string, mixed> $vulnerability Raw vulnerability payload as received from storage/API.
     */
    public function __construct(
        string $severity,
        string $lookup,
        string $slug,
        string $type,
        string $name,
        string $latestVersion,
        bool $hasUpdate,
        array $vulnerability
    ) {
        $this->vulnerability = $vulnerability;
        $this->hasUpdate = $hasUpdate;
        $this->latestVersion = $latestVersion;
        $this->name = $name;
        $this->type = $type;
        $this->slug = $slug;
        $this->lookup = $lookup;
        $this->severity = $severity;
    }

    /**
     * Return a new instance with an updated hasUpdate flag.
     *
     * The original instance is not modified (immutability).
     *
     * @param bool $hasUpdate New hasUpdate flag value.
     * @return self New instance with updated hasUpdate.
     */
    public function withHasUpdate(bool $hasUpdate): self
    {
        return new self(
            $this->severity,
            $this->lookup,
            $this->slug,
            $this->type,
            $this->name,
            $this->latestVersion,
            $hasUpdate,
            $this->vulnerability
        );
    }

    /**
     * Convert this DTO to an array.
     *
     * The array shape is intended for UI rendering or serialization.
     * The returned structure is stable and explicit.
     *
     * @return array{
     *   severity: string,
     *   lookup: string,
     *   slug: string,
     *   type: string,
     *   name: string,
     *   latestVersion: string,
     *   hasUpdate: bool,
     *   vulnerability: array<string, mixed>
     * }
     */
    public function toArray(): array
    {
        return [
            'severity' => $this->severity,
            'lookup' => $this->lookup,
            'slug' => $this->slug,
            'type' => $this->type,
            'name' => $this->name,
            'latestVersion' => $this->latestVersion,
            'hasUpdate' => $this->hasUpdate,
            'vulnerability' => $this->vulnerability,
        ];
    }
}
