<?php
/**
 * Copyright © Simplyin. All rights reserved.
 */
declare(strict_types=1);

namespace Simplyin\Payment\Controller\Api;

use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\CsrfAwareActionInterface;
use Magento\Framework\App\RequestInterface;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Customer\Model\Session as CustomerSession;
use Simplyin\Payment\Service\CheckoutOwnershipGuard;
use Simplyin\Payment\Service\ProcessPaymentService;

/**
 * Process Payment Controller (REST transport)
 *
 * Thin HTTP adapter: decodes the request body and delegates the payment-first
 * flow to {@see ProcessPaymentService}. All orchestration lives in the service
 * so it can be reused by the GraphQL resolver.
 */
class ProcessPayment implements HttpPostActionInterface, CsrfAwareActionInterface
{
    use CsrfAwareApiTrait;

    /**
     * @var JsonFactory
     */
    private $resultJsonFactory;

    /**
     * @var RequestInterface
     */
    private $request;

    /**
     * @var ProcessPaymentService
     */
    private $processPaymentService;

    /**
     * @var CheckoutOwnershipGuard
     */
    private $ownershipGuard;

    /**
     * @var CustomerSession
     */
    private $customerSession;

    /**
     * @param JsonFactory $resultJsonFactory
     * @param RequestInterface $request
     * @param ProcessPaymentService $processPaymentService
     * @param CheckoutOwnershipGuard $ownershipGuard
     * @param CustomerSession $customerSession
     */
    public function __construct(
        JsonFactory $resultJsonFactory,
        RequestInterface $request,
        ProcessPaymentService $processPaymentService,
        CheckoutOwnershipGuard $ownershipGuard,
        CustomerSession $customerSession
    ) {
        $this->resultJsonFactory = $resultJsonFactory;
        $this->request = $request;
        $this->processPaymentService = $processPaymentService;
        $this->ownershipGuard = $ownershipGuard;
        $this->customerSession = $customerSession;
    }

    /**
     * Authenticated customer id from the (cookie-backed) frontend session, or null.
     *
     * @return int|null
     */
    private function currentCustomerId(): ?int
    {
        return $this->customerSession->isLoggedIn()
            ? (int)$this->customerSession->getCustomerId()
            : null;
    }

    /**
     * Execute payment processing
     *
     * @return \Magento\Framework\Controller\Result\Json
     */
    public function execute()
    {
        // Tolerate any non-object body (scalar/malformed JSON) as an empty payload,
        // matching the previous inline flow which array-accessed $data defensively —
        // the service returns a graceful validation result rather than a 500.
        $data = json_decode($this->request->getContent(), true);
        if (!is_array($data)) {
            $data = [];
        }
        // The service reads orderData as an object; a scalar (e.g. {"orderData":"x"})
        // would raise a TypeError on its offset accesses. Normalise at the boundary.
        if (isset($data['orderData']) && !is_array($data['orderData'])) {
            $data['orderData'] = [];
        }

        // IDOR guard: an authenticated customer may only act on their own cart.
        if (!$this->ownershipGuard->isQuoteOwnedBy($this->currentCustomerId(), $data['orderData']['quoteId'] ?? null)) {
            return $this->resultJsonFactory->create()->setData([
                'success' => false,
                'message' => __('Unauthorized access to cart.')
            ])->setHttpResponseCode(403);
        }

        return $this->resultJsonFactory->create()->setData(
            $this->processPaymentService->process($data)
        );
    }
}
