<?php

declare(strict_types=1);

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

use ReallySimplePlugins\RSS\Core\Features\Pro\Vulnerability\Services\VulnerabilityMeasuresConfigService;
use ReallySimplePlugins\RSS\Core\Interfaces\ControllerInterface;
use ReallySimplePlugins\RSS\Core\Interfaces\DoActionInterface;
use ReallySimplePlugins\RSS\Core\Services\EmailService;

/**
 * Handles measures configuration actions for the Settings UI.
 */
final class VulnerabilityMeasuresConfigController implements ControllerInterface, DoActionInterface
{
    /**
     * Action hook used for getting measures configuration when opening the
     * Measures settings UI.
     */
    private const GET_MEASURES_ACTION = 'vulnerabilities_measures_get';

    /**
     * Action hook used for persisting measures configuration when saving in
     * the Measures settings UI.
     */
    private const SET_MEASURES_ACTION = 'vulnerabilities_measures_set';

    private VulnerabilityMeasuresConfigService $measuresConfigService;
    private EmailService $emailService;

    public function __construct(
        VulnerabilityMeasuresConfigService $measuresConfigService,
        EmailService $emailService
    )
    {
        $this->measuresConfigService = $measuresConfigService;
        $this->emailService = $emailService;
    }

    /**
     * @inheritDoc
     */
    public function register(): void
    {
        add_filter('rsssl_do_action', [$this, 'rssslDoAction'], 9, 3);
    }

    /**
     * @inheritDoc
     */
    public function rssslDoAction(array $response, string $action, $data): array
    {
        switch ($action) {
            case self::GET_MEASURES_ACTION:
                return $this->handleGetMeasures();

            case self::SET_MEASURES_ACTION:
                return $this->handleSaveMeasures($data);

            default:
                return $response;
        }
    }

    /**
     * Build the response payload for the measures settings UI.
     */
    private function handleGetMeasures(): array
    {
        return [
            'request_success' => true,
            'data' => $this->measuresConfigService->getMeasures(),
        ];
    }

    /**
     * Persist submitted measures and return a standard success response.
     *
     * When email validation is incomplete, submitted measures are normalized to
     * the disabled state before they are persisted.
     *
     * @param mixed $data Action payload coming from the Settings UI.
     */
    private function handleSaveMeasures($data): array
    {
        $riskData = [];
        if (is_array($data) && isset($data['riskData']) && is_array($data['riskData'])) {
            $riskData = $data['riskData'];
        }

        if (!$this->emailService->isEmailVerified()) {
            $riskData = $this->disableSubmittedMeasures($riskData);
        }

        $this->measuresConfigService->saveMeasures($riskData);

        return [
            'request_success' => true,
            'data' => [],
        ];
    }

    /**
     * Normalize submitted measures to the disabled state.
     *
     * @param array<int, array{id: string, value: mixed}> $riskData
     * @return array<int, array{id: string, value: string}>
     */
    private function disableSubmittedMeasures(array $riskData): array
    {
        return array_map(static function ($item): array {
            if (!is_array($item) || !isset($item['id'])) {
                return [
                    'id' => '',
                    'value' => '*',
                ];
            }

            return [
                'id' => (string) $item['id'],
                'value' => '*',
            ];
        }, $riskData);
    }
}
