<?php

namespace App\Service;

use App\Entity\Campaign;
use App\Repository\Campaign\CampaignRepositoryInterface;
use App\Service\DataGrid\DataGridInterface;
use Doctrine\ORM\EntityNotFoundException;
use DomainException;

final class CampaignService
{
    /**
     * @var CampaignRepositoryInterface
     */
    private $campaignRepository;

    /**
     * CampaignService constructor.
     *
     * @param CampaignRepositoryInterface $campaignRepository
     */
    public function __construct(CampaignRepositoryInterface $campaignRepository)
    {
        $this->campaignRepository = $campaignRepository;
    }

    /**
     * @param int $campaignId
     *
     * @return Campaign
     *
     * @throws EntityNotFoundException
     */
    public function getCampaign(int $campaignId): Campaign
    {
        $campaign = $this->campaignRepository->findById($campaignId);
        if (!$campaign) {
            throw new EntityNotFoundException('Campaign with id '.$campaignId.' does not exist!');
        }

        return $campaign;
    }

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

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

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

    /**
     * @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('id') && $dataGrid->getFilters()->get('id')->isValid()) {
            $criteria += ['id' => $dataGrid->getFilters()->get('id')->getValue()];
        }

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

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

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

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

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

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

        return $criteria;
    }

    /**
     * @param DataGridInterface $dataGrid
     *
     * @return int
     */
    public function countCampaignsByGrid(DataGridInterface $dataGrid): int
    {
        $criteria = $this->getCriteria($dataGrid);

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

    /**
     * @param Campaign $campaign
     *
     * @return Campaign
     */
    public function saveCampaign(Campaign $campaign): Campaign
    {
        $this->campaignRepository->save($campaign);

        return $campaign;
    }

    /**
     * @param Campaign $campaign
     *
     * @throws DomainException
     */
    public function delete(Campaign $campaign): void
    {
        if (null !== $campaign->getSemrushId()) {
            throw new DomainException('Campaign connected to Semrush cannot be deleted');
        }

        $this->campaignRepository->delete($campaign);
    }

    public function getByDomain(int $domainId)
    {
        return $this->campaignRepository->findBy(['domain' => [$domainId]]);
    }

    public function findByStatusCakeId(array $array)
    {
        return $this->campaignRepository->findOneBy($array);
    }
}
