<?php

namespace App\Command;

use App\Service\CitationFlowChecker;
use App\Service\DomainAuthorityChecker;
use App\Service\DomainService;
use App\Service\PageAuthorityChecker;
use App\Service\StatsProcessor;
use App\Service\TrustFlowChecker;
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;

class CrmDomainCheckCommand extends Command
{
    protected static $defaultName = 'crm:domain:check';
    private $domainService;
    private $processor;
    private $checker;
    /**
     * @var PageAuthorityChecker
     */
    private $pageAuthorityChecker;
    /**
     * @var TrustFlowChecker
     */
    private $trustFlowChecker;
    /**
     * @var CitationFlowChecker
     */
    private $citationFlowChecker;

    public function __construct(DomainService $domainService, StatsProcessor $processor, DomainAuthorityChecker $checker, PageAuthorityChecker $pageAuthorityChecker, TrustFlowChecker $trustFlowChecker, CitationFlowChecker $citationFlowChecker, ?string $name = null)
    {
        parent::__construct($name);
        $this->domainService = $domainService;
        $this->processor = $processor;
        $this->checker = $checker;
        $this->pageAuthorityChecker = $pageAuthorityChecker;
        $this->trustFlowChecker = $trustFlowChecker;
        $this->citationFlowChecker = $citationFlowChecker;
    }

    protected function configure()
    {
        $this
            ->setDescription('Update Domain Stats')
            ->addArgument('domainId', InputArgument::REQUIRED, 'Id of a Domain to check');
    }

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

        if ($domainId) {
            $io->note(sprintf('You passed an argument: %s', $domainId));
        }

        try {
            $domainEntity = $this->domainService->getDomain($domainId);
        } catch (\Exception $exception) {
            $io->error('Domain not found ('.$exception->getMessage().')');

            return null;
        }

        $this->processor->setDomain($domainEntity->getUrl());
        $this->processor->setDomainId($domainEntity->getId());

        foreach ($domainEntity->getStats() as $stat) {
            switch ($stat->getStat()->getSymbol()) {
                case 'DA':
                    $this->processor->addChecker($this->checker);

                    break;
                case 'PA':
                    $this->processor->addChecker($this->pageAuthorityChecker);

                    break;
                case 'TF':
                    $this->processor->addChecker($this->trustFlowChecker);

                    break;
                case 'CF':
                    $this->processor->addChecker($this->citationFlowChecker);

                    break;
                default:
                    break;
            }
        }

        try {
            $this->processor->process();
        } catch (\Throwable $e) {
            $io->getErrorStyle()->warning($e->getMessage());

            return 1;
        }

        return 0;
    }
}
