<?php
session_start();
require_once "../config/conexion.php";

/* Cabeceras 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 */
date_default_timezone_set('America/Lima');
if (isset($conexion) && $conexion instanceof mysqli) {
  @mysqli_set_charset($conexion, 'utf8');
  @mysqli_query($conexion, "SET time_zone = '-05:00'");
}

/* Helpers JSON */
function json_err($m){ echo json_encode(["success"=>false,"message"=>$m],JSON_UNESCAPED_UNICODE); exit; }
function json_ok($x=[]){ echo json_encode(["success"=>true]+$x,JSON_UNESCAPED_UNICODE); exit; }

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

if ($method === "POST") {
  $accion = $_POST['accion'] ?? '';

  // REGISTRAR SALIDA
  if ($accion === 'registrar') {
    $codigo        = trim($_POST['codigo_producto'] ?? '');
    $modalidad     = $_POST['tipo_movimiento'] ?? ''; // con_retorno | sin_retorno
    $motivo        = trim($_POST['motivo'] ?? '');
    $cantidad      = max(1, (int)($_POST['cantidad'] ?? 1));
    $trabajador_id = isset($_POST['trabajador_id']) && $_POST['trabajador_id'] !== '' ? (int)$_POST['trabajador_id'] : null;
    $responsable   = ($_POST['cliente_responsable'] ?? '') ?: null;

    if ($codigo === '' || $motivo === '' || ($modalidad !== 'con_retorno' && $modalidad !== 'sin_retorno')) {
      json_err("Faltan datos obligatorios.");
    }

    // === Validación de fecha de retorno ===
    $fecha_retorno = null;
    if ($modalidad === 'con_retorno') {
      if (empty($_POST['fecha_retorno'])) json_err("Ingrese la fecha de retorno.");
      $tz = new DateTimeZone('America/Lima');
      $fr = DateTime::createFromFormat('Y-m-d', $_POST['fecha_retorno'], $tz);
      if (!$fr) json_err("Fecha de retorno inválida.");
      $hoy = new DateTime('today', $tz);
      if ($fr < $hoy) json_err("La fecha de retorno no puede ser anterior a hoy.");
      $fecha_retorno = $fr->format('Y-m-d');
      // en con_retorno, normalmente no se usa 'responsable' (cliente)
      // lo dejamos tal cual por si tu esquema lo permite; si no aplica, podrías forzarlo a null.
    } else {
      // sin retorno: ignora cualquier fecha que llegue por error
      $fecha_retorno = null;
      // y trabajador no aplica
      $trabajador_id = null;
    }

    // producto
    $stmt = $conexion->prepare("SELECT id, stock FROM productos WHERE codigo = ? LIMIT 1");
    $stmt->bind_param("s", $codigo);
    $stmt->execute();
    $stmt->store_result();
    if ($stmt->num_rows === 0) json_err("Producto no encontrado por código.");
    $stmt->bind_result($producto_id, $stock_actual);
    $stmt->fetch();
    $stmt->free_result(); $stmt->close();

    if ($stock_actual < $cantidad) json_err("Stock insuficiente. Disponible: $stock_actual");

    // usuario sesión (evita FK 0)
    $usuario_id = (int)($_SESSION['usuario_id'] ?? 0);
    if ($usuario_id <= 0) {
      if ($rs = $conexion->query("SELECT id FROM usuarios ORDER BY id ASC LIMIT 1")) {
        if ($u = $rs->fetch_row()) $usuario_id = (int)$u[0];
        $rs->free();
      }
    }
    if ($usuario_id <= 0) json_err("Sesión inválida: usuario no identificado.");

    // insert
    $sql = "INSERT INTO movimientos
              (producto_id, cantidad, motivo, tipo_movimiento, fecha, fecha_retorno,
               codigo_qr, usuario_id, trabajador_id, responsable, estado_retorno, tipo)
            VALUES ( ?, ?, ?, ?, NOW(), ?, ?, ?, ?, ?, 'pendiente', 'salida')";
    $codigo_qr  = $codigo;

    // 9 params -> i i s s s s i i s
    $stmt = $conexion->prepare($sql);
    $stmt->bind_param(
      "iissssiis",
      $producto_id,      // i
      $cantidad,         // i
      $motivo,           // s
      $modalidad,        // s
      $fecha_retorno,    // s (puede ser null)
      $codigo_qr,        // s
      $usuario_id,       // i
      $trabajador_id,    // i (puede ser null -> 0 si la col no acepta NULL)
      $responsable       // s (puede ser null -> '' si la col no acepta NULL)
    );
    if (!$stmt->execute()) json_err("No se pudo registrar el movimiento.");

    // descontar stock
    $stmt2 = $conexion->prepare("UPDATE productos SET stock = stock - ? WHERE id = ? AND stock >= ?");
    $stmt2->bind_param("iii", $cantidad, $producto_id, $cantidad);
    $stmt2->execute();
    if ($stmt2->affected_rows === 0) json_err("No se pudo descontar stock.");

    json_ok();
  }

  // === el resto de acciones (marcar_devuelto / marcar_defectuoso) se mantienen igual ===

  if ($accion === 'marcar_devuelto') {
    $mov_id = (int)($_POST['movimiento_id'] ?? 0);
    if ($mov_id <= 0) json_err("ID de movimiento requerido.");

    $stmt = $conexion->prepare("SELECT id, producto_id, cantidad, estado_retorno, fecha_retorno FROM movimientos WHERE id = ? LIMIT 1");
    $stmt->bind_param("i", $mov_id);
    $stmt->execute(); $stmt->store_result();
    if ($stmt->num_rows === 0) json_err("Movimiento no existe.");
    $stmt->bind_result($id, $producto_id, $cantidad, $estado_retorno, $fecha_ret);
    $stmt->fetch(); $stmt->free_result(); $stmt->close();

    if (is_null($fecha_ret)) json_err("Este movimiento es sin retorno.");
    if ($estado_retorno === 'devuelto') json_err("Ya fue marcado devuelto.");

    $tiene_real = false;
    if ($res = $conexion->query("SHOW COLUMNS FROM movimientos LIKE 'fecha_retorno_real'")) {
      $tiene_real = (bool)$res->num_rows; $res->free();
    }
    if ($tiene_real) {
      $stmt = $conexion->prepare("UPDATE movimientos SET estado_retorno = 'devuelto', fecha_retorno_real = NOW() WHERE id = ?");
    } else {
      $stmt = $conexion->prepare("UPDATE movimientos SET estado_retorno = 'devuelto', fecha_retorno = NOW() WHERE id = ?");
    }
    $stmt->bind_param("i", $mov_id);
    $stmt->execute();

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

    json_ok();
  }

  if ($accion === 'marcar_defectuoso') {
    $mov_id = (int)($_POST['movimiento_id'] ?? 0);
    if ($mov_id <= 0) json_err("ID de movimiento requerido.");

    $stmt = $conexion->prepare("SELECT m.id, m.producto_id, m.cantidad, m.estado_retorno, m.fecha_retorno, m.codigo_qr, p.nombre
                                FROM movimientos m INNER JOIN productos p ON p.id = m.producto_id
                                WHERE m.id = ? LIMIT 1");
    $stmt->bind_param("i", $mov_id);
    $stmt->execute(); $stmt->store_result();
    if ($stmt->num_rows === 0) json_err("Movimiento no existe.");
    $stmt->bind_result($id, $producto_id, $cantidad, $estado_retorno, $fecha_ret, $codigo_qr, $nombre_prod);
    $stmt->fetch(); $stmt->free_result(); $stmt->close();

    if (is_null($fecha_ret)) json_err("Este movimiento es sin retorno.");
    if ($estado_retorno === 'devuelto') json_err("Ya fue devuelto como bueno.");

    $tiene_real = false;
    if ($res = $conexion->query("SHOW COLUMNS FROM movimientos LIKE 'fecha_retorno_real'")) {
      $tiene_real = (bool)$res->num_rows; $res->free();
    }
    if ($tiene_real) {
      $stmt = $conexion->prepare("UPDATE movimientos SET estado_retorno = 'devuelto_defectuoso', fecha_retorno_real = NOW() WHERE id = ?");
    } else {
      $stmt = $conexion->prepare("UPDATE movimientos SET estado_retorno = 'devuelto_defectuoso', fecha_retorno = NOW() WHERE id = ?");
    }
    $stmt->bind_param("i", $mov_id);
    $stmt->execute();

    if ($conexion->query("SHOW TABLES LIKE 'productos_defectuosos'")->num_rows) {
      $obs = "Registrado como defectuoso desde devolución";
      $tiene_nombre = false;
      if ($res = $conexion->query("SHOW COLUMNS FROM productos_defectuosos LIKE 'nombre_producto'")) {
        $tiene_nombre = (bool)$res->num_rows; $res->free();
      }
      if ($tiene_nombre) {
        $stmt2 = $conexion->prepare("INSERT INTO productos_defectuosos (producto_id, nombre_producto, codigo_qr, fecha_registro, observacion)
                                     VALUES (?, ?, ?, NOW(), ?)");
        $stmt2->bind_param("isss", $producto_id, $nombre_prod, $codigo_qr, $obs);
      } else {
        $stmt2 = $conexion->prepare("INSERT INTO productos_defectuosos (producto_id, codigo_qr, fecha_registro, observacion)
                                     VALUES (?, ?, NOW(), ?)");
        $stmt2->bind_param("iss", $producto_id, $codigo_qr, $obs);
      }
      $stmt2->execute();
    }

    json_ok();
  }

  json_err("Acción no válida.");
}

/* LISTAR */
if ($method === "GET" && ($_GET['accion'] ?? '') === 'listar') {
  $sql = "SELECT m.*, p.nombre AS producto, t.nombre AS trabajador_nombre
          FROM movimientos m
          INNER JOIN productos p ON p.id = m.producto_id
          LEFT JOIN trabajadores t ON t.id = m.trabajador_id
          ORDER BY m.id DESC";
  $res = $conexion->query($sql);
  $datos = [];
  while ($row = $res->fetch_assoc()) { $datos[] = $row; }
  echo json_encode($datos, JSON_UNESCAPED_UNICODE);
  exit;
}

json_err("Petición inválida.");
