<?php
/**
 * 2026 Paysera
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@prestashop.com so we can send you a copy immediately.
 *
 * @author Paysera <plugins@paysera.com>
 * @copyright 2026 Paysera
 * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
 * International Registered Trademark & Property of Paysera
 */

declare(strict_types=1);

use Paysera\PrestashopPayments\Factory\RequestFactory;
use Paysera\PrestashopPayments\Repository\OrderRepository;
use Paysera\PrestashopPayments\Repository\PayseraPaymentRepository;
use Paysera\PrestashopPayments\Service\CartRestorationService;
use Paysera\PrestashopPayments\Service\CheckoutErrorHandler;
use Paysera\PrestashopPayments\Service\CmsCookieFacade;
use Paysera\PrestashopPayments\Service\CmsToolsFacade;
use Paysera\PrestashopPayments\Service\OrderStatusManager;
use Paysera\PrestashopPayments\Service\PopupBridgeRenderer;
use Psr\Log\LoggerInterface;

if (!defined('_PS_VERSION_')) {
    exit;
}

class PayserapaymentsFailureModuleFrontController extends ModuleFrontController
{
    public function postProcess(): void
    {
        $cmsToolsFacade = $this->get(CmsToolsFacade::class);
        $logger = $this->get('paysera.logger');

        $this->logFailureHit($logger, $cmsToolsFacade);

        $this->markOrderFailed($cmsToolsFacade);

        $this->restoreCart($cmsToolsFacade);

        $checkoutUrl = $this->context->link->getPageLink('order', true);

        if ($cmsToolsFacade->getValue('restore')) {
            $cmsToolsFacade->redirect($checkoutUrl);

            return;
        }

        $errorHandler = new CheckoutErrorHandler($this->context->cookie);
        $errorHandler->setError(
            $this->module->getTranslator()->trans(
                'Payment was not completed. Please try again.',
                [],
                'Modules.Payserapayments.Global'
            )
        );
        $this->get(CmsCookieFacade::class)->write();

        $this->get(PopupBridgeRenderer::class)->redirect($checkoutUrl, $this->context->cookie);
    }

    private function markOrderFailed(CmsToolsFacade $cmsToolsFacade): void
    {
        $cartId = (int) $cmsToolsFacade->getValue('id_cart');

        if ($cartId <= 0) {
            return;
        }

        $order = $this->get(OrderRepository::class)->findByCartId($cartId);

        if ($order === null) {
            return;
        }

        $customerId = (int) ($this->context->customer->id ?? 0);

        if ($customerId <= 0 || (int) $order->id_customer !== $customerId) {
            return;
        }

        $this->get(OrderStatusManager::class)->setToFailed($order);
    }

    private function restoreCart(CmsToolsFacade $cmsToolsFacade): void
    {
        $cartId = (int) $cmsToolsFacade->getValue('id_cart');

        if ($cartId <= 0) {
            return;
        }

        $this->get(CartRestorationService::class)->restoreCartForFailedPayment($this->context, $cartId);

        $this->get(CmsCookieFacade::class)->remove('paysera_pending_cart_id');
    }

    private function logFailureHit(LoggerInterface $logger, CmsToolsFacade $cmsToolsFacade): void
    {
        $request = $this->get(RequestFactory::class)->createFromGlobals();
        $cartId = (int) $cmsToolsFacade->getValue('id_cart');

        $context = [
            'id_cart' => $cartId,
            'restore' => $cmsToolsFacade->getValue('restore'),
            'query_string' => $request->getUri()->getQuery(),
            'referer' => $request->getHeaderLine('Referer'),
        ];

        if ($cartId > 0) {
            $orderRepository = $this->get(OrderRepository::class);
            $order = $orderRepository->findByCartId($cartId);

            if ($order !== null) {
                $context['id_order'] = (int) $order->id;
                $context['current_state'] = (int) $order->current_state;
                $context['reference'] = $order->reference;

                $paysera = $this->get(PayseraPaymentRepository::class)->findByOrderId((int) $order->id);
                if ($paysera !== null) {
                    $context['paysera_payment_id'] = $paysera->getPayseraPaymentId();
                    $context['paysera_order_id'] = $paysera->getPayseraOrderId();
                    $context['payment_method'] = $paysera->getPaymentMethod();
                }
            }
        }

        $logger->warning('Paysera failure URL hit — customer returned from gateway', $context);
    }
}
