<?php

namespace App\Patient\Repository;

use App\Auth\Entity\User;
use App\Patient\Entity\PatientRecord;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

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

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

    public function findByEntityAndUser(string $entityType, int $entityId, User $user): ?PatientRecord
    {
        return $this->findOneBy([
            'entityType' => $entityType,
            'entityId'   => $entityId,
            'user'       => $user,
        ]);
    }

    public function findByEntity(string $entityType, int $entityId, int $page = 1, int $limit = 20, ?string $search = null): array
    {
        $qb = $this->createQueryBuilder('r')
            ->join('r.user', 'u')
            ->where('r.entityType = :type')
            ->andWhere('r.entityId = :id')
            ->setParameter('type', $entityType)
            ->setParameter('id', $entityId)
            ->orderBy('r.id', 'DESC')
            ->setFirstResult(($page - 1) * $limit)
            ->setMaxResults($limit);

        if ($search !== null && $search !== '') {
            $qb->andWhere('u.realName LIKE :search OR u.mobileNumber LIKE :search OR u.nationalCode LIKE :search')
               ->setParameter('search', '%' . $search . '%');
        }

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

    public function countByEntity(string $entityType, int $entityId, ?string $search = null): int
    {
        $qb = $this->createQueryBuilder('r')
            ->select('COUNT(r.id)')
            ->join('r.user', 'u')
            ->where('r.entityType = :type')
            ->andWhere('r.entityId = :id')
            ->setParameter('type', $entityType)
            ->setParameter('id', $entityId);

        if ($search !== null && $search !== '') {
            $qb->andWhere('u.realName LIKE :search OR u.mobileNumber LIKE :search OR u.nationalCode LIKE :search')
               ->setParameter('search', '%' . $search . '%');
        }

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

    public function countUnique(string $entityType, int $entityId, int $from, int $to): int
    {
        return (int) $this->createQueryBuilder('r')
            ->select('COUNT(DISTINCT r.user)')
            ->join('r.sessions', 's')
            ->where('r.entityType = :type')
            ->andWhere('r.entityId = :id')
            ->andWhere('s.createdAt BETWEEN :from AND :to')
            ->setParameter('type', $entityType)
            ->setParameter('id', $entityId)
            ->setParameter('from', $from)
            ->setParameter('to', $to)
            ->getQuery()
            ->getSingleScalarResult();
    }

    public function save(PatientRecord $record): void
    {
        $this->getEntityManager()->persist($record);
        $this->getEntityManager()->flush();
    }
}
