<?php

namespace Autogedal\TbiBank\Plugin;

use Autogedal\TbiBank\Model\FailureRedirect as FailureRedirectConfig;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\HTTP\Client\Curl;
use TbiBank\FusionPay\Helper\Data as FusionPayHelper;
use TbiBank\FusionPay\Model\Cryptor;

/** Replaces the vendor's success-page failure redirect without changing vendor code. */
class FailureRedirect
{
    public function __construct(
        private FusionPayHelper $fusionPayHelper,
        private FailureRedirectConfig $failureRedirect
    ) {
    }

    public function beforePost(Curl $subject, $uri, $params): array
    {
        if (parse_url((string) $uri, PHP_URL_PATH) !== '/api/RegisterApplication'
            || !is_string($params)
        ) {
            return [$uri, $params];
        }

        $request = json_decode($params, true);
        if (!is_array($request) || !is_string($request['data'] ?? null)) {
            return [$uri, $params];
        }

        $encryptionKey = (string) $this->fusionPayHelper->getConfigValue(
            'tbi_settings/general_settings/encryption_key'
        );
        if ($encryptionKey === '') {
            throw new LocalizedException(__('The TBI encryption key is not configured.'));
        }

        try {
            $application = json_decode(Cryptor::Decrypt($request['data'], $encryptionKey), true, 512, JSON_THROW_ON_ERROR);
            if (!is_array($application)) {
                throw new \UnexpectedValueException('TBI application payload is not an array.');
            }
            $application['failRedirectURL'] = $this->failureRedirect->getUrl(
                null,
                (string) ($application['orderid'] ?? ''),
                $encryptionKey
            );
            $request['data'] = Cryptor::Encrypt(
                json_encode($application, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_THROW_ON_ERROR),
                $encryptionKey
            );
        } catch (\Throwable $exception) {
            throw new LocalizedException(__('The TBI failure redirect could not be prepared.'), $exception);
        }

        return [$uri, json_encode($request, JSON_THROW_ON_ERROR)];
    }
}
