<?php

/*
 * @author TRYDEA - 2024
 */

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

use Shared\Authentication\Entity\Site;
use Webapp\Core\Entity\OezNature;
use Webapp\FileManagement\Dto\Common\ColorDto;
use Webapp\FileManagement\Service\XmlUtils\Normalizer\AbstractXmlNormalizer;
use Webapp\FileManagement\Service\XmlUtils\Normalizer\PlatformDtoNormalizer;

/**
 * @template-extends AbstractXmlNormalizer<OezNature, OezNatureXmlDto>
 *
 * @psalm-type OezNatureXmlDto = array{
 *      "@couleur": ?int,
 *      "@nom": ?string,
 *      "@texture": null
 * }
 */
class OezNatureNormalizer extends AbstractXmlNormalizer
{
    protected const ATTR_NOM = '@nom';
    protected const ATTR_COULEUR = '@couleur';
    protected const ATTR_TEXTURE = '@texture';

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

    protected function getImportDataConfig(array $context): array
    {
        return [
            self::ATTR_COULEUR => ColorDto::class,
            self::ATTR_NOM => 'string',
            self::ATTR_TEXTURE => 'null',
        ];
    }

    protected function generateImportedObject($data, array $context): OezNature
    {
        /** @var Site|null $site */
        $site = $context[PlatformDtoNormalizer::SITE] ?? null;
        \assert($site instanceof Site);

        // Get site OezNature to check if it is already present.
        $siteNaturesZhe = $site->getOezNatures()->getValues();

        $natureZhe = null;
        foreach ($siteNaturesZhe as $siteNatureZhe) {
            if ($siteNatureZhe->getNature() === $data[self::ATTR_NOM]) {
                $natureZhe = $siteNatureZhe;
                break;
            }
        }
        if (null === $natureZhe) {
            $natureZhe = new OezNature();
            $site->addOezNature($natureZhe);
        }

        return $natureZhe;
    }

    protected function completeImportedObject($object, $data, ?string $format, array $context): OezNature
    {
        if (null !== $object->getId()) {
            // This is an existing OezNature.
            return $object;
        }

        $site = $context[PlatformDtoNormalizer::SITE] ?? null;
        \assert($site instanceof Site);

        $nom = $data[self::ATTR_NOM] ?? '';
        $existing = $site->getOezNatures()->filter(fn (OezNature $oezNature) => $oezNature->getNature() === $nom)->first();
        if (false !== $existing) {
            return $existing;
        }

        $object
            ->setSite($site)
            ->setColor($data[self::ATTR_COULEUR] ?? 0)
            ->setNature($nom)
            ->setTexture(null);

        return $object;
    }

    protected function extractData($object, array $context): array
    {
        return [
            self::ATTR_COULEUR => new ColorDto($object->getColor()),
            self::ATTR_NOM => $object->getNature(),
            self::ATTR_TEXTURE => $object->getTexture(),
        ];
    }
}
