<?php

/*
 * @author TRYDEA - 2024
 */

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

use Webapp\Core\Entity\RequiredAnnotation;
use Webapp\Core\Enumeration\PathLevelEnum;
use Webapp\FileManagement\Entity\RequestFile;
use Webapp\FileManagement\Exception\ParsingException;
use Webapp\FileManagement\Service\XmlUtils\Normalizer\AbstractXmlNormalizer;

/**
 * @template-extends AbstractXmlNormalizer<RequiredAnnotation, RequiredAnnotationXmlDto>
 *
 * @psalm-type RequiredAnnotationXmlDto =array{
 *      "@avantSaisie": ?bool,
 *      "@commentaire": ?string,
 *      "@nature": ?string,
 *      "@typeUniteParcours": ?string
 * }
 */
class RequiredAnnotationNormalizer extends AbstractXmlNormalizer
{
    protected const ATTR_AVANT_SAISIE = '@avantSaisie';
    protected const ATTR_COMMENTAIRE = '@commentaire';
    protected const ATTR_NATURE = '@nature';
    protected const ATTR_TYPE_UNITE_PARCOURS = '@typeUniteParcours';

    protected const LEVEL_PARCEL = 'parcelle';
    protected const LEVEL_BLOCK = 'bloc';
    protected const LEVEL_SUB_BLOCK = 'sousBloc';
    protected const LEVEL_EXPERIMENT = 'dispositif';
    protected const LEVEL_PLATEFORM = 'plateforme';
    protected const LEVEL_INDIVIDUAL = 'individu';

    protected const REVERSE_UNITE_PARCOURS_MAP = [
        self::LEVEL_PARCEL => PathLevelEnum::UNIT_PLOT,
        self::LEVEL_BLOCK => PathLevelEnum::BLOCK,
        self::LEVEL_SUB_BLOCK => PathLevelEnum::SUB_BLOCK,
        self::LEVEL_EXPERIMENT => PathLevelEnum::EXPERIMENT,
        self::LEVEL_PLATEFORM => PathLevelEnum::PLATFORM,
        self::LEVEL_INDIVIDUAL => PathLevelEnum::INDIVIDUAL,
    ];

    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_AVANT_SAISIE => 'bool',
            self::ATTR_COMMENTAIRE => 'string',
            self::ATTR_NATURE => 'string',
            self::ATTR_TYPE_UNITE_PARCOURS => 'string',
        ];
    }

    protected function validateImportData($data, array $context): void
    {
        if (isset($data[self::ATTR_NATURE]) && !\in_array($data[self::ATTR_NATURE], array_keys(AnnotationNormalizer::REVERSE_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
            ->setAskWhenEntering($data[self::ATTR_AVANT_SAISIE] ?? false)
            ->setComment($data[self::ATTR_COMMENTAIRE] ?? '')
            ->setType(AnnotationNormalizer::REVERSE_TYPE_MAP[$data[self::ATTR_NATURE] ?? AnnotationNormalizer::TYPE_SON])
            ->setLevel(self::REVERSE_UNITE_PARCOURS_MAP[$data[self::ATTR_TYPE_UNITE_PARCOURS] ?? self::LEVEL_PARCEL]);

        return $object;
    }
}
