<?php

/*
 * @author TRYDEA - 2024
 */

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

use Doctrine\Common\Collections\Collection;
use Mobile\Device\Entity\EntryNote;
use Mobile\Device\Entity\OutExperimentationZone;
use Mobile\Device\Entity\SubBlock;
use Mobile\Device\Entity\UnitParcel;
use Webapp\FileManagement\Dto\Mobile\AnnotationDto;
use Webapp\FileManagement\Service\XmlUtils\Normalizer\AbstractXmlNormalizer;
use Webapp\FileManagement\Service\XmlUtils\Normalizer\XmlImportConfig;

/**
 * @template-extends AbstractXmlNormalizer<SubBlock, SubBlockXmlDto>
 *
 * @psalm-type SubBlockXmlDto = array{
 *      "@numero": ?string,
 *      notes: Collection<int, EntryNote>,
 *      parcellesUnitaire: Collection<int, UnitParcel>,
 *      zheAvecEpaisseurs: Collection<int, OutExperimentationZone>
 * }
 */
class SubBlockNormalizer extends AbstractXmlNormalizer
{
    protected const ATTR_NUMERO = '@numero';
    protected const TAG_ZHE_AVEC_EPAISSEURS = 'zheAvecEpaisseurs';
    protected const TAG_PARCELLES_UNITAIRE = 'parcellesUnitaire';
    protected const TAG_NOTES = 'notes';
    protected const TAG_METADONNEES = 'metadonnees';

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

    protected function extractData($object, array $context): array
    {
        $parcellesUnitaires = [];
        $outExperimentationZones = $object->getOutExperimentationZones();
        foreach ($object->getUnitParcels() as $unitParcel) {
            if (null === $unitParcel->getTreatment()) {
                // Case when the unit parcel comes from a treatment error
                foreach ($unitParcel->getOutExperimentationZones() as $outExperimentationZone) {
                    $outExperimentationZones[] = $outExperimentationZone;
                }
            } else {
                $parcellesUnitaires[] = $unitParcel;
            }
        }

        self::getWriterHelper($context)->addSessionAnnotations(AnnotationDto::fromCollection($object->getAnnotations(), $object));

        return [
            self::ATTR_NUMERO => $object->getName(),
            self::TAG_PARCELLES_UNITAIRE => $parcellesUnitaires,
            self::TAG_ZHE_AVEC_EPAISSEURS => $outExperimentationZones,
            self::TAG_NOTES => $object->getNotes(),
        ];
    }

    protected function getImportDataConfig(array $context): array
    {
        return [
            self::ATTR_NUMERO => 'string',
            self::TAG_ZHE_AVEC_EPAISSEURS => XmlImportConfig::collection(OutExperimentationZone::class),
            self::TAG_PARCELLES_UNITAIRE => XmlImportConfig::collection(UnitParcel::class),
            self::TAG_NOTES => XmlImportConfig::collection(EntryNote::class),
        ];
    }

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

    protected function completeImportedObject($object, $data, ?string $format, array $context): SubBlock
    {
        $object
            ->setOutExperimentationZones($data[self::TAG_ZHE_AVEC_EPAISSEURS])
            ->setUnitParcels($data[self::TAG_PARCELLES_UNITAIRE])
            ->setNotes($data[self::TAG_NOTES])
            ->setName($data[self::ATTR_NUMERO] ?? '0');

        return $object;
    }
}
