<?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']) : '';
 $motivo = isset($input['motivo']) ? trim($input['motivo']) : '';
 $items_devueltos = isset($input['items']) && is_array($input['items']) ? $input['items'] : [];

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

try {
    // Iniciar transaccion
    $mysqli->begin_transaction();

    // 1. Verificar que la factura exista y este en un estado valido
    $stmt_check_factura = $mysqli->prepare("SELECT estado FROM facturas WHERE id = ? AND slug_tienda = ? FOR UPDATE");
    $stmt_check_factura->bind_param("is", $factura_id, $slug_tienda);
    $stmt_check_factura->execute();
    $factura_data = $stmt_check_factura->get_result()->fetch_assoc();
    $stmt_check_factura->close();

    if (!$factura_data) {
        throw new Exception("Factura no encontrada.");
    }
    if ($factura_data['estado'] === 'cancelada') {
        throw new Exception("No se puede generar nota de credito para una factura cancelada.");
    }

    // 2. Generar un numero unico para la nota de credito
    $stmt_last_num = $mysqli->prepare("SELECT numero_nota_credito FROM notas_credito WHERE slug_tienda = ? ORDER BY id DESC LIMIT 1");
    $stmt_last_num->bind_param("s", $slug_tienda);
    $stmt_last_num->execute();
    $last_num_result = $stmt_last_num->get_result()->fetch_assoc();
    $stmt_last_num->close();

    if ($last_num_result) {
        // Extraer el numero y aumentarlo
        $last_num = (int)str_replace('NC-', '', $last_num_result['numero_nota_credito']);
        $next_num = $last_num + 1;
    } else {
        $next_num = 1;
    }
    $numero_nota_credito = 'NC-' . sprintf('%04d', $next_num);

    // 3. Determinar los items a devolver y calcular el total
    $items_a_procesar = [];
    $total_nota_credito = 0;

    if (empty($items_devueltos)) {
        // Nota de credito por el total de la factura
        $stmt_detalles_factura = $mysqli->prepare("SELECT articulo_id, cantidad, precio_unitario, subtotal FROM factura_detalles WHERE factura_id = ?");
        $stmt_detalles_factura->bind_param("i", $factura_id);
        $stmt_detalles_factura->execute();
        $items_a_procesar = $stmt_detalles_factura->get_result()->fetch_all(MYSQLI_ASSOC);
        $stmt_detalles_factura->close();
    } else {
        // Nota de credito parcial (validar que los items pertenezcan a la factura)
        $placeholders = implode(',', array_fill(0, count($items_devueltos), '?'));
        $types = str_repeat('i', count($items_devueltos));
        $stmt_detalles_factura = $mysqli->prepare("
            SELECT articulo_id, cantidad, precio_unitario, subtotal 
            FROM factura_detalles 
            WHERE factura_id = ? AND id IN ($placeholders)
        ");
        $params = array_merge([$factura_id], array_column($items_devueltos, 'id'));
        $stmt_detalles_factura->bind_param("i" . $types, ...$params);
        $stmt_detalles_factura->execute();
        $items_a_procesar = $stmt_detalles_factura->get_result()->fetch_all(MYSQLI_ASSOC);
        $stmt_detalles_factura->close();
    }

    if (empty($items_a_procesar)) {
        throw new Exception("No se encontraron items validos para generar la nota de credito.");
    }
    
    foreach ($items_a_procesar as $item) {
        $total_nota_credito += $item['subtotal'];
    }

    // 4. Insertar el encabezado de la nota de credito
    $stmt_insert_nc = $mysqli->prepare("
        INSERT INTO notas_credito (slug_tienda, numero_nota_credito, factura_id_relacionada, fecha, cajero, motivo, total) 
        VALUES (?, ?, ?, NOW(), ?, ?, ?)
    ");
    $stmt_insert_nc->bind_param("sssssd", $slug_tienda, $numero_nota_credito, $factura_id, $cajero, $motivo, $total_nota_credito);
    if (!$stmt_insert_nc->execute()) {
        throw new Exception("Error al crear el encabezado de la nota de credito: " . $stmt_insert_nc->error);
    }
    $nota_credito_id = $mysqli->insert_id;
    $stmt_insert_nc->close();

    // 5. Insertar los detalles de la nota de credito
    $stmt_insert_detalle = $mysqli->prepare("
        INSERT INTO nota_credito_detalles (nota_credito_id, articulo_id, cantidad, precio_unitario, subtotal) 
        VALUES (?, ?, ?, ?, ?)
    ");
    foreach ($items_a_procesar as $item) {
        $stmt_insert_detalle->bind_param("isidd", $nota_credito_id, $item['articulo_id'], $item['cantidad'], $item['precio_unitario'], $item['subtotal']);
        if (!$stmt_insert_detalle->execute()) {
            throw new Exception("Error al insertar detalle de la nota de credito: " . $stmt_insert_detalle->error);
        }
    }
    $stmt_insert_detalle->close();

    // --- NUEVA LOGICA: Devolver productos al 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 = "Devolucion por Nota de Credito";
    $batch_id = uniqid('nc_'); // 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 ($items_a_procesar 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
        $nota_detalle = "Nota de Credito {$numero_nota_credito} para Factura ID {$factura_id}. Motivo: {$motivo}";
        
        $stmt_insert_movimiento->bind_param(
            "ssiiisss",
            $item['articulo_id'], // articulo_id
            $slug_tienda,         // slug_tienda
            $item['cantidad'],    // 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();

    // Si todo fue exitoso, confirmar la transaccion
    $mysqli->commit();

    echo json_encode([
        'success' => true, 
        'message' => 'Nota de credito generada correctamente.',
        'numero_nota_credito' => $numero_nota_credito,
        'total' => $total_nota_credito
    ]);

} 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(); }
}
?>