<?php

declare(strict_types=1);

namespace NoahVet\Reef\Jane\Normalizer;

use Jane\Component\JsonSchemaRuntime\Reference;
use NoahVet\Reef\Jane\Runtime\Normalizer\CheckArray;
use NoahVet\Reef\Jane\Runtime\Normalizer\ValidatorTrait;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerAwareTrait;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

class WebOrderResponseNormalizer implements DenormalizerInterface, NormalizerInterface, DenormalizerAwareInterface, NormalizerAwareInterface
{
    use CheckArray;
    use DenormalizerAwareTrait;
    use NormalizerAwareTrait;
    use ValidatorTrait;

    public function supportsDenormalization(mixed $data, string $type, ?string $format = null, array $context = []): bool
    {
        return \NoahVet\Reef\Jane\Model\WebOrderResponse::class === $type;
    }

    public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool
    {
        return \is_object($data) && \NoahVet\Reef\Jane\Model\WebOrderResponse::class === $data::class;
    }

    public function denormalize(mixed $data, string $type, ?string $format = null, array $context = []): mixed
    {
        if (isset($data['$ref'])) {
            return new Reference($data['$ref'], $context['document-origin']);
        }
        if (isset($data['$recursiveRef'])) {
            return new Reference($data['$recursiveRef'], $context['document-origin']);
        }
        $object = new \NoahVet\Reef\Jane\Model\WebOrderResponse();
        if (\array_key_exists('totalPrice', $data) && \is_int($data['totalPrice'])) {
            $data['totalPrice'] = (float) $data['totalPrice'];
        }
        if (\array_key_exists('totalPaying', $data) && \is_int($data['totalPaying'])) {
            $data['totalPaying'] = (float) $data['totalPaying'];
        }
        if (\array_key_exists('totalYearEndDiscount', $data) && \is_int($data['totalYearEndDiscount'])) {
            $data['totalYearEndDiscount'] = (float) $data['totalYearEndDiscount'];
        }
        if (\array_key_exists('totalDiscount', $data) && \is_int($data['totalDiscount'])) {
            $data['totalDiscount'] = (float) $data['totalDiscount'];
        }
        if (\array_key_exists('totalBankFee', $data) && \is_int($data['totalBankFee'])) {
            $data['totalBankFee'] = (float) $data['totalBankFee'];
        }
        if (\array_key_exists('netPaying', $data) && \is_int($data['netPaying'])) {
            $data['netPaying'] = (float) $data['netPaying'];
        }
        if (\array_key_exists('netYearEndDiscount', $data) && \is_int($data['netYearEndDiscount'])) {
            $data['netYearEndDiscount'] = (float) $data['netYearEndDiscount'];
        }
        if (\array_key_exists('totalPayingDiscount', $data) && \is_int($data['totalPayingDiscount'])) {
            $data['totalPayingDiscount'] = (float) $data['totalPayingDiscount'];
        }
        if (\array_key_exists('totalPayingPatch', $data) && \is_int($data['totalPayingPatch'])) {
            $data['totalPayingPatch'] = (float) $data['totalPayingPatch'];
        }
        if (\array_key_exists('totalYearEndDiscountDiscount', $data) && \is_int($data['totalYearEndDiscountDiscount'])) {
            $data['totalYearEndDiscountDiscount'] = (float) $data['totalYearEndDiscountDiscount'];
        }
        if (\array_key_exists('totalYearEndDiscountPatch', $data) && \is_int($data['totalYearEndDiscountPatch'])) {
            $data['totalYearEndDiscountPatch'] = (float) $data['totalYearEndDiscountPatch'];
        }
        if (\array_key_exists('valuedTotalPrice', $data) && \is_int($data['valuedTotalPrice'])) {
            $data['valuedTotalPrice'] = (float) $data['valuedTotalPrice'];
        }
        if (\array_key_exists('totalPayable', $data) && \is_int($data['totalPayable'])) {
            $data['totalPayable'] = (float) $data['totalPayable'];
        }
        if (\array_key_exists('totalYearEndDiscountable', $data) && \is_int($data['totalYearEndDiscountable'])) {
            $data['totalYearEndDiscountable'] = (float) $data['totalYearEndDiscountable'];
        }
        if (null === $data || false === \is_array($data)) {
            return $object;
        }
        if (\array_key_exists('id', $data)) {
            $object->setId($data['id']);
            unset($data['id']);
        }
        if (\array_key_exists('mvsId', $data)) {
            $object->setMvsId($data['mvsId']);
            unset($data['mvsId']);
        }
        if (\array_key_exists('reference', $data)) {
            $object->setReference($data['reference']);
            unset($data['reference']);
        }
        if (\array_key_exists('invoiceDate', $data)) {
            $object->setInvoiceDate(\DateTime::createFromFormat('Y-m-d\\TH:i:sP', $data['invoiceDate']));
            unset($data['invoiceDate']);
        }
        if (\array_key_exists('state', $data)) {
            $object->setState($data['state']);
            unset($data['state']);
        }
        if (\array_key_exists('supplier', $data)) {
            $object->setSupplier($data['supplier']);
            unset($data['supplier']);
        }
        if (\array_key_exists('establishmentCode', $data)) {
            $object->setEstablishmentCode($data['establishmentCode']);
            unset($data['establishmentCode']);
        }
        if (\array_key_exists('establishmentName', $data)) {
            $object->setEstablishmentName($data['establishmentName']);
            unset($data['establishmentName']);
        }
        if (\array_key_exists('establishmentSupplierCode', $data)) {
            $object->setEstablishmentSupplierCode($data['establishmentSupplierCode']);
            unset($data['establishmentSupplierCode']);
        }
        if (\array_key_exists('totalPrice', $data)) {
            $object->setTotalPrice($data['totalPrice']);
            unset($data['totalPrice']);
        }
        if (\array_key_exists('totalPaying', $data)) {
            $object->setTotalPaying($data['totalPaying']);
            unset($data['totalPaying']);
        }
        if (\array_key_exists('totalYearEndDiscount', $data)) {
            $object->setTotalYearEndDiscount($data['totalYearEndDiscount']);
            unset($data['totalYearEndDiscount']);
        }
        if (\array_key_exists('totalDiscount', $data)) {
            $object->setTotalDiscount($data['totalDiscount']);
            unset($data['totalDiscount']);
        }
        if (\array_key_exists('totalBankFee', $data)) {
            $object->setTotalBankFee($data['totalBankFee']);
            unset($data['totalBankFee']);
        }
        if (\array_key_exists('netPaying', $data)) {
            $object->setNetPaying($data['netPaying']);
            unset($data['netPaying']);
        }
        if (\array_key_exists('netYearEndDiscount', $data)) {
            $object->setNetYearEndDiscount($data['netYearEndDiscount']);
            unset($data['netYearEndDiscount']);
        }
        if (\array_key_exists('veterinaryEstablishmentId', $data) && null !== $data['veterinaryEstablishmentId']) {
            $object->setVeterinaryEstablishmentId($data['veterinaryEstablishmentId']);
            unset($data['veterinaryEstablishmentId']);
        } elseif (\array_key_exists('veterinaryEstablishmentId', $data) && null === $data['veterinaryEstablishmentId']) {
            $object->setVeterinaryEstablishmentId(null);
        }
        if (\array_key_exists('totalPayingDiscount', $data)) {
            $object->setTotalPayingDiscount($data['totalPayingDiscount']);
            unset($data['totalPayingDiscount']);
        }
        if (\array_key_exists('totalPayingPatch', $data)) {
            $object->setTotalPayingPatch($data['totalPayingPatch']);
            unset($data['totalPayingPatch']);
        }
        if (\array_key_exists('totalYearEndDiscountDiscount', $data)) {
            $object->setTotalYearEndDiscountDiscount($data['totalYearEndDiscountDiscount']);
            unset($data['totalYearEndDiscountDiscount']);
        }
        if (\array_key_exists('totalYearEndDiscountPatch', $data)) {
            $object->setTotalYearEndDiscountPatch($data['totalYearEndDiscountPatch']);
            unset($data['totalYearEndDiscountPatch']);
        }
        if (\array_key_exists('valuedTotalPrice', $data)) {
            $object->setValuedTotalPrice($data['valuedTotalPrice']);
            unset($data['valuedTotalPrice']);
        }
        if (\array_key_exists('totalPayable', $data)) {
            $object->setTotalPayable($data['totalPayable']);
            unset($data['totalPayable']);
        }
        if (\array_key_exists('totalYearEndDiscountable', $data)) {
            $object->setTotalYearEndDiscountable($data['totalYearEndDiscountable']);
            unset($data['totalYearEndDiscountable']);
        }
        if (\array_key_exists('products', $data)) {
            $values = [];
            foreach ($data['products'] as $value) {
                $values[] = $this->denormalizer->denormalize($value, \NoahVet\Reef\Jane\Model\WebOrderProductResponse::class, 'json', $context);
            }
            $object->setProducts($values);
            unset($data['products']);
        }
        if (\array_key_exists('discounts', $data)) {
            $values_1 = [];
            foreach ($data['discounts'] as $value_1) {
                $values_1[] = $this->denormalizer->denormalize($value_1, \NoahVet\Reef\Jane\Model\WebOrderDiscountResponse::class, 'json', $context);
            }
            $object->setDiscounts($values_1);
            unset($data['discounts']);
        }
        if (\array_key_exists('payments', $data)) {
            $values_2 = [];
            foreach ($data['payments'] as $value_2) {
                $values_2[] = $this->denormalizer->denormalize($value_2, \NoahVet\Reef\Jane\Model\WebOrderPaymentResponse::class, 'json', $context);
            }
            $object->setPayments($values_2);
            unset($data['payments']);
        }
        if (\array_key_exists('patches', $data)) {
            $values_3 = [];
            foreach ($data['patches'] as $value_3) {
                $values_3[] = $this->denormalizer->denormalize($value_3, \NoahVet\Reef\Jane\Model\WebOrderPatchResponse::class, 'json', $context);
            }
            $object->setPatches($values_3);
            unset($data['patches']);
        }
        foreach ($data as $key => $value_4) {
            if (\preg_match('/.*/', (string) $key)) {
                $object[$key] = $value_4;
            }
        }

        return $object;
    }

