<?php

declare(strict_types=1);

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

use ReallySimplePlugins\RSS\Core\Features\Vulnerability\Repositories\VulnerabilityStorageRepository;
use ReallySimplePlugins\RSS\Core\Features\Vulnerability\Services\VulnerabilityPresentationService;
use ReallySimplePlugins\RSS\Core\Features\Vulnerability\Traits\HasFrontendUrl;
use ReallySimplePlugins\RSS\Core\Interfaces\ControllerInterface;
use ReallySimplePlugins\RSS\Core\Traits\HasViews;

/**
 * Integrates vulnerability indicators into the WordPress Plugins admin screen.
 *
 * This controller is responsible only for UI integration:
 * - It registers admin hooks for the Plugins overview table.
 * - It fetches precomputed vulnerability data from repositories.
 * - It delegates formatting and labels to presentation services.
 *
 * No business logic or persistence is handled here.
 */
final class PluginController implements ControllerInterface
{
    use HasViews;
    use HasFrontendUrl;

    private VulnerabilityStorageRepository $vulnerabilityStorageRepository;

    private VulnerabilityPresentationService $presentationService;

    public function __construct(
        VulnerabilityStorageRepository $vulnerabilityStorageRepository,
        VulnerabilityPresentationService $presentationService
    ) {
        $this->vulnerabilityStorageRepository = $vulnerabilityStorageRepository;
        $this->presentationService = $presentationService;
    }

    /**
     * Registers WordPress admin hooks for extending the Plugins overview table.
     *
     * Hooks registered:
     * - 'manage_plugins_columns' to add a new column for vulnerabilities.
     * - 'manage_plugins_custom_column' to render content in the custom column.
     *
     * This method is intended to be called once during plugin bootstrapping.
     */
    public function register(): void
    {
        add_filter('manage_plugins_columns', [$this, 'addVulnerabilityColumn']);
        add_action('manage_plugins_custom_column', [$this, 'renderVulnerabilityColumn'], 10, 2);
        add_filter('manage_plugins-network_columns', [$this, 'addVulnerabilityColumn']);
        add_action('manage_plugins-network_custom_column', [$this, 'renderVulnerabilityColumn'], 10, 2);
    }

    /**
     * Adds a new column to the Plugins table in the WordPress admin.
     *
     * The returned array represents the column headers, where the key is the column slug
     * and the value is the displayed column title.
     *
     * @param array<string, string> $columns Existing columns keyed by slug.
     * @return array<string, string> Modified columns including the vulnerability column.
     */
    public function addVulnerabilityColumn(array $columns): array
    {
        $columns['rsssl_vulnerabilities'] = __('Vulnerabilities', 'really-simple-ssl');

        return $columns;
    }

    /**
     * Renders the vulnerability indicator content for a plugin row in the admin table.
     *
     * This method is called by WordPress for each plugin row when rendering custom columns.
     *
     * @param string $columnName The current column slug being rendered.
     * @param string $pluginFile The plugin file path relative to the plugins directory.
     *                           This is used to determine the plugin slug.
     *
     * Slug normalization is necessary because plugins can be either single PHP files
     * or directories containing multiple files.
     *
     * Output is echoed directly as per WordPress admin table rendering conventions.
     */
    public function renderVulnerabilityColumn(string $columnName, string $pluginFile): void
    {
        if ($columnName !== 'rsssl_vulnerabilities') {
            return;
        }

        // Normalize slug: plugins can be directories or single files, handle both cases.
        $slug = dirname($pluginFile);
        if ($slug === '.' || $slug === '/') {
            $slug = basename($pluginFile, '.php');
        }
        $slug = strtolower($slug);

        $highestSeverity = $this->vulnerabilityStorageRepository->getHighestSeverityForPluginSlug($slug);

        if ($highestSeverity === null) {
            echo '';

            return;
        }

        $label = $this->presentationService->getLabelForSeverity($highestSeverity->severity);

        echo $this->view('features/vulnerability/plugin-column', [
            'severity' => $highestSeverity->severity,
            'label' => $label,
            'frontendUrl' => $this->getFrontendUrl(
                'plugin',
                $slug,
                $highestSeverity->lookup
            ),
        ]);
    }
}
