<?php

namespace App\Blog\Repository;

use App\Blog\Entity\Blog;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

class BlogRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry) { parent::__construct($registry, Blog::class); }

    public function findByUuid(string $uuid): ?Blog { return $this->findOneBy(['uuid' => $uuid]); }
    public function findBySlug(string $slug): ?Blog { return $this->findOneBy(['slug' => $slug]); }

    /** @return Blog[] published, newest first */
    public function findPublished(int $page = 1, int $limit = 20, ?string $tag = null): array
    {
        $qb = $this->createQueryBuilder('b')
            ->where('b.status = :status')
            ->setParameter('status', Blog::STATUS_PUBLISHED)
            ->orderBy('b.createdAt', 'DESC')
            ->setFirstResult(($page - 1) * $limit)
            ->setMaxResults($limit);

        $this->applyTagFilter($qb, $tag);

        return $qb->getQuery()->getResult();
    }

    public function countPublished(?string $tag = null): int
    {
        $qb = $this->createQueryBuilder('b')
            ->select('COUNT(b.id)')
            ->where('b.status = :status')
            ->setParameter('status', Blog::STATUS_PUBLISHED);

        $this->applyTagFilter($qb, $tag);

        return (int) $qb->getQuery()->getSingleScalarResult();
    }

    private function applyTagFilter(\Doctrine\ORM\QueryBuilder $qb, ?string $tag): void
    {
        if ($tag === null || $tag === '') {
            return;
        }
        // Blog.tags is a JSON array of tag names; match exact name membership.
        $qb->andWhere('JSON_CONTAINS(b.tags, :tag) = 1')
           ->setParameter('tag', json_encode($tag, JSON_UNESCAPED_UNICODE));
    }

    public function save(Blog $e, bool $flush = true): void { $this->getEntityManager()->persist($e); if ($flush) $this->getEntityManager()->flush(); }
    public function remove(Blog $e, bool $flush = true): void { $this->getEntityManager()->remove($e); if ($flush) $this->getEntityManager()->flush(); }
}
