<?php

namespace App\Service;

use App\Entity\Category;
use App\Repository\Category\CategoryRepositoryInterface;
use App\Service\DataGrid\DataGridInterface;
use Doctrine\ORM\EntityNotFoundException;

final class CategoryService
{
    /**
     * @var CategoryRepositoryInterface
     */
    private $categoryRepository;

    /**
     * CategoryService constructor.
     *
     * @param CategoryRepositoryInterface $categoryRepository
     */
    public function __construct(CategoryRepositoryInterface $categoryRepository)
    {
        $this->categoryRepository = $categoryRepository;
    }

    /**
     * @param int $categoryId
     *
     * @return Category
     *
     * @throws EntityNotFoundException
     */
    public function getCategory(int $categoryId): Category
    {
        $category = $this->categoryRepository->findById($categoryId);
        if (!$category) {
            throw new EntityNotFoundException('Category with id '.$categoryId.' does not exist!');
        }

        return $category;
    }

    /**
     * @return array|null
     */
    public function getAllCategories(): ?array
    {
        return $this->categoryRepository->findAll();
    }

    /**
     * @param DataGridInterface $dataGrid
     *
     * @return array|null
     */
    public function getCategoriesByGrid(DataGridInterface $dataGrid): ?array
    {
        $criteria = [];
        if ($dataGrid->getFilters()->containsKey('q') && $dataGrid->getFilters()->get('q')->isValid()) {
            $criteria += ['title' => $dataGrid->getFilters()->get('q')->getValue()];
        }

        return $this->categoryRepository->findBy(
            $criteria,
            [
                $dataGrid->getSorters()->first()->getSort() => $dataGrid->getSorters()->first()->getOrder(),
            ],
            $dataGrid->getNavigation()->getRpp(),
            $dataGrid->getNavigation()->getRpp() * $dataGrid->getNavigation()->getPage());
    }

    /**
     * @param DataGridInterface $dataGrid
     *
     * @return int
     */
    public function countCategoriesByGrid(DataGridInterface $dataGrid): int
    {
        $criteria = [];
        if ($dataGrid->getFilters()->containsKey('q') && $dataGrid->getFilters()->get('q')->isValid()) {
            $criteria += ['title' => $dataGrid->getFilters()->get('q')->getValue()];
        }

        return $this->categoryRepository->count($criteria);
    }

    /**
     * @param Category $category
     *
     * @return Category
     */
    public function saveCategory(Category $category): Category
    {
        $this->categoryRepository->save($category);

        return $category;
    }

    /**
     * @param Category $category
     */
    public function deleteCategory(Category $category): void
    {
        $this->categoryRepository->delete($category);
    }

    /**
     * @param string $title
     *
     * @return Category
     *
     * @throws \Exception
     */
    public function getByTitle(string $title): Category
    {
        if (null === $this->categoryRepository->getByTitle($title)) {
            throw new \Exception('There is no Category with this title');
        }

        return $this->categoryRepository->getByTitle($title);
    }
}
