<?php
// ? Errores (quitar en produccion)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);

// ? CORS y Headers
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Content-Type");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Content-Type: application/json; charset=utf-8");

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { http_response_code(200); exit; }

// ? Conexion
require_once(__DIR__ . '/../config.php');
 $mysqli->set_charset("utf8mb4");

// ? JSON
 $input = json_decode(file_get_contents('php://input'), true);
if (!$input) { 
    echo json_encode(['success'=>false,'message'=>'JSON invalido']); 
    exit; 
}

// --- VALIDACION DE PARAMETROS ---
 $slug_tienda = isset($input['slug_tienda']) ? trim($input['slug_tienda']) : '';
 $factura_id = isset($input['factura_id']) ? (int)$input['factura_id'] : 0;
 $cajero = isset($input['cajero']) ? trim($input['cajero']) : '';

if (!$slug_tienda || !$factura_id || !$cajero) {
    echo json_encode(['success' => false, 'message' => 'Parametros invalidos o incompletos.']);
    exit;
}

try {
    // Iniciar transaccion para asegurar la integridad de los datos
    $mysqli->begin_transaction();

    // --- PASO 0: Guardar en el historial ANTES de modificar cualquier cosa ---
    
    // 0.1. Obtener todos los datos del encabezado de la factura
    $stmt_get_factura = $mysqli->prepare("SELECT * FROM facturas WHERE id = ? AND slug_tienda = ? FOR UPDATE");
    $stmt_get_factura->bind_param("is", $factura_id, $slug_tienda);
    $stmt_get_factura->execute();
    $factura_data = $stmt_get_factura->get_result()->fetch_assoc();
    $stmt_get_factura->close();

    if (!$factura_data) {
        throw new Exception("Factura no encontrada.");
    }

    if ($factura_data['estado'] === 'cancelada') {
        throw new Exception("La factura ya se encuentra cancelada.");
    }
    
    // 0.2. Insertar el encabezado en la tabla de historial
    $stmt_insert_hist = $mysqli->prepare("
        INSERT INTO historial_facturas_anuladas (
            factura_original_id, slug_tienda, numero_factura, fecha, cliente_nombre, cliente_documento, 
            cajero, subtotal, descuento, iva, domicilio, propina, total, estado, estado_original, cajero_anulacion
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    ");
    $stmt_insert_hist->bind_param(
        "isssssddddssssss",
        $factura_data['id'], // factura_original_id
        $factura_data['slug_tienda'],
        $factura_data['numero_factura'],
        $factura_data['fecha'],
        $factura_data['cliente_nombre'],
        $factura_data['cliente_documento'],
        $factura_data['cajero'],
        $factura_data['subtotal'],
        $factura_data['descuento'],
        $factura_data['iva'],
        $factura_data['domicilio'],
        $factura_data['propina'],
        $factura_data['total'],
        $factura_data['estado'],
        $factura_data['estado'], // estado_original - mismo valor que el estado actual
        $cajero // cajero_anulacion
    );
    if (!$stmt_insert_hist->execute()) {
        throw new Exception("Error al guardar el encabezado en el historial: " . $stmt_insert_hist->error);
    }
    $historial_factura_id = $mysqli->insert_id; // Obtenemos el ID del registro de historial recien creado
    $stmt_insert_hist->close();

   // 0.3. OBTENER LOS DETALLES USANDO UN JOIN (CORREGIDO)
 $stmt_get_detalles = $mysqli->prepare("
    SELECT 
        fd.articulo_id, 
        fd.cantidad, 
        fd.precio_unitario, 
        fd.subtotal,
        a.titulo AS articulo_titulo -- Obtenemos el titulo desde la tabla articulos
    FROM factura_detalles fd
    JOIN articulos a ON fd.articulo_id = a.id COLLATE utf8mb4_unicode_ci
    WHERE fd.factura_id = ?
");
    $stmt_get_detalles->bind_param("i", $factura_id);
    $stmt_get_detalles->execute();
    $detalles = $stmt_get_detalles->get_result()->fetch_all(MYSQLI_ASSOC);
    $stmt_get_detalles->close();

    // 0.4. Insertar los detalles en la tabla de historial
    $stmt_insert_det_hist = $mysqli->prepare("
        INSERT INTO historial_facturas_anuladas_detalles (
            historial_factura_anulada_id, articulo_id, articulo_titulo, cantidad, precio_unitario, subtotal
        ) VALUES (?, ?, ?, ?, ?, ?)
    ");
    foreach ($detalles as $item) {
        // Medida de seguridad por si el titulo en 'articulos' es nulo
        $titulo_articulo = $item['articulo_titulo'] ?? 'Titulo no disponible';

        $stmt_insert_det_hist->bind_param(
            "isssdd",
            $historial_factura_id,
            $item['articulo_id'],
            $titulo_articulo, // Usamos la variable segura
            $item['cantidad'],
            $item['precio_unitario'],
            $item['subtotal']
        );
        if (!$stmt_insert_det_hist->execute()) {
            throw new Exception("Error al guardar el detalle en el historial para el articulo {$item['articulo_id']}: " . $stmt_insert_det_hist->error);
        }
    }
    $stmt_insert_det_hist->close();

    // --- PASO 1: Devolver stock y registrar movimiento ---
    
    // Preparar las sentencias fuera del bucle para mayor eficiencia
    $stmt_get_stock = $mysqli->prepare("SELECT stock FROM articulos WHERE id = ? FOR UPDATE");
    $stmt_update_stock = $mysqli->prepare("UPDATE articulos SET stock = stock + ? WHERE id = ?");
    
    // Preparar la sentencia para el movimiento de inventario
    $motivo_movimiento = "Anulacion de Factura";
    $batch_id = uniqid('anul_'); // Generar un ID unico para todo el lote de movimientos
    $stmt_insert_movimiento = $mysqli->prepare("
        INSERT INTO inventario_movimientos (
            articulo_id, slug_tienda, cantidad_ingresada, cantidad_anterior, 
            cantidad_actual, motivo, nota, batch_id
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
    ");

    foreach ($detalles as $item) {
        // a. Obtener el stock ANTERIOR del articulo
        $stmt_get_stock->bind_param("s", $item['articulo_id']);
        $stmt_get_stock->execute();
        $stock_result = $stmt_get_stock->get_result();
        $stock_data = $stock_result->fetch_assoc();
        
        if (!$stock_data) {
            throw new Exception("Articulo con ID {$item['articulo_id']} no encontrado para consultar stock.");
        }
        $cantidad_anterior = $stock_data['stock'];

        // b. Calcular la cantidad ACTUAL
        $cantidad_actual = $cantidad_anterior + $item['cantidad'];

        // c. Devolver el stock al articulo
        $stmt_update_stock->bind_param("is", $item['cantidad'], $item['articulo_id']);
        if (!$stmt_update_stock->execute()) {
            throw new Exception("Error al devolver stock para el articulo ID {$item['articulo_id']}: " . $stmt_update_stock->error);
        }

        // d. Registrar el movimiento en inventario_movimientos
        $cantidad_ingresada = $item['cantidad']; // Es un ingreso, por lo que es positivo
        $nota_detalle = "Anulacion de factura No.: {$factura_data['numero_factura']}. Cajero: {$cajero}.";
        
        $stmt_insert_movimiento->bind_param(
            "ssiiisss",
            $item['articulo_id'], // articulo_id
            $slug_tienda,         // slug_tienda
            $cantidad_ingresada,  // cantidad_ingresada (positivo)
            $cantidad_anterior,   // cantidad_anterior
            $cantidad_actual,     // cantidad_actual
            $motivo_movimiento,   // motivo
            $nota_detalle,        // nota (detalles)
            $batch_id             // batch_id
        );
        if (!$stmt_insert_movimiento->execute()) {
            throw new Exception("Error al registrar movimiento de inventario para el articulo ID {$item['articulo_id']}: " . $stmt_insert_movimiento->error);
        }
    }

    // Cerrar las sentencias del bucle
    $stmt_get_stock->close();
    $stmt_update_stock->close();
    $stmt_insert_movimiento->close();

    // --- PASO 2: Actualizar el estado de la factura a 'cancelada' ---
    $stmt_update_factura = $mysqli->prepare("UPDATE facturas SET estado = 'cancelada', updated_at = NOW() WHERE id = ? AND slug_tienda = ?");
    $stmt_update_factura->bind_param("is", $factura_id, $slug_tienda);
    if (!$stmt_update_factura->execute()) {
        throw new Exception("Error al actualizar el estado de la factura: " . $stmt_update_factura->error);
    }
    $stmt_update_factura->close();

    // Si todas las operaciones tuvieron exito, confirmar la transaccion
    $mysqli->commit();

    echo json_encode([
        'success' => true, 
        'message' => 'Factura anulada, guardada en historial y stock actualizado correctamente.'
    ]);

} catch (Exception $e) {
    // Si algo salio mal, deshacer todos los cambios
    $mysqli->rollback();
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => $e->getMessage()]);
} finally {
    if (isset($mysqli) && $mysqli) { $mysqli->close(); }
}
?>