<?php
/**
 * Fichier  : api/reservations.php
 * Auteur   : KREMER Régis
 * Version  : 2.4.0
 * Date     : 2026-02-26
 * Description : API REST — Réservations de stock (Lot 4)
 */
require_once dirname(__DIR__).'/config.php';
startSession(); requireAuth();

$method = $_SERVER['REQUEST_METHOD'];
if($method === 'GET') {
    requirePerm('reservations.read');
} else {
    requirePerm('reservations.manage');
    csrfCheck();
}

$body = json_decode(file_get_contents('php://input'), true) ?? [];

// getReservedQty() is now defined in config.php (shared with movements.php)

switch($method){
case 'GET':
    $items = loadData('reservations');
    $pid = (int)($_GET['productId'] ?? 0);
    $wid = (int)($_GET['warehouseId'] ?? 0);
    $status = $_GET['status'] ?? '';
    if($pid>0) $items = array_filter($items, fn($r)=>(int)($r['productId']??0)===$pid);
    if($wid>0) $items = array_filter($items, fn($r)=>(int)($r['warehouseId']??0)===$wid);
    if($status) $items = array_filter($items, fn($r)=>(string)($r['status']??'active')===(string)$status);
    jsonResponse(array_values($items));

case 'POST':
    $pid = (int)($body['productId'] ?? 0);
    $wid = (int)($body['warehouseId'] ?? 0);
    $loc = (string)($body['locationId'] ?? 'default');
    $qty = (float)($body['qty'] ?? 0);
    $unit = normalizeUnit((string)($body['unit'] ?? 'piece'));
    if($pid<=0 || $wid<=0) jsonError('Produit/Magasin obligatoire.');
    if($qty<=0) jsonError('Quantité invalide.');

    $p = findById(loadData('products'), $pid);
    if(!$p) jsonError('Produit introuvable.',404);
    if(!userCanAccessWarehouse($wid)) jsonError('Accès magasin interdit.',403);

    $baseQty = toBaseQuantity($p, $unit, $qty);

    // Available check (fail-soft) — does not modify stock, only prevents obvious overbooking
    $entry = null;
    foreach(loadData('stock') as $s){
        if((int)($s['productId']??0)===$pid && (int)($s['warehouseId']??0)===$wid){ $entry=$s; break; }
    }
    $available = (float)($entry['quantity'] ?? 0);
    $reserved = getReservedQty($pid,$wid,null);
    if($baseQty > max(0,$available - $reserved)){
        jsonError('Stock insuffisant pour réserver (stock disponible tenant compte des réservations).');
    }

    $item = addItem('reservations', [
        'productId' => $pid,
        'warehouseId' => $wid,
        'locationId' => $loc,
        'qty' => $qty,
        'unit' => $unit,
        'baseQty' => $baseQty,
        'label' => trim((string)($body['label'] ?? '')),
        'worksite' => trim((string)($body['worksite'] ?? '')),
        'status' => 'active',
        'createdBy' => (currentUser()['id'] ?? null),
    ]);
    jsonResponse($item,201);

case 'PUT':
    $id = $body['id'] ?? null;
    if(!$id) jsonError('ID manquant.');
    $items = loadData('reservations');
    $r = findById($items, $id);
    if(!$r) jsonError('Non trouvé.',404);

    $fields = [];
    if(array_key_exists('status',$body)){
        $st = (string)$body['status'];
        if(!in_array($st,['active','released','canceled'],true)) jsonError('Statut invalide.');
        $fields['status'] = $st;
    }
    if(array_key_exists('label',$body)) $fields['label'] = trim((string)$body['label']);
    if(array_key_exists('worksite',$body)) $fields['worksite'] = trim((string)$body['worksite']);
    $fields['updatedBy'] = (currentUser()['id'] ?? null);

    $up = updateItem('reservations', $id, $fields);
    $up ? jsonResponse($up) : jsonError('Non trouvé.',404);

case 'DELETE':
    $id = $_GET['id'] ?? null;
    if(!$id) jsonError('ID manquant.');
    deleteItem('reservations', $id);
    jsonResponse(['ok'=>true]);

default:
    jsonError('Méthode non supportée',405);
}
