<?php
/**
 * Fichier  : api/analytics.php
 * Version  : 2.6.101
 * Description : API — Intelligence stock : consommation, projections, risques, dormants, KPIs
 * Changelog : v2.6.101 (2026-07-20) — Valorisation par produit dormant et total dédié.
 */
require_once __DIR__.'/../config.php';

requireAuth();
requirePerm('analytics.read');

$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';
if($method !== 'GET') jsonError('Méthode non supportée', 405);

$warehouseId = isset($_GET['warehouseId']) && $_GET['warehouseId']!=='' ? (int)$_GET['warehouseId'] : null;
$windowDays  = isset($_GET['windowDays'])  ? max(7,  (int)$_GET['windowDays'])  : 90;
$horizonDays = isset($_GET['horizonDays']) ? max(7,  (int)$_GET['horizonDays']) : 90;
$top         = isset($_GET['top'])         ? max(5,  (int)$_GET['top'])         : 20;
$dormantDays = isset($_GET['dormantDays']) ? max(30, (int)$_GET['dormantDays']) : 180;

$warehouses = loadData('warehouses');
$products   = loadData('products');

// Top consommés
$consTotals = computeConsumptionTotals($windowDays, $warehouseId);
$topRows = [];
foreach($consTotals as $k=>$qty){
    if($qty <= 0) continue;
    [$wh,$pid] = array_map('intval', explode('|', $k));
    $p = findById($products, $pid);
    if(!$p) continue;
    $topRows[] = [
        'warehouseId'  => $wh,
        'productId'    => $pid,
        'productName'  => (string)($p['name'] ?? ('#'.$pid)),
        'sku'          => (string)($p['sku'] ?? ''),
        'category'     => (string)($p['category'] ?? ''),
        'consumed'     => (float)$qty,
        'windowDays'   => $windowDays,
    ];
}
usort($topRows, fn($a,$b)=>($b['consumed'] <=> $a['consumed']));
$topRows = array_slice($topRows, 0, $top);

// Risques — retourner TOUS les produits actifs (pas seulement top N)
// Le frontend filtre et trie lui-même
$risks = computeRuptureRisks($windowDays, $horizonDays, $warehouseId);

// Dormants avec jours inactifs calculés et valorisation ligne par ligne.
$dormants = computeDormantProducts($dormantDays, $warehouseId);
$canSeePrices = hasPerm('price.read') || hasPerm('valuation.read');
$stockRows = loadData('stock');
$productsById = [];
foreach($products as $product) $productsById[(int)($product['id'] ?? 0)] = $product;

$stockValueByKey = [];
if($canSeePrices){
    foreach($stockRows as $stockRow){
        $pid = (int)($stockRow['productId'] ?? 0);
        $wid = (int)($stockRow['warehouseId'] ?? 0);
        if($warehouseId !== null && $wid !== (int)$warehouseId) continue;
        $product = $productsById[$pid] ?? null;
        if(!$product) continue;

        $baseUnit = normalizeUnit((string)($product['packBaseUnit'] ?? ($product['unitType'] ?? 'piece')));
        $unitType = normalizeUnit((string)($product['unitType'] ?? $baseUnit));
        $cump = (float)($product['cump'] ?? ($product['cost'] ?? 0));
        $explicitBaseCost = null;
        foreach(($product['costByUnit'] ?? []) as $costRow){
            if(!is_array($costRow)) continue;
            if(normalizeUnit((string)($costRow['unit'] ?? '')) === $baseUnit && (float)($costRow['cost'] ?? 0) > 0){
                $explicitBaseCost = (float)$costRow['cost'];
                break;
            }
        }
        $fallbackCost = $explicitBaseCost ?? (($unitType === $baseUnit && $cump > 0) ? $cump : null);
        $rowValue = 0.0;
        $lots = $stockRow['lots'] ?? [];
        if(is_array($lots) && count($lots)){
            foreach($lots as $lot){
                $qty = (float)($lot['quantity'] ?? 0);
                $unitCost = (float)($lot['unitCost'] ?? 0);
                $effectiveCost = $unitCost > 0 ? $unitCost : ($fallbackCost ?? 0);
                if($qty > 0 && $effectiveCost > 0) $rowValue += $qty * $effectiveCost;
            }
        } else {
            $qty = (float)($stockRow['quantity'] ?? 0);
            if($qty > 0 && $fallbackCost !== null && $fallbackCost > 0) $rowValue = $qty * $fallbackCost;
        }
        $key = $wid.'|'.$pid;
        $stockValueByKey[$key] = ($stockValueByKey[$key] ?? 0.0) + $rowValue;
    }
}

$now = time();
$dormantValueTotal = 0.0;
foreach($dormants as &$d){
    $ts = isset($d['lastMovementAt']) && $d['lastMovementAt'] ? strtotime($d['lastMovementAt']) : 0;
    $d['inactiveDays'] = $ts > 0 ? (int)floor(($now - $ts) / 86400) : null;
    $value = $canSeePrices ? round((float)($stockValueByKey[((int)$d['warehouseId']).'|'.((int)$d['productId'])] ?? 0), 2) : null;
    $d['valuation'] = $value;
    $d['unitValue'] = ($value !== null && (float)$d['quantity'] > 0) ? round($value / (float)$d['quantity'], 4) : null;
    if($value !== null) $dormantValueTotal += $value;
}
unset($d);

// Valorisation globale
$valuation = computeStockValuation($warehouseId);
if(!$canSeePrices) $valuation = ['totalValue'=>null,'byWarehouse'=>[]];

// KPIs
$kpi = [
    'windowDays'    => $windowDays,
    'horizonDays'   => $horizonDays,
    'warehouseId'   => $warehouseId,
    'stockValue'    => $valuation['totalValue'],
    'riskCount'     => count(array_filter($risks, fn($r)=>in_array($r['risk'],['attention','alerte','critique'], true))),
    'criticalCount' => count(array_filter($risks, fn($r)=>$r['risk']==='critique')),
    'alertCount'    => count(array_filter($risks, fn($r)=>in_array($r['risk'],['attention','alerte'], true))),
    'dormantCount'  => count($dormants),
    'dormantValue'  => $canSeePrices ? round($dormantValueTotal, 2) : null,
    'activeProducts'=> count(array_filter($risks, fn($r)=>($r['avgDaily']??0)>0)),
];

jsonResponse([
    'kpi'          => $kpi,
    'topConsumed'  => $topRows,
    'ruptureRisks' => $risks,       // tous les produits avec consommation
    'dormants'     => $dormants,
    'valuation'    => $valuation,
    'warehouses'   => $warehouses,
], 200);
