<?php
header('Content-Type: application/json');
$response = ['success' => false, 'message' => 'Gagal memperbarui status deposit.'];

require_once __DIR__ . '/../../../config/config.php';
require_once __DIR__ . '/../../../includes/session.php';
require_once __DIR__ . '/../../../lib/Auth.php';
require_once __DIR__ . '/../../../includes/functions.php';

if (!Auth::isLoggedIn() || $_SESSION['user_role'] !== 'admin') {
    http_response_code(403);
    $response['message'] = 'Akses ditolak.';
    echo json_encode($response);
    exit;
}

if (!isset($pdo) || !$pdo instanceof PDO) {
    http_response_code(500);
    error_log("PDO object not available in admin/update_deposit.php");
    $response['message'] = 'Koneksi database gagal.';
    echo json_encode($response);
    exit;
}

if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    $response['message'] = 'Metode request tidak valid.';
    echo json_encode($response);
    exit;
}

try {
    $depositId = filter_input(INPUT_POST, 'deposit_id', FILTER_VALIDATE_INT);
    $newStatus = sanitize_input($_POST['status'] ?? '');
    $currentStatusInput = sanitize_input($_POST['current_status'] ?? ''); // Status saat ini dari form
    $userId = filter_input(INPUT_POST, 'user_id', FILTER_VALIDATE_INT);
    $receivedAmountInput = filter_input(INPUT_POST, 'received_amount', FILTER_VALIDATE_FLOAT);


    if (!$depositId) {
        throw new InvalidArgumentException('ID deposit tidak valid.');
    }
    if (empty($newStatus)) {
        throw new InvalidArgumentException('Status baru tidak boleh kosong.');
    }

    $validStatuses = ['pending', 'success', 'failed', 'expired', 'canceled'];
    if (!in_array($newStatus, $validStatuses)) {
        throw new InvalidArgumentException('Status baru tidak valid.');
    }

    $pdo->beginTransaction();

    $stmtGetDeposit = $pdo->prepare("SELECT id, user_id, deposit_id as deposit_unique_id, amount, received_amount, status as current_db_status, deposit_method_id FROM deposits WHERE id = :deposit_id FOR UPDATE");
    $stmtGetDeposit->bindParam(':deposit_id', $depositId, PDO::PARAM_INT);
    $stmtGetDeposit->execute();
    $depositData = $stmtGetDeposit->fetch(PDO::FETCH_ASSOC);

    if (!$depositData) {
        $pdo->rollBack();
        throw new InvalidArgumentException('Data deposit tidak ditemukan.');
    }

    $currentDbStatus = $depositData['current_db_status'];
    $userIdFromDb = $depositData['user_id'];
    $receivedAmountFromDb = (float)$depositData['received_amount'];
    $depositUniqueId = $depositData['deposit_unique_id'];
    $depositMethodId = $depositData['deposit_method_id'];

    if ($userId !== (int)$userIdFromDb) { // Pastikan user_id dari POST cocok dengan DB
        $pdo->rollBack();
        throw new InvalidArgumentException('Data pengguna tidak cocok.');
    }
    if ($receivedAmountInput === false || $receivedAmountInput != $receivedAmountFromDb) {
         // Sebaiknya received_amount tidak diubah manual di sini, tapi diambil dari DB
         // Jika ingin ada penyesuaian, perlu logika khusus. Untuk sekarang, kita pakai dari DB.
    }
    $balanceToAdd = $receivedAmountFromDb;


    if ($currentDbStatus === 'success' && $newStatus !== 'success') {
        $pdo->rollBack(); // Tidak jadi commit jika mencoba mengubah dari success
        http_response_code(400);
        $response['message'] = 'Deposit yang sudah sukses tidak dapat diubah ke status lain selain sukses.';
        echo json_encode($response);
        exit;
    }

    if ($currentDbStatus === $newStatus) {
        $pdo->commit();
        $response['success'] = true;
        $response['message'] = 'Status deposit tidak berubah.';
        echo json_encode($response);
        exit;
    }


    $stmtUpdateDeposit = $pdo->prepare("UPDATE deposits SET status = :new_status, updated_at = NOW() WHERE id = :deposit_id_update");
    $stmtUpdateDeposit->bindParam(':new_status', $newStatus);
    $stmtUpdateDeposit->bindParam(':deposit_id_update', $depositId, PDO::PARAM_INT);

    if (!$stmtUpdateDeposit->execute()) {
        $pdo->rollBack();
        throw new RuntimeException("Gagal memperbarui status deposit di database.");
    }

    if ($newStatus === 'success' && $currentDbStatus !== 'success') {
        if ($balanceToAdd <= 0) {
             $pdo->rollBack();
             throw new InvalidArgumentException("Jumlah diterima tidak valid untuk update saldo.");
        }

        $stmtUser = $pdo->prepare("SELECT balance FROM users WHERE id = :user_id FOR UPDATE");
        $stmtUser->bindParam(':user_id', $userIdFromDb, PDO::PARAM_INT);
        $stmtUser->execute();
        $userBalanceBefore = (float)$stmtUser->fetchColumn();

        $newUserBalance = $userBalanceBefore + $balanceToAdd;

        $stmtUpdateUserBalance = $pdo->prepare("UPDATE users SET balance = :amount WHERE id = :user_id_bal");
        $stmtUpdateUserBalance->bindParam(':amount', $newUserBalance);
        $stmtUpdateUserBalance->bindParam(':user_id_bal', $userIdFromDb, PDO::PARAM_INT);
        if (!$stmtUpdateUserBalance->execute()) {
            $pdo->rollBack();
            throw new RuntimeException("Gagal memperbarui saldo pengguna setelah status deposit diubah menjadi sukses.");
        }

        $stmtMethodName = $pdo->prepare("SELECT name FROM deposit_methods WHERE id = :method_id");
        $stmtMethodName->bindParam(':method_id', $depositMethodId, PDO::PARAM_INT);
        $stmtMethodName->execute();
        $methodName = $stmtMethodName->fetchColumn() ?: 'N/A';

        log_balance_mutation(
            $pdo,
            $userIdFromDb,
            'credit',
            'deposit',
            $balanceToAdd,
            $userBalanceBefore,
            $newUserBalance,
            "Deposit berhasil melalui {$methodName} (ID Deposit: {$depositUniqueId})",
            $depositUniqueId,
            'admin'
        );
        $response['balance_updated'] = true;
    }

    $pdo->commit();
    $response['success'] = true;
    $response['message'] = 'Status deposit berhasil diperbarui.';

} catch (InvalidArgumentException $e) {
    if (isset($pdo) && $pdo->inTransaction()) { $pdo->rollBack(); }
    http_response_code(400);
    $response['message'] = $e->getMessage();
} catch (RuntimeException $e) {
    if (isset($pdo) && $pdo->inTransaction()) { $pdo->rollBack(); }
    error_log("Admin Update Deposit Runtime Error: " . $e->getMessage());
    $response['message'] = "Gagal memproses: " . $e->getMessage();
    http_response_code(500);
} catch (\PDOException $e) {
    if (isset($pdo) && $pdo->inTransaction()) { $pdo->rollBack(); }
    error_log("Admin Update Deposit DB Error: " . $e->getMessage());
    $response['message'] = "Terjadi kesalahan database.";
    http_response_code(500);
} catch (\Throwable $e) {
    if (isset($pdo) && $pdo->inTransaction()) { $pdo->rollBack(); }
    error_log("Admin Update Deposit General Error: " . $e->getMessage());
    $response['message'] = "Terjadi kesalahan internal server.";
    if (defined('DEBUG_MODE') && DEBUG_MODE === true) { $response['debug_php'] = $e->getMessage(); }
    http_response_code(500);
}

echo json_encode($response);
exit;
?>
