<?php

namespace RtmBusiness\PostSync\Serializer;

use DateTime;
use DateTimeInterface;
use RtmBusiness\PostSync\Model\SyncableChild;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

class SyncableChildNormalizer implements NormalizerInterface, DenormalizerInterface
{

    /**
     * Checks if the normalizer supports the given data for normalization.
     *
     * @param mixed $data The data to be normalized.
     * @param string|null $format The format being used for normalization.
     * @return bool True if the data is an instance of SyncableChild, false otherwise.
     */
    public function supportsNormalization(mixed $data, string $format = null): bool
    {
        return $data instanceof SyncableChild;
    }

    /**
     * Normalizes the given object into an array.
     *
     * @param mixed $object The object to be normalized.
     * @param string|null $format The format being used for normalization.
     * @param array $context The normalization context.
     * @return array The normalized data as an array.
     */
    public function normalize(mixed $object, string $format = null, array $context = []): array
    {
        return [
            'blogId' => $object->blogId,
            'postId' => $object->postId,
            'deletedOn' => $object->getDeletedOn()?->format(DATE_ATOM),
            'overwriteSlug' => $object->overwriteSlug,
        ];
    }

    /**
     * Checks if the denormalizer supports the given data for denormalization.
     *
     * @param mixed $data The data to be denormalized.
     * @param string $type The class to which the data should be denormalized.
     * @param string|null $format The format being used for denormalization.
     * @return bool True if the type is SyncableChild::class, false otherwise.
     */
    public function supportsDenormalization(mixed $data, string $type, string $format = null): bool
    {
        return $type === SyncableChild::class;
    }

    /**
     * Denormalizes the given data into a SyncableChild object.
     *
     * @param mixed $data The data to be denormalized.
     * @param string $type The class to which the data should be denormalized.
     * @param string|null $format The format being used for denormalization.
     * @param array $context The denormalization context.
     * @return SyncableChild The denormalized SyncableChild object.
     */
    public function denormalize(mixed $data, string $type, string $format = null, array $context = []): SyncableChild
    {
        $syncableChild = new SyncableChild($data['blogId'], $data['postId']);

        if (isset($data['overwriteSlug'])) {
            $syncableChild->setOverwriteSlug($data['overwriteSlug']);
        }

        if (isset($data['deletedOn'])) {
            $date = DateTime::createFromFormat(DateTimeInterface::ATOM, $data['deletedOn']);
            $syncableChild->setDeletedOn($date);
        }

        return $syncableChild;
    }
}
