<?php

namespace App\Service;

use App\Entity\Link;
use App\Repository\Link\LinkRepositoryInterface;
use App\Service\DataGrid\DataGridInterface;
use Doctrine\ORM\EntityNotFoundException;

final class LinkService
{
    /**
     * @var LinkRepositoryInterface
     */
    private $repository;

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

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

        return $link;
    }

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

    /**
     * @return array|null
     */
    public function getByGrid(DataGridInterface $dataGrid): ?array
    {
        $criteria = $this->getCriteria($dataGrid);

        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 = $this->getCriteria($dataGrid);

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

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

        return $link;
    }

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

    /**
     * @param DataGridInterface $dataGrid
     *
     * @return array
     */
    private function getCriteria(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('campaign') && $dataGrid->getFilters()->get('campaign')->isValid()) {
            $criteria += ['campaign' => $dataGrid->getFilters()->get('campaign')->getValue()];
        }

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

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

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

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

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

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

        return $criteria;
    }

    public function getLinksByIpFrom(string $ip)
    {
        return $this->repository->findBy(['ipFrom' => $ip]);
    }

    public function getLinksByIpTo(string $ip)
    {
        return $this->repository->findBy(['ipTo' => $ip]);
    }

    public function getByProspect(array $prospectIds)
    {
        return $this->repository->findBy(['prospect' => $prospectIds]);
    }

    public function getByCampaign(array $campaignIds)
    {
        return $this->repository->findBy(['campaign' => $campaignIds]);
    }

    public function getFirstCreatedAt(): ?string
    {
        return $this->repository->getFirstCreatedAt();
    }
}
