<?php ob_start();
require_once '../files/guardiankey.php'; ?>
<?php
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', __DIR__ . '/../logs/php_errors.log');
error_reporting(E_ALL);

include_once 'db_connection.php';

$response = [];

try {
    // Decodificar los datos JSON enviados en el cuerpo de la solicitud
    $data = json_decode(file_get_contents('php://input'), true);

    // Verificar si el JSON es válido
    if (json_last_error() !== JSON_ERROR_NONE) {
        error_log("Error al decodificar JSON en invoice-status-update.php: " . json_last_error_msg());
        throw new Exception('Error al procesar los datos enviados.');
    }

    // Validar que se han recibido los datos requeridos: ID de la factura y el nuevo estado
    if (empty($data['id']) || empty($data['status'])) {
        throw new Exception('Datos incompletos para actualizar el estado de la factura. Se requiere ID y estado.');
    }

    // ✅ CORRECCIÓN: Filtrar y validar el ID de la factura para seguridad
    $invoice_db_id = filter_var($data['id'], FILTER_VALIDATE_INT);
    if ($invoice_db_id === false) {
        throw new Exception('ID de factura inválido.');
    }

    // ✅ CORRECCIÓN: Limpiar y validar el nuevo estado de forma segura
    $new_status = filter_var(trim($data['status']), FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    // Definir los estados permitidos para las facturas
    $allowed_statuses = ['generada', 'enviada', 'cancelada', 'atrasada', 'pagada'];
    if (!in_array($new_status, $allowed_statuses)) {
        throw new Exception('Estado de factura inválido. Estados permitidos: ' . implode(', ', $allowed_statuses));
    }

    // Iniciar una transacción para asegurar la integridad de la base de datos
    $pdo->beginTransaction();

    // Preparar la consulta SQL para actualizar solo la columna 'status' y 'updated_at'
    $stmt = $pdo->prepare(
        "UPDATE invoices
         SET status = ?, updated_at = NOW()
         WHERE id = ?"
    );

    // Ejecutar la consulta con el nuevo estado y el ID de la factura
    $stmt->execute([$new_status, $invoice_db_id]);

    // Lógica para registrar en finanzas si el nuevo estado es 'pagada'
    if ($new_status === 'pagada') {
        // Obtener detalles de la factura para el registro financiero
        $stmtInvoice = $pdo->prepare("SELECT client_id, total_amount, external_id FROM invoices WHERE id = ? FOR UPDATE"); // Usar FOR UPDATE
        $stmtInvoice->execute([$invoice_db_id]);
        $invoiceDetails = $stmtInvoice->fetch(PDO::FETCH_ASSOC);

        if ($invoiceDetails) {
            $amount = (float)$invoiceDetails['total_amount'];
            $clientId = (int)$invoiceDetails['client_id'];
            $description = "Ingreso por factura pagada #" . filter_var($invoiceDetails['external_id'], FILTER_SANITIZE_FULL_SPECIAL_CHARS); // Usar external_id y sanitizar

            // Verificar si ya existe una transacción de ingreso para esta factura en finances
            $stmtCheckFinance = $pdo->prepare("SELECT COUNT(*) FROM finances WHERE description LIKE ? AND client_id = ? AND type = 'ingreso'");
            $stmtCheckFinance->execute(["Ingreso por factura pagada #%" . $invoice_db_id, $clientId]); // Usar LIKE y ID de DB para un chequeo más robusto
            if ($stmtCheckFinance->fetchColumn() === 0) { // Solo insertar si no existe una transacción para esta factura
                $stmtFinance = $pdo->prepare("INSERT INTO finances (type, description, amount, transaction_date, client_id) VALUES ('ingreso', :description, :amount, CURDATE(), :client_id)");
                $stmtFinance->bindParam(':description', $description);
                $stmtFinance->bindParam(':amount', $amount);
                $stmtFinance->bindParam(':client_id', $clientId, PDO::PARAM_INT); // Asegurar tipo de parámetro
                $stmtFinance->execute();
            } else {
                error_log("Advertencia: Se intentó registrar un ingreso duplicado para la factura ID: " . $invoice_db_id);
            }
        }
    }

    // Verificar si la actualización afectó alguna fila
    if ($stmt->rowCount() > 0) {
        $pdo->commit(); // Confirmar la transacción si la actualización fue exitosa
        $response = [
            'success' => true,
            'message' => 'Estado de la factura actualizado con éxito.',
            'id' => $invoice_db_id,
            'new_status' => $new_status
        ];
    } else {
        $pdo->rollBack(); // Revertir la transacción si no se encontró la factura o no hubo cambios
        $response = ['success' => false, 'message' => 'La factura no fue encontrada o el estado ya es el mismo.'];
    }

} catch (PDOException $e) {
    // Capturar errores de la base de datos (PDO)
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    error_log("PDO Error en invoice-status-update.php: " . $e->getMessage());
    $response = ['success' => false, 'message' => 'Error de Base de Datos al actualizar el estado. Por favor, inténtalo de nuevo más tarde.'];
} catch (Exception $e) {
    // Capturar cualquier otra excepción
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    error_log("General Error en invoice-status-update.php: " . $e->getMessage());
    $response = ['success' => false, 'message' => $e->getMessage()];
}

// Limpiar el buffer de salida y enviar la respuesta JSON
ob_end_clean();
header('Content-Type: application/json');
echo json_encode($response);
exit;