<?php
/**
 * ADOBE CONFIDENTIAL
 *
 * Copyright 2023 Adobe
 * All Rights Reserved.
 *
 * NOTICE: All information contained herein is, and remains
 * the property of Adobe and its suppliers, if any. The intellectual
 * and technical concepts contained herein are proprietary to Adobe
 * and its suppliers and are protected by all applicable intellectual
 * property laws, including trade secret and copyright laws.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe.
 */
declare(strict_types=1);

namespace PayPal\Braintree\Model\Recaptcha;

use Magento\Framework\Exception\InputException;
use Magento\Framework\Webapi\Rest\Request;
use Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface;
use Magento\ReCaptchaUi\Model\ValidationConfigResolverInterface;
use Magento\ReCaptchaValidationApi\Api\Data\ValidationConfigInterface;
use Magento\ReCaptchaWebapiApi\Api\Data\EndpointInterface;
use Magento\ReCaptchaWebapiApi\Api\WebapiValidationConfigProviderInterface;
use PayPal\Braintree\Model\Ui\ConfigProvider;

/**
 * Provide checkout related endpoint configuration.
 */
class WebapiConfigProvider implements WebapiValidationConfigProviderInterface
{
    public const CAPTCHA_ID = 'braintree';

    /**
     * @param Request $request
     * @param IsCaptchaEnabledInterface $isEnabled
     * @param ValidationConfigResolverInterface $configResolver
     */
    public function __construct(
        private readonly Request $request,
        private readonly IsCaptchaEnabledInterface $isEnabled,
        private readonly ValidationConfigResolverInterface $configResolver
    ) {
    }

    /**
     * Provides a validation config for an endpoint if it exists and validation is required.
     *
     * @param EndpointInterface $endpoint
     * @return ValidationConfigInterface|null
     * @throws InputException
     */
    public function getConfigFor(EndpointInterface $endpoint): ?ValidationConfigInterface
    {
        // Check if we should perform validation for the Rest Request.
        // Only skip captcha for savePaymentInformationAndPlaceOrder when it's NOT a Braintree payment.
        // placeOrder (PUT /guest-carts/{id}/order) has no payment data in the request body
        if ($endpoint->getServiceMethod() === 'savePaymentInformationAndPlaceOrder'
            && !$this->isBraintreePaymentRestRequest()
        ) {
            return null;
        }

        //phpcs:disable Magento2.PHP.LiteralNamespaces
        if ($endpoint->getServiceMethod() === 'savePaymentInformationAndPlaceOrder'
            || $endpoint->getServiceMethod() === 'placeOrder'
            || $endpoint->getServiceClass() === 'Magento\QuoteGraphQl\Model\Resolver\SetPaymentAndPlaceOrder'
            || $endpoint->getServiceClass() === 'Magento\QuoteGraphQl\Model\Resolver\PlaceOrder'
        ) {
            if ($this->isEnabled->isCaptchaEnabledFor(self::CAPTCHA_ID)) {
                return $this->configResolver->get(self::CAPTCHA_ID);
            }
        }
        //phpcs:enable Magento2.PHP.LiteralNamespaces

        return null;
    }

    /**
     * Check rest request from Braintree Payments
     *
     * @return bool
     */
    private function isBraintreePaymentRestRequest(): bool
    {
        $requestData = $this->request->getRequestData();

        return isset($requestData['paymentMethod']['method'])
            && $requestData['paymentMethod']['method'] === ConfigProvider::CODE;
    }
}
