<?php

namespace App\MessageHandler;

use App\Entity\Link\Check;
use App\Message\LinkCheckedMessage;
use App\Service\Link\CheckService;
use App\Service\LinkService;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;

final class LinkCheckedMessageHandler implements MessageHandlerInterface
{
    /**
     * @var ValidatorInterface
     */
    private $validator;
    /**
     * @var LinkService
     */
    private $linkService;
    /**
     * @var CheckService
     */
    private $checkService;

    public function __construct(ValidatorInterface $validator, LinkService $linkService, CheckService $checkService)
    {
        $this->validator = $validator;
        $this->linkService = $linkService;
        $this->checkService = $checkService;
    }

    public function __invoke(LinkCheckedMessage $message)
    {
        try {
            $link = $this->linkService->get($message->getLinkId());
        } catch (\Throwable $e) {
            return;
        }

        $errors = $this->validator->validate($message);

        $check = (new Check())
            ->setLink($link)
            ->setStatusCode($message->getStatusCode())
            ->setResponseTime($message->getResponseTime())
            ->setAnchorHref($message->hasHref())
            ->setAnchorText($message->getAnchorText())
            ->setPageAuthority($message->getPageAuthority())
            ->setRelNoFollow($message->hasRelNoFollow());

        if (0 === $errors->count()) {
            $check->setPositive(true);
        } else {
            $check->setPositive(false);
            $check->setOutput($message->getOutput());
        }

        $check = $this->checkService->save($check);

        if (0 === $errors->count()) {
            $link->setStatus('ACTIVE');
            if (null !== $link->getFailCheck()) {
                $link->setFailCheck(null);
            }
        } else {
            $link->setStatus('PROBLEM');
            if (null === $link->getFailCheck()) {
                $link->setFailCheck($check);
            }
        }

        $link->setCheckedAt($message->getTimestamp());
        $this->linkService->save($link);
    }
}
