<?php

/**
 * Copyright 2024-2025 Simply.IN Sp. z o.o.
 *
 * NOTICE OF LICENSE
 *
 * Licensed under the EUPL-1.2 or later.
 * You may not use this work except in compliance with the Licence.
 *
 * Copy of the Licence is available at:
 * https://joinup.ec.europa.eu/software/page/eupl
 * It is bundled with this package in the file LICENSE.txt
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the Licence is distributed on an as is basis,
 * without warranties or conditions of any kind, either express or implied.
 * Check the Licence for the specific language governing permissions
 * and limitations under the License.
 *
 * @author   Simply.IN Sp. z o.o.
 * @copyright 2024-2025 Simply.IN Sp. z o.o.
 * @license   https://joinup.ec.europa.eu/software/page/eupl
 */

declare(strict_types=1);

namespace SimplyIn\Webhook;

use Configuration;
use Order;
use PrestaShopLogger;
use SimplyIn\Payment\OrderStateUpdaterInterface;
use Validate;

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

final class WebhookProcessor
{
    public function __construct(
        private readonly OrderStateUpdaterInterface $orderStateUpdater,
        private readonly WebhookContextScoperInterface $contextScoper,
    ) {
    }

    /**
     * Apply the webhook status to every order matching the reference.
     *
     * @return bool true when at least one order was found and handled; false when no order matched
     *              (e.g. the webhook raced ahead of order creation) so the caller can allow a retry
     */
    public function process(string $orderReference, string $status): bool
    {
        $handled = false;
        $orders = Order::getByReference($orderReference);
        foreach ($orders as $order) {
            if (!($order instanceof Order) || !Validate::isLoadedObject($order)) {
                continue;
            }
            $handled = true;

            $this->contextScoper->scope($order);

            switch (strtoupper($status)) {
                case 'PAID':
                    $this->orderStateUpdater->update(
                        $order,
                        (int) Configuration::get('PS_OS_PAYMENT'),
                        'markAsPaid',
                    );

                    break;

                case 'REJECTED':
                case 'FAILED':
                case 'FAILD': // defensive: legacy backend typo, kept in sync with PaymentStatusChecker::TERMINAL_STATUSES
                    $this->orderStateUpdater->update(
                        $order,
                        (int) Configuration::get('SIMPLYIN_PAYMENT_STATUS_CANCELED'),
                        'markAsRejected',
                    );

                    break;

                case 'CANCELLED':
                    $this->orderStateUpdater->update(
                        $order,
                        (int) Configuration::get('SIMPLYIN_PAYMENT_STATUS_CANCELED'),
                        'markAsCancelled',
                    );

                    break;

                case 'REFUNDED':
                    $this->orderStateUpdater->update(
                        $order,
                        (int) Configuration::get('PS_OS_REFUND'),
                        'markAsRefunded',
                    );

                    break;

                default:
                    PrestaShopLogger::addLog(
                        sprintf('SimplyIn webhook: unknown status "%s" for order %s', $status, $orderReference),
                        2,
                        null,
                        'SimplyIn',
                        (int) $order->id,
                        true,
                    );
            }
        }

        return $handled;
    }
}
