<?php

/*
 * @author TRYDEA - 2024
 */

namespace Webapp\FileManagement\Service\XmlUtils\Normalizer\Common;

use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
use Webapp\Core\Enumeration\GraphicalOriginEnum;
use Webapp\FileManagement\Dto\Common\GraphicalStructureDto;
use Webapp\FileManagement\Service\XmlUtils\Normalizer\AbstractXmlNormalizer;

class GraphicalStructureDtoNormalizer implements ContextAwareDenormalizerInterface
{
    private const ORIGIN_BAS_GAUCHE = 'basGauche';
    private const ORIGIN_HAUT_GAUCHE = 'hautGauche';
    private const ORIGIN_BAS_DROITE = 'basDroite';
    private const ORIGIN_HAUT_DROITE = 'hautDroite';

    private const REVERSE_ORIGIN_MAP = [
        self::ORIGIN_BAS_GAUCHE => GraphicalOriginEnum::BOTTOM_LEFT,
        self::ORIGIN_HAUT_GAUCHE => GraphicalOriginEnum::TOP_LEFT,
        self::ORIGIN_HAUT_DROITE => GraphicalOriginEnum::TOP_RIGHT,
        self::ORIGIN_BAS_DROITE => GraphicalOriginEnum::BOTTOM_RIGHT,
    ];

    protected const ATTR_LARGEUR_MAILLE = '@largeurMaille';
    protected const ATTR_HAUTEUR_MAILLE = '@hauteurMaille';
    protected const ATTR_ORIGINE = '@origine';

    public function supportsDenormalization($data, string $type, ?string $format = null, array $context = []): bool
    {
        return GraphicalStructureDto::class === $type && ($context[AbstractXmlNormalizer::IMPORT_XML] ?? false) === true;
    }

    public function denormalize($data, string $type, ?string $format = null, array $context = []): GraphicalStructureDto
    {
        $origine = $data[self::ATTR_ORIGINE] ?? self::ORIGIN_BAS_DROITE;
        $largeur = $data[self::ATTR_LARGEUR_MAILLE] ?? 0;
        $hauteur = $data[self::ATTR_HAUTEUR_MAILLE] ?? 0;
        if (!\is_string($origine)) {
            throw new UnexpectedValueException('origine must be a string');
        }
        if (!is_numeric($largeur)) {
            throw new UnexpectedValueException('largeurMaille must be a numeric');
        }
        if (!is_numeric($hauteur)) {
            throw new UnexpectedValueException('hauteurMaille must be a numeric');
        }
        if (!\in_array($origine, array_keys(self::REVERSE_ORIGIN_MAP), true)) {
            throw new UnexpectedValueException("Unknown origine '$origine'");
        }

        return new GraphicalStructureDto((int) $largeur, (int) $hauteur, self::REVERSE_ORIGIN_MAP[$origine]);
    }
}
