<?php

declare(strict_types=1);

namespace App\Service;

use App\Entity\Judge;
use Doctrine\ORM\EntityManager;
use UtilityModule\Hydrator\DoctrineObject;

class JudgeManager
{
    /** @var EntityManager */
    private $entityManager;

    /** @var DoctrineObject */
    private $hydrator;

    public function __construct(
        EntityManager $entityManager,
        DoctrineObject $hydrator
    ) {
        $this->entityManager = $entityManager;
        $this->hydrator = $hydrator;
    }

    public function getJudges()
    {
        $qb = $this->entityManager->createQueryBuilder();
        return $qb->select('j, t')
            ->from(Judge::class, 'j')
            ->leftJoin('j.titles', 't')
            ->orderBy('j.name', 'ASC')
            ->getQuery()
            ->getArrayResult();
    }

    /**
     * @param int $year
     * @return array
     */
    public function getJudgesByYear(int $year)
    {
        $qb = $this->entityManager->createQueryBuilder();
        return $qb->select('j,t')
            ->from(Judge::class, 'j')
            ->innerJoin('j.titles', 't')
            ->where('t.year = :year')
            ->orderBy('j.name', 'ASC')
            ->setParameter('year', $year)
            ->getQuery()
            ->getArrayResult();
    }

    /**
     * @param int $id
     * @return Judge|null
     */
    public function getJudge(int $id): ?Judge
    {
        /** @var Judge $judge */
        $judge = $this->entityManager->getRepository(Judge::class)->find($id);
        return $judge;
    }

    /**
     * @param $data
     * @return Judge
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function create($data): Judge
    {
        /** @var Judge $judge */
        $judge = $this->hydrator->hydrate($data, new Judge());
        $this->entityManager->persist($judge);
        $this->entityManager->flush();
        return $judge;
    }

    /**
     * @param int $id
     * @param $data
     * @return Judge
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function update(int $id, $data): Judge
    {
        $judge = $this->entityManager->getRepository(Judge::class)->find($id);
        /** @var Judge $judge */
        $judge = $this->hydrator->hydrate($data, $judge);
        $this->entityManager->persist($judge);
        $this->entityManager->flush();
        return $judge;
    }

    /**
     * @param int $id
     * @return bool
     * @throws \Doctrine\ORM\ORMException
     * @throws \Doctrine\ORM\OptimisticLockException
     */
    public function delete(int $id): bool
    {
        if (null !== ($entity = $this->getJudge($id))) {
            $this->entityManager->remove($entity);
            $this->entityManager->flush();
            return true;
        }
        return false;
    }
}
