<?php

declare(strict_types=1);

namespace Myvetshop\Module\Clinique\Serializer;

use Myvetshop\Module\Clinique\Generated\Jane\Reporting\Model\OrdersGetResponse200Item;
use Myvetshop\Module\Clinique\Generated\Jane\Reporting\Normalizer\OrdersGetResponse200ItemDiscountsItemNormalizer;
use Myvetshop\Module\Clinique\Generated\Jane\Reporting\Normalizer\OrdersGetResponse200ItemNormalizer;
use Myvetshop\Module\Clinique\Generated\Jane\Reporting\Normalizer\OrdersGetResponse200ItemProductsItemNormalizer;
use Myvetshop\Module\Clinique\Generated\Jane\Reporting\Normalizer\OrdersGetResponse200ItemRefundsItemNormalizer;

/**
 * @extends AbstractReportingSerializer<OrdersGetResponse200Item>
 */
class OrderReportingSerializer extends AbstractReportingSerializer
{
    public static function getNormalizers(): array
    {
        return [
            new OrdersGetResponse200ItemNormalizer(),
            new OrdersGetResponse200ItemProductsItemNormalizer(),
            new OrdersGetResponse200ItemDiscountsItemNormalizer(),
            new OrdersGetResponse200ItemRefundsItemNormalizer(),
        ];
    }

    public static function getModelClass(): string
    {
        return OrdersGetResponse200Item::class;
    }

    /**
     * @param array<string, string|int>[] $orders
     * @param array<string, string|int>[] $products
     * @param array<string, string>[] $discounts
     * @param array<string, string>[] $refunds
     *
     * @return array<string, mixed>[]
     */
    public static function prepareOrdersArray(array $orders, array $products, array $discounts, array $refunds): array
    {
        $orderElements = ['products' => $products, 'discounts' => $discounts, 'refunds' => $refunds];

        foreach ($orderElements as $name => $elements) {
            $orderElements[$name] = \array_reduce($elements, function (array $carry, array $element) {
                // Suppression de l'id de commande inutile
                $orderId = $element['order_id'];
                unset($element['order_id']);

                // Création de la liste des éléments pour la commande concernée si elle n'existe pas
                if (!\array_key_exists($orderId, $carry)) {
                    $carry[$orderId] = [];
                }

                // Ajout de l'élément à la liste
                $carry[$orderId][] = $element;

                return $carry;
            }, []);
        }

        foreach ($orders as &$order) {
            $dt = \DateTimeImmutable::createFromFormat('Y-m-d H:i:s', (string) $order['invoice_date']);
            \assert($dt instanceof \DateTimeImmutable);
            $order['invoice_date'] = $dt->format(\DateTimeInterface::ATOM);

            // Ajout des éléments
            foreach ($orderElements as $name => $elements) {
                $order[$name] = \array_key_exists($order['id'], $elements) ? $elements[$order['id']] : [];
            }
        }

        return $orders;
    }
}
