<?php

namespace App\Command;

use App\DTO\KeywordPositionDTO;
use App\Event\KeywordPositionUpdatedEvent;
use App\Integrations\Semrush\Client;
use App\Integrations\Semrush\Requests\GetCampaignReportRequest;
use App\Service\CampaignService;
use DateTime;
use Exception;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

class CrmSemrushReportCommand extends Command
{
    protected static $defaultName = 'crm:semrush:report';
    /**
     * @var CampaignService
     */
    private $campaignService;
    /**
     * @var Client
     */
    private $semrushClient;
    /**
     * @var EventDispatcherInterface
     */
    private $eventDispatcher;

    public function __construct(CampaignService $campaignService, Client $semrushClient, EventDispatcherInterface $eventDispatcher, ?string $name = null)
    {
        parent::__construct($name);
        $this->campaignService = $campaignService;
        $this->semrushClient = $semrushClient;
        $this->eventDispatcher = $eventDispatcher;
    }

    protected function configure()
    {
        $this
            ->setDescription('Get SEMrush report')
            ->addArgument('campaign', InputArgument::REQUIRED, 'Campaign id');
    }

    protected function execute(InputInterface $input, OutputInterface $output): ?int
    {
        $io = new SymfonyStyle($input, $output);
        $campaign = $input->getArgument('campaign');

        try {
            $campaign = $this->campaignService->getCampaign($campaign);
        } catch (Exception $exception) {
            $io->error('Campaign not found ('.$exception->getMessage().')');
        }

        if (null === $campaign->getSemrushId()) {
            $io->error('Campaign is not connected to SEMrush project!');

            return 1;
        }

        $request = (new GetCampaignReportRequest())
            ->setProjectId($campaign->getSemrushId())
            ->setReportUrl($campaign->getDomain()->getUrl());

        $response = $this->semrushClient->execute($request);

        foreach ($response->getBody()['data'] as $keyword) {
            $date = array_keys($keyword['Dt'])[0];
            $dailyPosition = array_values($keyword['Dt'])[0];

            try {
                $reportDate = new DateTime($date);
            } catch (Exception $error) {
                continue;
            }

            $dto = new KeywordPositionDTO(
                $campaign,
                $keyword['Ph'],
                (int) (array_values($dailyPosition))[0],
                $reportDate,
                'n/a' !== $keyword['Cp'] ? $keyword['Cp'] : null,
                'n/a' !== $keyword['Nq'] ? $keyword['Nq'] : null,
                $keyword['Lu'][$date] ? array_values($keyword['Lu'][$date])[0] : null,
                (int) array_values($keyword['Diff'])[0],
                (int) array_values($keyword['Diff1'])[0],
                (int) array_values($keyword['Diff7'])[0],
                (int) array_values($keyword['Diff30'])[0]
            );

            $this->eventDispatcher->dispatch('event.keyword_position_updated', new KeywordPositionUpdatedEvent($dto));
        }
    }
}