    public function normalize(mixed $data, ?string $format = null, array $context = []): array|string|int|float|bool|\ArrayObject|null
    {
        $dataArray = [];
        $dataArray['id'] = $data->getId();
        $dataArray['mvsId'] = $data->getMvsId();
        $dataArray['reference'] = $data->getReference();
        $dataArray['invoiceDate'] = $data->getInvoiceDate()?->format('Y-m-d\\TH:i:sP');
        $dataArray['state'] = $data->getState();
        $dataArray['supplier'] = $data->getSupplier();
        $dataArray['establishmentCode'] = $data->getEstablishmentCode();
        $dataArray['establishmentName'] = $data->getEstablishmentName();
        $dataArray['establishmentSupplierCode'] = $data->getEstablishmentSupplierCode();
        $dataArray['totalPrice'] = $data->getTotalPrice();
        $dataArray['totalPaying'] = $data->getTotalPaying();
        $dataArray['totalYearEndDiscount'] = $data->getTotalYearEndDiscount();
        $dataArray['totalDiscount'] = $data->getTotalDiscount();
        $dataArray['totalBankFee'] = $data->getTotalBankFee();
        $dataArray['netPaying'] = $data->getNetPaying();
        $dataArray['netYearEndDiscount'] = $data->getNetYearEndDiscount();
        $dataArray['veterinaryEstablishmentId'] = $data->getVeterinaryEstablishmentId();
        $dataArray['totalPayingDiscount'] = $data->getTotalPayingDiscount();
        $dataArray['totalPayingPatch'] = $data->getTotalPayingPatch();
        $dataArray['totalYearEndDiscountDiscount'] = $data->getTotalYearEndDiscountDiscount();
        $dataArray['totalYearEndDiscountPatch'] = $data->getTotalYearEndDiscountPatch();
        $dataArray['valuedTotalPrice'] = $data->getValuedTotalPrice();
        $dataArray['totalPayable'] = $data->getTotalPayable();
        $dataArray['totalYearEndDiscountable'] = $data->getTotalYearEndDiscountable();
        $values = [];
        foreach ($data->getProducts() as $value) {
            $values[] = $this->normalizer->normalize($value, 'json', $context);
        }
        $dataArray['products'] = $values;
        $values_1 = [];
        foreach ($data->getDiscounts() as $value_1) {
            $values_1[] = $this->normalizer->normalize($value_1, 'json', $context);
        }
        $dataArray['discounts'] = $values_1;
        $values_2 = [];
        foreach ($data->getPayments() as $value_2) {
            $values_2[] = $this->normalizer->normalize($value_2, 'json', $context);
        }
        $dataArray['payments'] = $values_2;
        $values_3 = [];
        foreach ($data->getPatches() as $value_3) {
            $values_3[] = $this->normalizer->normalize($value_3, 'json', $context);
        }
        $dataArray['patches'] = $values_3;
        foreach ($data as $key => $value_4) {
            if (\preg_match('/.*/', (string) $key)) {
                $dataArray[$key] = $value_4;
            }
        }

        return $dataArray;
    }

    public function getSupportedTypes(?string $format = null): array
    {
        return [\NoahVet\Reef\Jane\Model\WebOrderResponse::class => false];
    }
}
