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

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_user.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 {
    $userIdToUpdate = filter_input(INPUT_POST, 'user_id', FILTER_VALIDATE_INT);
    if (!$userIdToUpdate) {
        throw new InvalidArgumentException('ID pengguna tidak valid.');
    }

    $fullName = sanitize_input($_POST['full_name'] ?? null);
    $phoneNumber = sanitize_input($_POST['phone_number'] ?? null);
    $balanceInput = $_POST['balance'] ?? null; // Ambil sebagai string dulu
    $role = sanitize_input($_POST['role'] ?? 'member');
    $status = sanitize_input($_POST['status'] ?? 'inactive');
    $newPassword = $_POST['new_password'] ?? null;
    $adminReason = sanitize_input($_POST['admin_reason'] ?? ''); // Ambil alasan dari admin jika ada

    $errors = [];
    $updateData = [];

    if ($phoneNumber !== null && $phoneNumber !== '' && !preg_match('/^[0-9]{10,15}$/', $phoneNumber)) {
        $errors['phone_number'] = 'Format nomor handphone tidak valid (hanya angka, 10-15 digit).';
    }

    $balance = null;
    if ($balanceInput !== null) {
        if (!is_numeric($balanceInput) || (float)$balanceInput < 0) {
            $errors['balance'] = 'Saldo tidak valid. Harus angka positif atau nol.';
        } else {
            $balance = (float)$balanceInput;
        }
    }


    if (!in_array($role, ['member', 'admin'])) {
        $errors['role'] = 'Peran tidak valid.';
        $role = 'member';
    }
     if (!in_array($status, ['active', 'inactive', 'banned'])) {
        $errors['status'] = 'Status tidak valid.';
        $status = 'inactive';
    }
    if ($newPassword !== null && $newPassword !== '' && strlen($newPassword) < 6) {
         $errors['new_password'] = 'Password baru minimal 6 karakter.';
    }


    if (!empty($errors)) {
        http_response_code(400);
        $response['message'] = 'Periksa kembali input Anda.';
        $response['errors'] = $errors;
    } else {
        $auth = new Auth($pdo);
        $oldUserData = $auth->getUserById($userIdToUpdate);
        if (!$oldUserData) {
            throw new InvalidArgumentException('Pengguna yang akan diupdate tidak ditemukan.');
        }
        $balanceBeforeAdminUpdate = (float)$oldUserData['balance'];

        $updateData = [
            'full_name' => $fullName ?: null,
            'phone_number' => $phoneNumber ?: null,
            'role' => $role,
            'status' => $status,
        ];

        if ($balance !== null) {
            $updateData['balance'] = $balance;
        }


        if ($newPassword !== null && $newPassword !== '') {
            $updateData['password'] = $newPassword; // Hashing akan dilakukan di dalam metode updateUserByAdmin
        }

        $pdo->beginTransaction();

        if ($auth->updateUserByAdmin($userIdToUpdate, $updateData)) {
            $newBalanceAdminUpdate = $balance !== null ? $balance : $balanceBeforeAdminUpdate;
            $amountChanged = $newBalanceAdminUpdate - $balanceBeforeAdminUpdate;

            if (abs($amountChanged) > 0.001) { // Cek jika ada perubahan saldo yang signifikan
                $logType = $amountChanged > 0 ? 'credit' : 'debit';
                $absAmountChanged = abs($amountChanged);
                $logDescriptionAdmin = "Penyesuaian saldo oleh Admin ({$_SESSION['username']}).";
                if (!empty($adminReason)) {
                    $logDescriptionAdmin .= " Alasan: " . $adminReason;
                }

                log_balance_mutation(
                    $pdo,
                    $userIdToUpdate,
                    $logType,
                    'admin_adjustment',
                    $absAmountChanged,
                    $balanceBeforeAdminUpdate,
                    $newBalanceAdminUpdate,
                    $logDescriptionAdmin,
                    (string)$_SESSION['user_id'], // ID Admin yang melakukan aksi
                    'admin'
                );
            }
            $pdo->commit();
            $response['success'] = true;
            $response['message'] = 'Data pengguna berhasil diperbarui.';
        } else {
            $pdo->rollBack();
            http_response_code(500);
            $response['message'] = 'Gagal memperbarui data pengguna di database.';
        }
    }

} catch (InvalidArgumentException $e) {
    if (isset($pdo) && $pdo->inTransaction()) { $pdo->rollBack(); }
    http_response_code(400);
    $response['message'] = $e->getMessage();
} catch (\PDOException $e) {
    if (isset($pdo) && $pdo->inTransaction()) { $pdo->rollBack(); }
    error_log("Admin Update User 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 User 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;
?>
