<?php

declare(strict_types=1);

use Myvetshop\Module\Clinique\Serializer\DiscountReportingSerializer;

require_once __DIR__ . '/reporting_init.php';

// Constantes
const RESULTS_LIMIT = 1000;
const RETURN_LIMIT = 5000;

$db = Db::getInstance();

$query = ' FROM ' . _DB_PREFIX_ . 'cart_rule cr'
    . ' INNER JOIN ' . _DB_PREFIX_ . 'cart_rule_lang crl ON crl.id_cart_rule=cr.id_cart_rule AND crl.id_lang=1'
;

// Compte des promos
$count = (int) $db->getValue('SELECT COUNT(cr.id_cart_rule)' . $query, false);

// Gestion de la pagination
$rangeStart = (int) $_REQUEST['page'] * RETURN_LIMIT;
$rangeEnd = \min($rangeStart + RETURN_LIMIT, $count) - 1;
\header(\sprintf('Content-Range: items %u-%u/%u', $rangeStart, $rangeEnd, $count));

// Préparation du retour
$serializer = new DiscountReportingSerializer();
echo '[';

for ($i = $rangeStart; $i < $rangeEnd; $i += RESULTS_LIMIT) {
    // Ajout du séparateur entre les lots de données
    if ($i != $rangeStart) {
        echo ',';
    }

    // Récupération des données
    $discounts = $db->executeS(
        'SELECT cr.id_cart_rule as id, cr.code as code, crl.name as name'
        . $query
        . ' LIMIT ' . RESULTS_LIMIT . ' OFFSET ' . $i
    );

    if (!\is_array($discounts)) {
        $discounts = [];
    }

    $discountIds = \array_unique(\array_map(fn ($d) => $d['id'], $discounts));

    $products = $db->executeS(
        'SELECT'
        . ' p.id_product as "id"'
        . ', pl.name as "name"'
        . ', s.id_category_default as "category_id"'
        . ', p.id_manufacturer as "manufacturer_id"'
        . ', crg.id_cart_rule as "discount_id"'
        . ' FROM ' . _DB_PREFIX_ . 'cart_rule_product_rule_group crg'
        . ' INNER JOIN ' . _DB_PREFIX_ . 'cart_rule_product_rule crp ON crp.id_product_rule_group=crg.id_product_rule_group AND crp.type="products"'
        . ' INNER JOIN ' . _DB_PREFIX_ . 'cart_rule_product_rule_value crv ON crv.id_product_rule=crp.id_product_rule'

        // Infos du produit
        . ' INNER JOIN ' . _DB_PREFIX_ . 'product p ON p.id_product=crv.id_item'
        . ' INNER JOIN ' . _DB_PREFIX_ . 'product_lang pl ON pl.id_product=p.id_product AND pl.id_lang=1 AND pl.id_shop=1'
        . ' LEFT JOIN ' . _DB_PREFIX_ . 'product_shop s ON s.id_product=p.id_product AND s.id_shop=1'

        . ' WHERE crg.id_cart_rule IN (' . implode(', ', $discountIds) . ')'
    );

    if (!\is_array($products)) {
        $products = [];
    }

    $discountProducts = \array_reduce($products, function ($carry, $product) {
        // Suppression de l'id de commande inutile
        $discountId = $product['discount_id'];
        unset($product['discount_id']);

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

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

        return $carry;
    }, []);

    foreach ($discounts as &$discount) {
        $discount['products'] = \array_key_exists($discount['id'], $discountProducts) ? $discountProducts[$discount['id']] : [];
    }

    echo trim($serializer->serialize($discounts), '[]');
}

// Fermeture du tableau json
echo ']';
