<?php
declare(strict_types=1);

namespace PayPo\Payment\Controller\Redirect;

use Magento\Checkout\Model\Session;
use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\Controller\Result\RedirectFactory;
use Magento\Framework\Message\ManagerInterface;
use Magento\Sales\Model\Order;
use Magento\Sales\Model\OrderFactory;
use PayPo\Payment\Model\Payment\PayPo;

/**
 * Sends the customer from checkout to the PayPo payment page.
 */
class Index implements HttpGetActionInterface
{
    /**
     * @param Session $checkoutSession
     * @param OrderFactory $orderFactory
     * @param RedirectFactory $resultRedirectFactory
     * @param ManagerInterface $messageManager
     */
    public function __construct(
        private readonly Session $checkoutSession,
        private readonly OrderFactory $orderFactory,
        private readonly RedirectFactory $resultRedirectFactory,
        private readonly ManagerInterface $messageManager
    ) {
    }

    /**
     * @return Redirect
     */
    public function execute()
    {
        $resultRedirect = $this->resultRedirectFactory->create();
        $order = $this->getOrder();
        $url = $order ? (string)$order->getPayment()?->getAdditionalInformation(PayPo::REDIRECT_URL_KEY) : '';

        // Orders placed by older module versions have the url stored html encoded.
        $url = html_entity_decode($url, ENT_QUOTES | ENT_HTML5);

        if ($url !== '' && (str_starts_with($url, 'https://') || str_starts_with($url, 'http://'))) {
            return $resultRedirect->setUrl($url);
        }

        $this->messageManager->addErrorMessage(__('PayPo url not found'));

        return $resultRedirect->setPath('checkout/cart');
    }

    /**
     * Order the customer has just placed, if any.
     *
     * @return Order|null
     */
    public function getOrder(): ?Order
    {
        $incrementId = $this->checkoutSession->getLastRealOrderId();

        if (!$incrementId) {
            return null;
        }

        $order = $this->orderFactory->create()->loadByIncrementId($incrementId);

        return $order->getId() ? $order : null;
    }
}
