<?php

declare(strict_types=1);

$headers = getallheaders();

header('Access-Control-Allow-Origin: ' . ($headers['origin'] ?? '*'));
header('Access-Control-Allow-Methods: GET');
header('Access-Control-Allow-Headers: X-Requested-With, Content-Type, Authorization, Origin, Accept');
header('Access-Control-Allow-Credentials: true');

if ('OPTIONS' == $_SERVER['REQUEST_METHOD']) {
    exit(0);
}

ob_start();

require_once __DIR__ . '/../../../../config/config.inc.php';

// Cart is needed for some requests
$context = \Context::getContext();

if (null === $context) {
    header('HTTP/1.1 500 Internal Server Error');
    exit(0);
}

$context->cart = new Cart();
$context->currency = new Currency(1);
$context->cookie->disallowWriting();
Db::getInstance()->disableCache();

// Initialisation du container
global $kernel;
if (!$kernel) {
    require_once _PS_ROOT_DIR_ . '/app/AppKernel.php';
    $kernel = new \AppKernel('prod', false);
    $kernel->boot();
}

// Charement du module clinique
\Module::getInstanceByName('myvetshopclinique');

if (!isset($_SERVER['HTTP_AUTHORIZATION'])) {
    $_SERVER['HTTP_AUTHORIZATION'] = $headers['authorization'] ?? $headers['Authorization'] ?? '';
}

if (isset($_SERVER['HTTP_AUTHORIZATION']) && 0 === \stripos($_SERVER['HTTP_AUTHORIZATION'], 'basic ')) {
    $exploded = \explode(':', \base64_decode(\substr($_SERVER['HTTP_AUTHORIZATION'], 6)), 2);
    if (2 == \count($exploded)) {
        [$code, $apikey] = $exploded;

        $clinique = Clinique::getByCodePrivilege(trim($code));
        if (!$clinique || $clinique->apiKey !== $apikey || $clinique->deleted) {
            \header('HTTP/1.1 403 Forbidden');
            exit(0);
        }
    } else {
        \header('HTTP/1.1 401 Unauthorized');
        exit(0);
    }
} else {
    \header('HTTP/1.1 401 Unauthorized');
    exit(0);
}

// At this point, no more cache
\header('Cache-Control: no-store, no-cache, must-revalidate');
\header('Vary: Authorization');

// Get after
$after = $_GET['after'] ?? 0;
if (!is_numeric($after)) {
    \header('HTTP/1.1 400 Bad Request');
    exit(0);
}
$after = (int) $after;
if ($after < 0) {
    \header('HTTP/1.1 400 Bad Request');
    exit(0);
}

// Get limit

$limit = $_GET['limit'] ?? 500;
if (!is_numeric($limit)) {
    \header('HTTP/1.1 400 Bad Request');
    exit(0);
}
$limit = (int) $limit;
if ($limit < 1 || $limit > 500) {
    \header('HTTP/1.1 400 Bad Request');
    exit(0);
}

$queryBody = 'FROM `' . _DB_PREFIX_ . EstablishmentEvent::TABLE . '` e'
    . ' INNER JOIN `' . _DB_PREFIX_ . Clinique::TABLE . '` c ON c.`id_myvetshop_clinique` = e.`id_myvetshop_clinique`'
    . ' WHERE `c`.`code_privilege` = "{code}"';

$db = \Db::getInstance();
$queryBody = str_replace(
    '{code}',
    $db->escape($clinique->code_privilege),
    $queryBody
);

$globalMaxResultId = $db->getValue('SELECT MAX(e.`id_establishment_event`) ' . $queryBody);

// Add start filtering
$queryBody .= ' AND e.`id_establishment_event` > ' . $after;

// Add limit
$queryBody .= ' ORDER BY e.`id_establishment_event` ASC LIMIT ' . $limit;

// Right now we will return only JSON content
\header('Content-Type: application/json');
$rawResults = $db->executeS('SELECT e.* ' . $queryBody);
if (!\is_array($rawResults)) {
    \header('HTTP/1.1 500 Internal Server Error');
    exit(0);
}
/** @var EstablishmentEvent[] $results */
$results = ObjectModel::hydrateCollection(
    EstablishmentEvent::class,
    $rawResults
);

if (empty($results)) {
    \header('HTTP/1.1 416 Range Not Satisfiable');
    exit(0);
}

$maxResultId = array_reduce(
    $results,
    fn (int $carry, EstablishmentEvent $event): int => (int) \max($carry, $event->id),
    $after + 1
);
\header('Content-Range: events ' . ($after + 1) . '-' . $maxResultId . '/' . (int) $globalMaxResultId);
echo \json_encode(
    \array_map(
        function (EstablishmentEvent $event): array {
            return [
                'id' => $event->id,
                'event' => $event->event,
                'customer' => $event->id_customer ? \json_decode($event->customer_data ?? '', true) : null,
                'order' => $event->id_order ? \json_decode($event->order_data ?? '', true) : null,
            ];
        },
        $results
    )
);
