<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; }

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

// ── Verificar token admin ─────────────────────────────────────────────────────
$headers    = getallheaders();
$authHeader = $headers['Authorization'] ?? $headers['authorization'] ?? '';
$token      = str_replace('Bearer ', '', $authHeader);
if (empty($token)) {
    http_response_code(401);
    echo json_encode(['success' => false, 'message' => 'Token requerido']);
    exit;
}

$db  = getDB();
$now = date('Y-m-d H:i:s');
$stmtSess = $db->prepare(
    "SELECT s.idusuarios_sist FROM admin_sessions s
     WHERE s.token = ? AND s.expira > ? LIMIT 1"
);
$stmtSess->execute([$token, $now]);
if (!$stmtSess->fetch()) {
    http_response_code(401);
    echo json_encode(['success' => false, 'message' => 'Sesión inválida']);
    exit;
}

// ── POST: Ajuste manual de stock ──────────────────────────────────────────────
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $body  = json_decode(file_get_contents('php://input'), true);
    $ajuste = $body['ajuste'] ?? null;
    if (!$ajuste || !isset($ajuste['idcd'], $ajuste['idprod'], $ajuste['cantidad'])) {
        http_response_code(400);
        echo json_encode(['success' => false, 'message' => 'Datos de ajuste incompletos']);
        exit;
    }
    $idcd     = (int)$ajuste['idcd'];
    $idprod   = (int)$ajuste['idprod'];
    $cantidad = (int)$ajuste['cantidad'];

    // Actualizar o insertar en stock
    $stmtCheck = $db->prepare("SELECT idstock FROM stock WHERE idcd = ? AND idprod = ?");
    $stmtCheck->execute([$idcd, $idprod]);
    $existing = $stmtCheck->fetch(PDO::FETCH_ASSOC);
    if ($existing) {
        $db->prepare("UPDATE stock SET cantidad = ? WHERE idcd = ? AND idprod = ?")
           ->execute([$cantidad, $idcd, $idprod]);
    } else {
        $db->prepare("INSERT INTO stock (idcd, idprod, cantidad) VALUES (?, ?, ?)")
           ->execute([$idcd, $idprod, $cantidad]);
    }

    // Registrar en cambiostock
    $db->prepare("
        INSERT INTO cambiostock (centro, cant_mov, prod1, quitado, prod2, agregado, fecha, hora)
        VALUES (?, ?, ?, 0, 0, 0, CURDATE(), CURTIME())
    ")->execute([$idcd, $cantidad, $idprod]);

    echo json_encode(['success' => true, 'message' => 'Stock ajustado correctamente']);
    exit;
}

// ── GET: Calcular diferencias ─────────────────────────────────────────────────
$centroFiltro = isset($_GET['centro']) ? (int)$_GET['centro'] : -1;

