<?php


namespace Fifa\ConnectId\Sdk\Notifications;

use DateTime;
use Fifa\ConnectId\Sdk\ApiModelValidation\DateOfBirthValidator;
use Fifa\ConnectId\Sdk\ApiModelValidation\DateTimeValidatingParser;
use Fifa\ConnectId\Sdk\MessageHandlers\MessageHandlerInterface;
use Fifa\ConnectId\Sdk\MessageHandlers\MessageHandlersUtil;
use Fifa\ConnectId\Sdk\Registration\ValidationException;
use Fifa\ConnectId\Sdk\Util\Data\Message\ActionType;
use Fifa\ConnectId\Sdk\Util\XmlDeserializer\XmlDeserializer;
use Fifa\ConnectServiceBus\Sdk\Message\Message;

class DateOfBirthChangedMessageHandler implements MessageHandlerInterface
{
    /**
     * @var DateOfBirthChangedNotificationHandlerInterface
     */
    private $dateOfBirthChangedNotificationHandler;
    /**
     * @var XmlDeserializer
     */
    private $xmlDeserializer;

    public function __construct(DateOfBirthChangedNotificationHandlerInterface $dateOfBirthChangedNotificationHandler)
    {
        $this->dateOfBirthChangedNotificationHandler = $dateOfBirthChangedNotificationHandler;
        $this->xmlDeserializer = new XmlDeserializer(DateOfBirthChangedNotificationDto::class, []);
    }

    /**
     * @inheritDoc
     */
    public function canHandle(?string $messageType): bool
    {
        return $messageType == ActionType::DATE_OF_BIRTH_CHANGED_NOTIFICATION;
    }

    /**
     * @inheritDoc
     */
    public function handle(?string $messageType, Message $message)
    {
        /** @var DateOfBirthChangedNotificationDto $dto */
        $dto = MessageHandlingHelper::getDto($message, DateOfBirthChangedNotificationDto::class, $this->xmlDeserializer);
        $operationTimestamp = MessageHandlingHelper::validateAndParse($dto);
        $before = self::validateDateOfBirthAndReturnDateTime($dto->Before, "Before");
        $after = self::validateDateOfBirthAndReturnDateTime($dto->After, "After");

        $notificationData = new DateOfBirthChangedNotification(
            $dto->PersonFIFAId,
            $before,
            $after,
            $dto->ActorName,
            $operationTimestamp);
        $this->dateOfBirthChangedNotificationHandler->execute($notificationData);
    }

    /**
     * @param string $dateOfBirth
     * @param string $validationSubjectName
     * @return DateTime
     * @throws ValidationException
     */
    private static function validateDateOfBirthAndReturnDateTime(string $dateOfBirth, string $validationSubjectName): DateTime
    {
        $dateOfBirthDateTime = DateTimeValidatingParser::parse($dateOfBirth, $validationSubjectName);
        DateOfBirthValidator::validate($dateOfBirthDateTime, $validationSubjectName);
        return $dateOfBirthDateTime;
    }

    /**
     * String representation of the object
     */
    public function __toString()
    {
        return MessageHandlersUtil::FullNameWithMessageType($this, ActionType::DATE_OF_BIRTH_CHANGED_NOTIFICATION);
    }
}