<?php
// registrar_abono.php (Versión Corregida y Optimizada)

// Iniciar buffer de salida para capturar CUALQUIER cosa que se imprima (errores, advertencias, espacios)
ob_start();

// ? Errores (quitar en producción)
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; }

// ? Conexión
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 inválido']); 
    exit; 
}

// --- VALIDACIÓN DE PARÁMETROS ---
 $slug_tienda = isset($input['slug_tienda']) ? trim($input['slug_tienda']) : '';
 $credito_id = isset($input['credito_id']) ? (int)$input['credito_id'] : 0;
 $monto_abono = isset($input['monto_abono']) ? (float)$input['monto_abono'] : 0;
 $metodo_abono = trim($input['metodo_abono'] ?? '');
 $nota = trim($input['nota'] ?? '');
 $cajero = trim($input['cajero'] ?? '');

if (!$slug_tienda || !$credito_id || $monto_abono <= 0 || !$metodo_abono) {
    echo json_encode(['success' => false, 'message' => 'Datos de abono incompletos o inválidos.']);
    exit;
}

 $mysqli->begin_transaction();

try {
    // 1. Obtener información del crédito, saldo pendiente y factura_id
    $stmt = $mysqli->prepare("SELECT saldo_pendiente, factura_id FROM creditos WHERE id = ? AND slug_tienda = ? FOR UPDATE");
    $stmt->bind_param("is", $credito_id, $slug_tienda);
    $stmt->execute();
    $credito = $stmt->get_result()->fetch_assoc();
    $stmt->close();

    if (!$credito) {
        throw new Exception("Crédito no encontrado.");
    }
    if ($monto_abono > $credito['saldo_pendiente']) {
        throw new Exception("El abono no puede superar el saldo pendiente.");
    }

    // 2. Obtener cuotas pendientes ordenadas por fecha de vencimiento
    // ¡CORRECCIÓN! Seleccionar también 'monto_pagado' para calcular correctamente el estado de la cuota si ya tenía abonos parciales.
    $stmt = $mysqli->prepare("SELECT id, valor_cuota, monto_pagado FROM plan_pagos_creditos WHERE credito_id = ? AND estado = 'pendiente' ORDER BY fecha_vencimiento ASC");
    $stmt->bind_param("i", $credito_id);
    $stmt->execute();
    $cuotas_pendientes = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
    $stmt->close();

    if (empty($cuotas_pendientes)) {
        throw new Exception("No hay cuotas pendientes para este crédito.");
    }

    $monto_restante = $monto_abono;

    // 3. Aplicar el abono a las cuotas
    foreach ($cuotas_pendientes as $cuota) {
        if ($monto_restante <= 0) break;

        $valor_cuota = $cuota['valor_cuota'];
        $monto_a_aplicar = min($monto_restante, $valor_cuota);

        // ¡CORRECCIÓN! Calcular el nuevo monto total pagado para esta cuota para saber si se liquida completamente.
        $nuevo_monto_pagado_total = $cuota['monto_pagado'] + $monto_a_aplicar;
        $esta_pagada = ($nuevo_monto_pagado_total >= $valor_cuota);
        $nuevo_estado = $esta_pagada ? 'pagada' : 'pendiente';

        // Actualizar la cuota
        // ¡CORRECCIÓN 1! Se suma el monto en la consulta SQL en lugar de reemplazarlo.
        $stmt = $mysqli->prepare("UPDATE plan_pagos_creditos SET monto_pagado = monto_pagado + ?, estado = ?, fecha_pago = ? WHERE id = ?");
        
        // ¡CORRECCIÓN 2! Se usa solo el formato DATE para evitar errores de tipo de dato si la columna es DATE.
        $fecha_pago = $esta_pagada ? date('Y-m-d') : null;
        
        $stmt->bind_param("dssi", $monto_a_aplicar, $nuevo_estado, $fecha_pago, $cuota['id']);
        $stmt->execute();
        $stmt->close();
        
        $monto_restante -= $monto_a_aplicar;
    }

    // 4. Registrar el abono
    $stmt = $mysqli->prepare("INSERT INTO abonos_creditos (credito_id, factura_id, slug_tienda, monto_abono, metodo_abono, nota, cajero) VALUES (?, ?, ?, ?, ?, ?, ?)");
    $stmt->bind_param("iisssss", $credito_id, $credito['factura_id'], $slug_tienda, $monto_abono, $metodo_abono, $nota, $cajero);
    $stmt->execute();
    $abono_id = $stmt->insert_id;
    $stmt->close();

    // 5. Actualizar el saldo pendiente del crédito
    $nuevo_saldo = $credito['saldo_pendiente'] - $monto_abono;
    $nuevo_estado_credito = ($nuevo_saldo <= 0) ? 'pagado' : 'activo';
    $stmt = $mysqli->prepare("UPDATE creditos SET saldo_pendiente = ?, estado = ? WHERE id = ?");
    $stmt->bind_param("dsi", $nuevo_saldo, $nuevo_estado_credito, $credito_id);
    $stmt->execute();
    $stmt->close();

    // --- PASO 6: Verificar y actualizar el estado de la factura ---
    $factura_actualizada = false;
    $mensaje_factura = '';

    // 6.1. Obtener el total de la factura
    $stmt_factura = $mysqli->prepare("SELECT total, estado FROM facturas WHERE id = ?");
    $stmt_factura->bind_param("i", $credito['factura_id']);
    $stmt_factura->execute();
    $factura_info = $stmt_factura->get_result()->fetch_assoc();
    $stmt_factura->close();

    if ($factura_info && $factura_info['estado'] !== 'pagada') {
        $total_factura = $factura_info['total'];

        // 6.2. Sumar todos los abonos asociados a esa factura
        $stmt_sum_abonos = $mysqli->prepare("SELECT SUM(monto_abono) AS total_abonado FROM abonos_creditos WHERE factura_id = ?");
        $stmt_sum_abonos->bind_param("i", $credito['factura_id']);
        $stmt_sum_abonos->execute();
        $resultado_sum = $stmt_sum_abonos->get_result()->fetch_assoc();
        $stmt_sum_abonos->close();

        $total_abonado = $resultado_sum['total_abonado'] ?? 0;

        // 6.3. Comparar y actualizar si el total abonado es igual o mayor al total de la factura
        if ($total_abonado >= $total_factura) {
            $stmt_update_factura = $mysqli->prepare("UPDATE facturas SET estado = 'pagada' WHERE id = ?");
            $stmt_update_factura->bind_param("i", $credito['factura_id']);
            $stmt_update_factura->execute();
            
            if ($stmt_update_factura->affected_rows > 0) {
                $factura_actualizada = true;
                $mensaje_factura = " ¡La factura asociada también fue marcada como pagada!";
            }
            $stmt_update_factura->close();
        }
    }

    $mysqli->commit();

    $response_message = 'Abono registrado correctamente.' . ($mensaje_factura ?: '');
    $response = [
        'success' => true,
        'message' => $response_message,
        'nuevo_saldo_pendiente' => $nuevo_saldo,
        'estado_credito' => $nuevo_estado_credito,
        'factura_actualizada' => $factura_actualizada
    ];

} catch (Exception $e) {
    $mysqli->rollback();
    http_response_code(400); // Bad Request
    $response = [
        'success' => false, 
        'message' => $e->getMessage()
    ];
} finally {
    if (isset($mysqli) && $mysqli) { 
        $mysqli->close(); 
    }
}

// --- LÓGICA DE DEPURACIÓN FINAL ---
// 1. Limpiar el buffer de salida y obtener todo lo que se imprimió
 $php_output = ob_get_clean();

// 2. Verificar si hubo salida no deseada
if (!empty($php_output)) {
    // Si la hay, significa que hubo un error de PHP o un espacio en blanco.
    // Devolvemos un error JSON que incluya esa salida para que el frontend la muestre.
    http_response_code(500); // Internal Server Error
    echo json_encode([
        'success' => false,
        'message' => 'Error de PHP inesperado. Salida no deseada detectada.',
        'php_output' => $php_output // Aquí está el error real
    ]);
} else {
    // Si no hubo salida no deseada, imprimimos la respuesta JSON normal.
    echo json_encode($response);
}
?>