<?php

namespace App\Service;

use App\Entity\NegotiationMessage;
use App\Repository\NegotiationMessage\NegotiationMessageRepositoryInterface;
use App\Service\DataGrid\DataGridInterface;
use Doctrine\ORM\EntityNotFoundException;

final class NegotiationMessageService
{
    /**
     * @var NegotiationMessageRepositoryInterface
     */
    private $repository;

    /**
     * NegotiationMessageService constructor.
     *
     * @param NegotiationMessageRepositoryInterface $repository
     */
    public function __construct(NegotiationMessageRepositoryInterface $repository)
    {
        $this->repository = $repository;
    }

    /**
     * @param int $id
     *
     * @return NegotiationMessage
     *
     * @throws EntityNotFoundException
     */
    public function get(int $id): NegotiationMessage
    {
        $negotiationMessage = $this->repository->findById($id);
        if (!$negotiationMessage) {
            throw new EntityNotFoundException('NegotiationMessage with id '.$id.' does not exist!');
        }

        return $negotiationMessage;
    }

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

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

        if ($dataGrid->getFilters()->containsKey('negotiation') && $dataGrid->getFilters()->get('negotiation')->isValid()) {
            $criteria += ['negotiation' => $dataGrid->getFilters()->get('negotiation')->getValue()];
        }

        if ($dataGrid->getFilters()->containsKey('user') && $dataGrid->getFilters()->get('user')->isValid()) {
            $criteria += ['user' => $dataGrid->getFilters()->get('user')->getValue()];
        }

        if ($dataGrid->getFilters()->containsKey('prospect') && $dataGrid->getFilters()->get('prospect')->isValid()) {
            $criteria += ['prospect' => $dataGrid->getFilters()->get('prospect')->getValue()];
        }

        if ($dataGrid->getFilters()->containsKey('direction') && $dataGrid->getFilters()->get('direction')->isValid()) {
            $criteria += ['direction' => $dataGrid->getFilters()->get('direction')->getValue()];
        }

        return $this->repository->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 countByGrid(DataGridInterface $dataGrid): int
    {
        $criteria = [];
        if ($dataGrid->getFilters()->containsKey('q') && $dataGrid->getFilters()->get('q')->isValid()) {
            $criteria += ['q' => $dataGrid->getFilters()->get('q')->getValue()];
        }

        if ($dataGrid->getFilters()->containsKey('negotiation') && $dataGrid->getFilters()->get('negotiation')->isValid()) {
            $criteria += ['negotiation' => $dataGrid->getFilters()->get('negotiation')->getValue()];
        }

        if ($dataGrid->getFilters()->containsKey('user') && $dataGrid->getFilters()->get('user')->isValid()) {
            $criteria += ['user' => $dataGrid->getFilters()->get('user')->getValue()];
        }

        if ($dataGrid->getFilters()->containsKey('prospect') && $dataGrid->getFilters()->get('prospect')->isValid()) {
            $criteria += ['prospect' => $dataGrid->getFilters()->get('prospect')->getValue()];
        }

        if ($dataGrid->getFilters()->containsKey('direction') && $dataGrid->getFilters()->get('direction')->isValid()) {
            $criteria += ['direction' => $dataGrid->getFilters()->get('direction')->getValue()];
        }

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

    /**
     * @param NegotiationMessage $negotiationMessage
     *
     * @return NegotiationMessage
     */
    public function save(NegotiationMessage $negotiationMessage): NegotiationMessage
    {
        $this->repository->save($negotiationMessage);

        return $negotiationMessage;
    }

    /**
     * @param NegotiationMessage $negotiationMessage
     */
    public function delete(NegotiationMessage $negotiationMessage): void
    {
        $this->repository->delete($negotiationMessage);
    }

    public function moveMessagesBetweenUsers(int $from, int $to)
    {
        return $this->repository->moveMessagesBetweenUsers($from, $to);
    }
}