// Stock real actual
$whereReal = $centroFiltro >= 0 ? "WHERE s.idcd = {$centroFiltro}" : "";
$stockReal = $db->query("
    SELECT s.idcd, s.idprod, s.cantidad,
           p.nombreProd, p.presentacion,
           uc.nombre AS nombre_centro
    FROM stock s
    JOIN productos p ON p.id_prod = s.idprod
    LEFT JOIN usuarios_ci uc ON uc.idusuarios_ci = s.idcd
    {$whereReal}
")->fetchAll(PDO::FETCH_ASSOC);

// Construir mapa de stock real: [idcd][idprod] = cantidad
$realMap = [];
foreach ($stockReal as $row) {
    $realMap[(int)$row['idcd']][(int)$row['idprod']] = [
        'cantidad'      => (int)$row['cantidad'],
        'nombre_prod'   => $row['nombreProd'],
        'presentacion'  => $row['presentacion'],
        'nombre_centro' => $row['nombre_centro'] ?? ($row['idcd'] == 0 ? 'Almacén Principal' : "Centro {$row['idcd']}"),
    ];
}

// Entradas tipo 20 (recepción en almacén principal idcd=0)
$entradas20 = $db->query("
    SELECT 0 AS idcd, p.productos_idprod AS idprod, SUM(p.cant) AS total
    FROM transacciones t
    JOIN pedido p ON p.transacciones_idtransacciones = t.idtransacciones
    WHERE t.tipostr_idtipostr = 20 AND t.statusentrega = 'ENTREGADO'
    GROUP BY p.productos_idprod
")->fetchAll(PDO::FETCH_ASSOC);

// Transferencias recibidas (tipo 5, ENTREGADO): suma al cdentrega
$transfsRecibidas = $db->query("
    SELECT t.cdentrega AS idcd, p.productos_idprod AS idprod, SUM(p.cant) AS total
    FROM transacciones t
    JOIN pedido p ON p.transacciones_idtransacciones = t.idtransacciones
    WHERE t.tipostr_idtipostr = 5 AND t.statusentrega = 'ENTREGADO'
    GROUP BY t.cdentrega, p.productos_idprod
")->fetchAll(PDO::FETCH_ASSOC);

// Transferencias enviadas (tipo 5): resta del origen
$transfsEnviadas = $db->query("
    SELECT t.usuarios_ci_idusuarios_ci AS idcd, p.productos_idprod AS idprod, SUM(p.cant) AS total
    FROM transacciones t
    JOIN pedido p ON p.transacciones_idtransacciones = t.idtransacciones
    WHERE t.tipostr_idtipostr = 5
    GROUP BY t.usuarios_ci_idusuarios_ci, p.productos_idprod
")->fetchAll(PDO::FETCH_ASSOC);

// Ventas entregadas (tipos 6, 10, 11): resta del cdentrega
$ventasEntregadas = $db->query("
    SELECT t.cdentrega AS idcd, p.productos_idprod AS idprod, SUM(p.cant) AS total
    FROM transacciones t
    JOIN pedido p ON p.transacciones_idtransacciones = t.idtransacciones
    WHERE t.tipostr_idtipostr IN (6, 10, 11)
      AND t.statusentrega IN ('ENTREGADO', 'EMPACADO')
    GROUP BY t.cdentrega, p.productos_idprod
")->fetchAll(PDO::FETCH_ASSOC);

// Construir mapa calculado
$calcMap = [];
$addToCalc = function($rows, $sign) use (&$calcMap) {
    foreach ($rows as $row) {
        $idcd   = (int)$row['idcd'];
        $idprod = (int)$row['idprod'];
        if (!isset($calcMap[$idcd][$idprod])) $calcMap[$idcd][$idprod] = 0;
        $calcMap[$idcd][$idprod] += $sign * (int)$row['total'];
    }
};
$addToCalc($entradas20,       +1);
$addToCalc($transfsRecibidas, +1);
$addToCalc($transfsEnviadas,  -1);
$addToCalc($ventasEntregadas, -1);

// ── Comparar real vs calculado ────────────────────────────────────────────────
$diferencias = [];
$allKeys = [];
foreach ($realMap as $idcd => $prods) {
    foreach ($prods as $idprod => $_) $allKeys[$idcd][$idprod] = true;
}
foreach ($calcMap as $idcd => $prods) {
    foreach ($prods as $idprod => $_) $allKeys[$idcd][$idprod] = true;
}

foreach ($allKeys as $idcd => $prods) {
    if ($centroFiltro >= 0 && $idcd !== $centroFiltro) continue;
    foreach ($prods as $idprod => $_) {
        $real = $realMap[$idcd][$idprod]['cantidad'] ?? 0;
        $calc = $calcMap[$idcd][$idprod] ?? 0;
        $diff = $real - $calc;
        if ($diff !== 0) {
            $nombreProd   = $realMap[$idcd][$idprod]['nombre_prod']   ?? "Producto {$idprod}";
            $nombreCentro = $realMap[$idcd][$idprod]['nombre_centro'] ?? ($idcd === 0 ? 'Almacén Principal' : "Centro {$idcd}");
            $diferencias[] = [
                'idcd'          => $idcd,
                'idprod'        => $idprod,
                'nombre_centro' => $nombreCentro,
                'nombre_prod'   => $nombreProd,
                'stock_real'    => $real,
                'stock_calc'    => $calc,
                'diferencia'    => $diff,
            ];
        }
    }
}

usort($diferencias, fn($a, $b) => abs($b['diferencia']) - abs($a['diferencia']));

$centros = $db->query("
    SELECT idusuarios_ci, nombre FROM usuarios_ci
    WHERE tipo_usuario = 2 ORDER BY idusuarios_ci
")->fetchAll(PDO::FETCH_ASSOC);
array_unshift($centros, ['idusuarios_ci' => 0, 'nombre' => 'Almacén Principal']);

echo json_encode([
    'success'     => true,
    'diferencias' => $diferencias,
    'centros'     => $centros,
    'stats' => [
        'total_diferencias' => count($diferencias),
        'con_faltante'      => count(array_filter($diferencias, fn($d) => $d['diferencia'] < 0)),
        'con_sobrante'      => count(array_filter($diferencias, fn($d) => $d['diferencia'] > 0)),
    ],
], JSON_UNESCAPED_UNICODE);
