<?php

declare(strict_types=1);

require_once __DIR__ . '/reporting_init.php';

use Myvetshop\Module\Clinique\Serializer\OrderReportingSerializer;

// Constantes
define('ORDERS_REQUEST_RESULTS_LIMIT', 1000);

// Récupération et vérification sur les paramètres de date (datemin obligatoire)
$dateMin = \DateTimeImmutable::createFromFormat(\DateTimeInterface::ATOM, $_REQUEST['datemin'] ?? '');
$dateMax = \DateTimeImmutable::createFromFormat(\DateTimeInterface::ATOM, $_REQUEST['datemax'] ?? '') ?: new \DateTimeImmutable();

if (
    !$dateMin || $dateMin->format(\DateTimeInterface::ATOM) !== $_REQUEST['datemin']
    || !$dateMax || ($_REQUEST['datemax'] && $dateMax->format(\DateTimeInterface::ATOM) !== $_REQUEST['datemax'])
) {
    header('HTTP/1.1 400 Bad Request');
    echo 'Cannot parse date parameters';
    exit(0);
}

// On limite le nombre de jours pour éviter la surcharge de données
$diff = $dateMin->diff($dateMax);
if ($diff->invert) {
    header('HTTP/1.1 400 Bad Request');
    echo 'datemax have to be later than datemin';
    exit(0);
}
if ($diff->format('%a') > 100) {
    header('HTTP/1.1 400 Bad Request');
    echo 'Cannot get more than 100 days data';
    exit(0);
}

$db = \Db::getInstance();

// Préparation de la requête de récupération des commandes (avec critères de recherche)
$ordersQuery = ' FROM ' . _DB_PREFIX_ . 'orders'
    . ' INNER JOIN ' . _DB_PREFIX_ . 'order_invoice ON ' . _DB_PREFIX_ . 'orders.id_order=' . _DB_PREFIX_ . 'order_invoice.id_order'
    . ' INNER JOIN ' . _DB_PREFIX_ . Clinique::TABLE . ' ON ' . _DB_PREFIX_ . 'orders.id_carrier=' . _DB_PREFIX_ . Clinique::TABLE . '.id_carrier OR ' . _DB_PREFIX_ . 'orders.id_carrier=' . _DB_PREFIX_ . Clinique::TABLE . '.id_carrier_home'
    . ' WHERE ' . _DB_PREFIX_ . 'orders.date_upd >= "' . $dateMin->format('Y-m-d H:i:s') . '"'
    . ' AND ' . _DB_PREFIX_ . 'orders.date_upd <= "' . $dateMax->format('Y-m-d H:i:s') . '"'
    . ' ORDER BY ' . _DB_PREFIX_ . 'orders.invoice_date DESC';

// Compte des commandes trouvées selon les critères de filtres
$ordersCount = (int) $db->getValue('SELECT COUNT(' . _DB_PREFIX_ . 'orders.id_order)' . $ordersQuery, false);

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

