<?php

namespace App\Controller\Trigger;

use App\Message\TriggerPriceImport;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Stamp\TransportNamesStamp;
use Symfony\Component\RateLimiter\RateLimiterFactory;
use Symfony\Component\Routing\Annotation\Route;

final class PriceTriggerController extends AbstractController
{
    public function __construct(
        private readonly MessageBusInterface $bus,

        #[Autowire(service: 'limiter.price_import')]
        private readonly RateLimiterFactory  $priceImportLimiter,

        private readonly LoggerInterface     $logger
    )
    {
    }

    #[Route('/trigger-import', name: 'trigger_import', methods: ['POST'])]
    public function trigger(Request $request): JsonResponse
    {
        $limiter = $this->priceImportLimiter->create('price_import_trigger_limiter');
        $limit = $limiter->consume();

        if (!$limit->isAccepted()) {
            return new JsonResponse([
                'status' => 'rate-limited',
                'retry_after' => $limit->getRetryAfter()?->getTimestamp() - time(),
            ], 429);
        }

        $timestamp = time(); // Default fallback

        if ($request->getContent()) {
            try {
                $payload = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);

                if (is_array($payload) && isset($payload['timestamp']) && is_numeric($payload['timestamp'])) {
                    $timestamp = (int)$payload['timestamp'];
                }
            } catch (\JsonException $e) {
                $this->logger->warning('Invalid JSON payload in optional body', ['error' => $e->getMessage(), 'payload' => $request->getContent()]);
            }
        }

        try {
            $this->bus->dispatch(
                new TriggerPriceImport((string)$timestamp),
                [new TransportNamesStamp(['async'])]
            );
        } catch (\Throwable $e) {
            $this->logger->error('Dispatch failed', ['exception' => $e]);

            return new JsonResponse([
                'status' => 'error',
                'message' => 'Dispatch failed',
            ], 500);
        }

        return new JsonResponse([
            'status' => 'queued',
            'timestamp' => $timestamp,
        ]);
    }
}
