<?php

namespace PortalPeople\virtualstock\controllers;

use PortalPeople\virtualstock\exceptions\ValidationException;
use PortalPeople\virtualstock\jobs\ProcessWebhookJob;
use PortalPeople\virtualstock\services\WebhookService;
use yii\filters\VerbFilter;
use yii\web\Controller;
use yii\web\Response;
use Yii;

/**
 * Receives inbound VirtualStock webhook HTTP requests.
 *
 * Register in the host application URL rules, e.g.:
 *   'virtualstock/webhook/receive' => 'virtualstock/webhook/receive'
 *
 * The endpoint must be publicly accessible (no session/CSRF required — the
 * webhook secret provides authentication instead).
 */
class WebhookController extends Controller
{
    /** @inheritdoc */
    public $enableCsrfValidation = false;

    public function behaviors(): array
    {
        return [
            'verbFilter' => [
                'class'   => VerbFilter::class,
                'actions' => [
                    'receive' => ['POST'],
                ],
            ],
        ];
    }

    /**
     * Receive and process a VirtualStock webhook push notification.
     */
    public function actionReceive(): Response
    {
        Yii::$app->response->format = Response::FORMAT_JSON;

        $module = Yii::$app->getModule('virtualstock');
        if ($module === null || !$module->isConfigured()) {
            Yii::$app->response->statusCode = 503;
            return $this->asJson(['error' => 'Module not configured']);
        }

        $rawBody         = Yii::$app->request->getRawBody();
        $signatureHeader = Yii::$app->request->getHeaders()->get('X-Virtualstock-Signature', '');

        /** @var WebhookService $service */
        $service = Yii::createObject([
            'class'         => WebhookService::class,
            'webhookSecret' => $module->webhookSecret ?? '',
        ]);

        try {
            // When queue processing is enabled, signature is verified inline for
            // immediate 400 rejection on bad signatures, then the payload is handed
            // off to a queue job for async processing.
            if ($module->useQueue) {
                $service = Yii::createObject([
                    'class'         => WebhookService::class,
                    'webhookSecret' => $module->webhookSecret ?? '',
                ]);

                // Verify signature before queuing — bad signatures are rejected immediately.
                $service->verifySignature($rawBody, $signatureHeader);

                Yii::$app->get($module->queueComponent)->push(new ProcessWebhookJob([
                    'rawBody'         => $rawBody,
                    'signatureHeader' => $signatureHeader,
                ]));
            } else {
                $service = Yii::createObject([
                    'class'         => WebhookService::class,
                    'webhookSecret' => $module->webhookSecret ?? '',
                ]);

                $service->process($rawBody, $signatureHeader);
            }
        } catch (ValidationException $e) {
            Yii::$app->response->statusCode = 400;
            return $this->asJson(['error' => $e->getMessage()]);
        }

        Yii::$app->response->statusCode = 200;
        return $this->asJson(['ok' => true]);
    }
}
