<?php

namespace App\Blog\Service;

use App\Blog\Entity\Blog;
use Psr\Log\LoggerInterface;
use Symfony\Contracts\HttpClient\HttpClientInterface;

/**
 * پس از هر نوشتن روی بلاگ، کش ISR سایت عمومی (nobat724_front) را باطل می‌کند.
 *
 * سایت پاسخ `GET /api/v1/blog/{slug}` را با `revalidate: 3600` و tag ذخیره
 * می‌کند؛ بدون این فراخوانی، تغییر پنل ادمین تا یک ساعت روی سایت دیده نمی‌شود.
 *
 * قرارداد: `POST {webhookUrl}` با هدر `X-Revalidate-Secret` و بدنهٔ
 * `{"tags": ["blog-<slug>", "blog-<uuid>", "blog-list"]}`.
 *
 * fail-open: شکست شبکه فقط لاگ می‌شود و هرگز ذخیرهٔ مقاله را نمی‌شکند.
 */
class BlogCacheInvalidator
{
    public function __construct(
        private readonly HttpClientInterface $httpClient,
        private readonly LoggerInterface $logger,
        private readonly string $webhookUrl,     // خالی = سایت عمومی پیکربندی نشده
        private readonly string $webhookSecret,
    ) {}

    public function invalidate(Blog $blog): void
    {
        if ($this->webhookUrl === '' || $this->webhookSecret === '') {
            return;
        }

        // مقادیر قبل از هر تغییر بعدی برداشته می‌شوند تا حذف مقاله هم قابل باطل‌سازی باشد.
        $tags = array_values(array_filter([
            $blog->getSlug() !== '' ? 'blog-' . $blog->getSlug() : null,
            'blog-' . $blog->getUuid(),
            'blog-list',
        ]));

        try {
            $this->httpClient->request('POST', $this->webhookUrl, [
                'json'    => ['tags' => $tags],
                'headers' => ['X-Revalidate-Secret' => $this->webhookSecret],
                'timeout' => 3,
            ])->getStatusCode();
        } catch (\Throwable $e) {
            $this->logger->warning('blog cache invalidation failed', [
                'uuid'  => $blog->getUuid(),
                'error' => $e->getMessage(),
            ]);
        }
    }
}
