<?php

/*
 * @author TRYDEA - 2024
 */

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

use Mobile\Measure\Entity\Annotation;
use Mobile\Measure\Entity\Variable\RequiredAnnotation;
use Shared\Authentication\Entity\IdentifiedEntity;
use Webapp\FileManagement\Entity\RequestFile;
use Webapp\FileManagement\Exception\ParsingException;
use Webapp\FileManagement\Service\XmlUtils\Normalizer\AbstractXmlNormalizer;
use Webapp\FileManagement\Service\XmlUtils\Normalizer\XmlImportConfig;

/**
 * @template-extends AbstractXmlNormalizer<RequiredAnnotation, RequiredAnnotationXmlDto>
 *
 * @psalm-type RequiredAnnotationXmlDto = array{
 *      "@active": ?bool,
 *      "@avantSaisie": ?bool,
 *      "@nature": ?string,
 *      "@objetMetier": ?IdentifiedEntity,
 *      "@commentaire": ?string,
 *      "@typeUniteParcours": ?string,
 *      "categories": string[],
 *      "motscles": string[],
 * }
 */
class RequiredAnnotationNormalizer extends AbstractXmlNormalizer
{
    protected const TYPE_TEXTE = 'texte';
    protected const TYPE_PHOTO = 'photo';
    protected const TYPE_SON = 'son';

    private const TYPE_MAP = [
        self::TYPE_TEXTE => Annotation::ANNOT_TYPE_TEXT,
        self::TYPE_PHOTO => Annotation::ANNOT_TYPE_IMAG,
        self::TYPE_SON => Annotation::ANNOT_TYPE_SONG,
    ];

    protected const ATTR_OBJET_METIER = '@objetMetier';
    protected const ATTR_NATURE = '@nature';
    protected const ATTR_ACTIVE = '@active';
    protected const ATTR_AVANT_SAISIE = '@avantSaisie';
    protected const ATTR_COMMENTAIRE = '@commentaire';
    protected const ATTR_TYPE_UNITE_PARCOURS = '@typeUniteParcours';
    protected const TAG_CATEGORIES = 'categories';
    protected const TAG_MOTSCLES = 'motscles';

    protected function getClass(): string
    {
        return RequiredAnnotation::class;
    }

    protected function extractData($object, array $context): array
    {
        throw new \LogicException('Method not implemented');
    }

    protected function getImportDataConfig(array $context): array
    {
        return [
            self::ATTR_OBJET_METIER => XmlImportConfig::values(IdentifiedEntity::class),
            self::ATTR_NATURE => 'string',
            self::ATTR_ACTIVE => 'bool',
            self::ATTR_AVANT_SAISIE => 'bool',
        ];
    }

    protected function validateImportData($data, array $context): void
    {
        if (!\in_array($data[self::ATTR_NATURE] ?? self::TYPE_SON, array_keys(self::TYPE_MAP), true)) {
            throw new ParsingException('', RequestFile::ERROR_INCORRECT_ANNOTATION_TYPE);
        }
    }

    protected function generateImportedObject($data, array $context): RequiredAnnotation
    {
        return new RequiredAnnotation();
    }

    protected function completeImportedObject($object, $data, ?string $format, array $context): RequiredAnnotation
    {
        $object
            ->setActive($data[self::ATTR_ACTIVE] ?? false)
            ->setAskWhenEntering($data[self::ATTR_AVANT_SAISIE] ?? false)
            ->setComment($data[self::ATTR_COMMENTAIRE])
            ->setType(self::TYPE_MAP[$data[self::ATTR_NATURE] ?? self::TYPE_SON])
            ->setPathLevel($data[self::ATTR_TYPE_UNITE_PARCOURS] ?? 'Parcelle Unitaire')
            ->setCategory($data[self::TAG_CATEGORIES])
            ->setKeywords($data[self::TAG_MOTSCLES]);

        $idPath = '';
        foreach ($data[self::ATTR_OBJET_METIER] as $businessObject) {
            $idPath .= $businessObject->getUri();
        }
        $object->setBuisnessObjects($idPath);

        return $object;
    }
}
