<?php
/**
 * controllers/IngresosController.php
 * - POST  -> Registrar ingreso rápido (suma stock + registro en movimientos)
 * - GET   -> Listar movimientos de un producto (con rango de fechas opcional)
 */
session_start();
require_once "../config/conexion.php";

/* === Cabeceras JSON + anti-caché === */
header("Content-Type: application/json; charset=utf-8");
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Pragma: no-cache");
header("Expires: 0");

/* === Zona horaria & charset MySQL === */
date_default_timezone_set('America/Lima');
if ($conexion && $conexion instanceof mysqli) {
  mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
  @$conexion->set_charset('utf8');
  @$conexion->query("SET time_zone = '-05:00'");
}

/* === Helpers JSON === */
function jerr(string $m, int $code = 500){
  http_response_code($code);
  echo json_encode(['success'=>false,'message'=>$m], JSON_UNESCAPED_UNICODE);
  exit;
}
function jok(array $x = []){
  echo json_encode(['success'=>true] + $x, JSON_UNESCAPED_UNICODE);
  exit;
}

$method = $_SERVER['REQUEST_METHOD'] ?? 'GET';

/* =========================================================
 * POST: Registrar Ingreso Rápido
 * ========================================================= */
if ($method === 'POST') {
  try {
    $producto_id = isset($_POST['producto_id']) ? (int)$_POST['producto_id'] : 0;
    $cantidad    = isset($_POST['cantidad']) ? (int)$_POST['cantidad'] : 0;
    $motivo      = trim((string)($_POST['motivo'] ?? ''));

    if ($producto_id <= 0) jerr('Producto inválido', 400);
    if ($cantidad <= 0)    jerr('Cantidad inválida', 400);

    // Tomar usuario de sesión si existe
    $usuario_id = isset($_SESSION['usuario_id']) ? (int)$_SESSION['usuario_id'] : null;
    if ($usuario_id !== null) {
      // Validar que exista en BD; si no existe, pasamos a NULL
      $stU = $conexion->prepare("SELECT id FROM usuarios WHERE id = ? LIMIT 1");
      $stU->bind_param("i", $usuario_id);
      $stU->execute();
      $stU->store_result();
      if ($stU->num_rows === 0) { $usuario_id = null; }
      $stU->close();
    }

    $conexion->begin_transaction();

    // Verificar que el producto exista y bloquearlo para actualizar stock
    $st = $conexion->prepare("SELECT id FROM productos WHERE id = ? FOR UPDATE");
    $st->bind_param("i", $producto_id);
    $st->execute();
    $st->store_result();
    if ($st->num_rows === 0) {
      $st->close();
      $conexion->rollback();
      jerr('El producto no existe', 404);
    }
    $st->close();

    // 1) Sumar stock
    $st = $conexion->prepare("UPDATE productos SET stock = stock + ? WHERE id = ?");
    $st->bind_param("ii", $cantidad, $producto_id);
    $st->execute();
    $st->close();

    // 2) Registrar movimiento tipo "ingreso"
    // codigo_qr/trabajador/responsable/estado_retorno -> NULL en este flujo
    if ($usuario_id === null) {
      $sql = "INSERT INTO movimientos
                (producto_id, cantidad, motivo, tipo_movimiento, fecha, fecha_retorno,
                 codigo_qr, usuario_id, trabajador_id, responsable, estado_retorno, tipo)
              VALUES
                (?, ?, ?, 'ingreso', NOW(), NULL, NULL, NULL, NULL, NULL, NULL, 'ingreso')";
      $st = $conexion->prepare($sql);
      // i i s
      $st->bind_param("iis", $producto_id, $cantidad, $motivo);
    } else {
      $sql = "INSERT INTO movimientos
                (producto_id, cantidad, motivo, tipo_movimiento, fecha, fecha_retorno,
                 codigo_qr, usuario_id, trabajador_id, responsable, estado_retorno, tipo)
              VALUES
                (?, ?, ?, 'ingreso', NOW(), NULL, NULL, ?, NULL, NULL, NULL, 'ingreso')";
      $st = $conexion->prepare($sql);
      // i i s i
      $st->bind_param("iisi", $producto_id, $cantidad, $motivo, $usuario_id);
    }

    $st->execute();
    $st->close();

    $conexion->commit();
    jok(['message' => 'Ingreso registrado.']);

  } catch (Throwable $e) {
    try { $conexion->rollback(); } catch (\Throwable $_) {}
    jerr('Error interno al registrar el ingreso: '.$e->getMessage(), 500);
  }
}

/* =========================================================
 * GET: Listado de movimientos por producto
 * ========================================================= */
try {
  $producto_id = isset($_GET['producto_id']) ? (int)$_GET['producto_id'] : 0;
  $desde       = trim((string)($_GET['desde'] ?? ''));
  $hasta       = trim((string)($_GET['hasta'] ?? ''));

  if ($producto_id <= 0) jerr('Producto inválido', 400);

  $sql = "SELECT id, tipo, cantidad, motivo,
                 DATE_FORMAT(fecha, '%Y-%m-%d %H:%i:%S') AS fecha,
                 responsable
          FROM movimientos
          WHERE producto_id = ?";
  $types  = "i";
  $params = [$producto_id];

  if ($desde !== '') { $sql .= " AND fecha >= ?"; $types .= "s"; $params[] = $desde . " 00:00:00"; }
  if ($hasta !== '') { $sql .= " AND fecha <= ?"; $types .= "s"; $params[] = $hasta . " 23:59:59"; }
  $sql .= " ORDER BY fecha DESC, id DESC";

  $st = $conexion->prepare($sql);
  $st->bind_param($types, ...$params);
  $st->execute();
  $st->bind_result($id, $tipo, $cant, $mot, $fec, $resp);
  $data = [];
  while ($st->fetch()) {
    $data[] = [
      'id'          => (int)$id,
      'tipo'        => (string)$tipo,
      'cantidad'    => (int)$cant,
      'motivo'      => (string)$mot,
      'fecha'       => (string)$fec,
      'responsable' => $resp,
    ];
  }
  $st->close();

  jok(['data' => $data]);

} catch (Throwable $e) {
  jerr('Error interno al listar: '.$e->getMessage(), 500);
}