for ($i = 0; $i < $ordersCount; $i += ORDERS_REQUEST_RESULTS_LIMIT) {
    // Ajout du séparateur entre les séries de commandes
    if ($i != 0) {
        echo ',';
    }

    // Récupération des commandes
    $orders = $db->executeS(
        'SELECT'
        . ' ' . _DB_PREFIX_ . 'orders.id_order as id'
        . ', ' . _DB_PREFIX_ . 'order_invoice.date_add as invoice_date'
        . ', ' . _DB_PREFIX_ . Clinique::TABLE . '.id_' . Clinique::TABLE . ' as clinic_id'
        . ', ' . _DB_PREFIX_ . Clinique::TABLE . '.centrale as supplier'
        . ', ' . _DB_PREFIX_ . 'orders.current_state as state'
        . ', ' . _DB_PREFIX_ . 'orders.total_products_wt as total_products_wt'
        . ', ' . _DB_PREFIX_ . 'orders.total_paid_tax_incl as total_paid_tax_incl'
        . $ordersQuery
        . ' LIMIT ' . ORDERS_REQUEST_RESULTS_LIMIT . ' OFFSET ' . $i, true, false
    );

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

    // Constitution des listes des ids de commande pour affiner les requêtes suivantes
    $orderIds = \array_unique(\array_map(fn ($o) => $o['id'], $orders));

    $products = $db->executeS(
        'SELECT'
        . ' ' . _DB_PREFIX_ . 'order_detail.id_order as "order_id"'
        . ', ' . _DB_PREFIX_ . 'order_detail.product_name as "name"'
        . ', ' . _DB_PREFIX_ . 'order_detail.product_reference as "reference"'
        . ', ' . _DB_PREFIX_ . 'product_shop.id_category_default as "category_id"'
        . ', ' . _DB_PREFIX_ . 'order_detail.product_quantity as "quantity"'
        . ', ' . _DB_PREFIX_ . 'order_detail.purchase_supplier_price as "purchase_price"'
        . ', ' . _DB_PREFIX_ . 'order_detail.unit_price_tax_excl as "price_tax_excl"'
        . ', ' . _DB_PREFIX_ . 'order_detail.total_price_tax_excl as "total_price_tax_excl"'
        . ', ' . _DB_PREFIX_ . 'order_detail.total_price_tax_incl as "total_price_tax_incl"'
        . ' FROM ' . _DB_PREFIX_ . 'order_detail'
        . ' LEFT JOIN ' . _DB_PREFIX_ . 'product_shop ON ' . _DB_PREFIX_ . 'product_shop.id_product=' . _DB_PREFIX_ . 'order_detail.product_id'
        . ' WHERE ' . _DB_PREFIX_ . 'order_detail.id_order IN (' . implode(', ', $orderIds) . ')',
        true, false
    );
    if (!\is_array($products)) {
        $products = [];
    }

    $discounts = $db->executeS(
        'SELECT'
        . ' ' . _DB_PREFIX_ . 'order_cart_rule.name as "name"'
        . ', ' . _DB_PREFIX_ . 'order_cart_rule.value_tax_excl as "value_tax_excl"'
        . ', ' . _DB_PREFIX_ . 'order_cart_rule.value as "value_tax_incl"'
        . ', ' . _DB_PREFIX_ . 'order_cart_rule.id_order as "order_id"'
        . ' FROM ' . _DB_PREFIX_ . 'order_cart_rule'
        . ' WHERE ' . _DB_PREFIX_ . 'order_cart_rule.id_order IN (' . implode(', ', $orderIds) . ')',
        true, false
    );
    if (!\is_array($discounts)) {
        $discounts = [];
    }

    $refunds = $db->executeS(
        'SELECT'
        . ' ' . _DB_PREFIX_ . 'order_slip.total_products_tax_excl as "total_products_tax_excl"'
        . ', ' . _DB_PREFIX_ . 'order_slip.total_products_tax_incl as "total_products_tax_incl"'
        . ', ' . _DB_PREFIX_ . 'order_slip.total_shipping_tax_excl as "total_shipping_tax_excl"'
        . ', ' . _DB_PREFIX_ . 'order_slip.total_shipping_tax_incl as "total_shipping_tax_incl"'
        . ', ' . _DB_PREFIX_ . 'order_slip.id_order as "order_id"'
        . ' FROM ' . _DB_PREFIX_ . 'order_slip'
        . ' WHERE ' . _DB_PREFIX_ . 'order_slip.id_order IN (' . implode(', ', $orderIds) . ')',
        true, false
    );
    if (!\is_array($refunds)) {
        $refunds = [];
    }

    $orders = OrderReportingSerializer::prepareOrdersArray(
        $orders,
        $products,
        $discounts,
        $refunds,
    );

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

// Fermeture du tableau json
echo ']';
