<?php
/**
 * DONIGUARD AUTH SYSTEM v5.1 - Authoritative Ledger & Anti-Double & Migration Ready
 * Sistem Keamanan Audit Rantai Transaksi Pandawa-Digital
 * * Changelog:
 * v4.1: Mencegah Double Refund dengan validasi trx_id
 * v5.0: Menambahkan fitur "reset_balance" untuk pengesahan saldo oleh Admin (Hard Reset)
 * v5.1: Integrasi Tools Migrasi (Menangkap Total Data User & Injeksi Saldo)
 */

header('Content-Type: application/json');
date_default_timezone_set('Asia/Jakarta');

// 1. Ambil input dari frontend (Mendukung JSON dari sistem lama & POST dari tools migrasi)
$input = file_get_contents('php://input');
$data = json_decode($input, true);

// --- MODIFIKASI V5.1: Deteksi Request dari Tools Migrasi (debug.html) ---
if (isset($_POST['action']) && $_POST['action'] === 'restore_full_migration') {
    $data = $_POST; // Timpa $data dengan input POST
    
    // Fallback jika sistem web lama menggunakan key 'username' alih-alih 'uid'
    if (!isset($data['uid']) && isset($data['username'])) {
        $data['uid'] = $data['username'];
    }
}
// ------------------------------------------------------------------------

if (!$data || !isset($data['uid'])) {
    echo json_encode(['status' => 'error', 'message' => 'Invalid Request Structure (UID tidak ditemukan)']);
    exit;
}

$uid = $data['uid'];

// --- MODIFIKASI V5.1: Simpan Profil & Setup Parameter Migrasi ---
if (isset($data['action']) && $data['action'] === 'restore_full_migration') {
    // A. Simpan SELURUH data profil user (email, no_hp, dll) ke folder terpisah untuk Admin Panel
    $profile_folder = 'user_profiles/';
    if (!file_exists($profile_folder)) {
        mkdir($profile_folder, 0777, true);
    }
    // Simpan data sebagai file JSON
    file_put_contents($profile_folder . 'profil_' . $uid . '.json', json_encode($data, JSON_PRETTY_PRINT));

    // B. Ubah action menjadi 'reset_balance' agar diproses oleh fitur Hard Reset v5.0 Doniguard
    // Ini akan mereset buku besar dan memasukkan saldo awal dari website lama
    $data['action'] = 'reset_balance';
    $data['nominal'] = isset($data['saldo']) ? intval($data['saldo']) : 0;
    $data['produk'] = 'MIGRASI_SISTEM_BARU';
    $data['trx_id'] = 'MIGRATE_' . time() . '_' . rand(100,999);
}
// ----------------------------------------------------------------

$folder = 'user/';
$filename = $folder . 'uid' . $uid . '.txt';

// Buat folder jika belum ada
if (!file_exists($folder)) {
    mkdir($folder, 0777, true);
}

// 2. Buka/Buat file "Buku Besar"
$file_handle = fopen($filename, 'c+');

if (!$file_handle) {
    echo json_encode(['status' => 'error', 'message' => 'Sistem audit gagal diakses']);
    exit;
}

// 3. Kunci file (Locking) untuk mencegah Race Condition (Tabrakan data)
flock($file_handle, LOCK_EX);

// 4. Baca semua riwayat ke dalam array
$lines = [];
while (($line = fgets($file_handle)) !== false) {
    $line = trim($line);
    if (!empty($line)) {
        $lines[] = $line;
    }
}

// Ambil saldo terakhir dari riwayat yang ada
$last_balance = 0;
if (!empty($lines)) {
    $last_entry = json_decode(end($lines), true);
    $last_balance = intval($last_entry['saldo_akhir'] ?? 0);
}

// 5. Parameter transaksi dari Client
$action = $data['action'] ?? 'check'; // 'topup', 'transaksi', 'check', atau 'reset_balance'
$nominal = intval($data['nominal'] ?? 0);
$saldo_client = intval($data['saldo_akhir_client'] ?? 0);
$produk = $data['produk'] ?? 'SYSTEM_AUDIT';
$trx_id = $data['trx_id'] ?? ('SYS_' . time() . '_' . rand(100,999));

// Normalisasi ID agar refund ganda dari transaksi yang sama tidak bisa masuk dengan variasi ID berbeda.
// Contoh yang dianggap sama: TRX123, TRX123-REF, TRX123_REF, REFUND_TRX123.
function doniguard_normalize_refund_base_id($id) {
    $id = trim((string)$id);
    $id = preg_replace('/^(REFUND|REF)\-?/i', '', $id);
    $id = preg_replace('/(\-REFUND|\_REFUND|\-REF|\_REF)$/i', '', $id);
    return $id;
}

function doniguard_is_refund_event($action, $produk, $trx_id) {
    $action = strtoupper((string)$action);
    $produk = strtoupper((string)$produk);
    $trx_id = strtoupper((string)$trx_id);
    return ($action === 'TOPUP') && (
        strpos($produk, 'REFUND') !== false ||
        strpos($produk, 'REFOUND') !== false ||
        preg_match('/(\-REFUND|\_REFUND|\-REF|\_REF)$/i', $trx_id)
    );
}

$is_refund_event = doniguard_is_refund_event($action, $produk, $trx_id);
$original_trx_id = $trx_id;
$refund_base_id = doniguard_normalize_refund_base_id($trx_id);
$dedupe_trx_id = $is_refund_event ? ('REFUND_' . $refund_base_id) : $trx_id;

/**
 * 6. FITUR KEAMANAN: ANTI-DOUBLE REFUND / IDEMPOTENCY
 * Refund hanya boleh tercatat 1 kali untuk 1 transaksi asal.
 * Sistem ini tetap membaca format log lama yang mungkin memakai trx_id TRX123-REF.
 */
if ($action !== 'check' && $action !== 'reset_balance') {
    foreach ($lines as $line_str) {
        $history = json_decode($line_str, true);
        if (!$history) continue;

        $history_trx_id = (string)($history['trx_id'] ?? '');
        $history_produk = (string)($history['produk'] ?? '');
        $history_type = (string)($history['type'] ?? '');
        $history_is_refund = !empty($history['is_refund']) || doniguard_is_refund_event($history_type, $history_produk, $history_trx_id);

        $duplicate_found = false;

        if ($is_refund_event && $history_is_refund) {
            $history_base_id = (string)($history['refund_base_id'] ?? doniguard_normalize_refund_base_id($history_trx_id));
            $duplicate_found = ($history_base_id === $refund_base_id);
        } else {
            $duplicate_found = ($history_trx_id === $dedupe_trx_id || $history_trx_id === $trx_id);
        }

        if ($duplicate_found) {
            flock($file_handle, LOCK_UN);
            fclose($file_handle);

            echo json_encode([
                'status' => 'success',
                'message' => $is_refund_event
                    ? 'Refund sudah pernah diproses. Saldo tidak ditambah ulang.'
                    : 'Transaksi sudah diproses sebelumnya (Duplicate prevention)',
                'duplicate' => true,
                'audit' => [
                    'valid' => true,
                    'correct_balance' => $last_balance,
                    'force_sync' => true,
                    'timestamp' => date('c')
                ]
            ]);
            exit;
        }
    }
}

/**
 * 7. LOGIKA UTAMA PERHITUNGAN SALDO SAH
 */
if ($action === 'reset_balance') {
    // === MODUL RESET / PENGESAHAN ADMIN ===
    ftruncate($file_handle, 0);
    rewind($file_handle);
    
    $lines = []; 
    $last_balance = 0; 
    $saldo_akhir = $nominal;
    
    // Override parameter untuk pencatatan log baru
    $produk = ($produk === 'SYSTEM_AUDIT') ? 'INITIAL_PUSH_ADMIN' : $produk;
    $action = 'topup'; 
    
} elseif ($action === 'topup') {
    $saldo_akhir = $last_balance + $nominal;
} elseif ($action === 'check') {
    $saldo_akhir = (empty($lines)) ? 0 : $last_balance;
} else {
    if (empty($lines)) {
        $saldo_akhir = 0; 
    } else {
        $saldo_akhir = $last_balance - $nominal;
    }
}

/**
 * 8. PENCATATAN LOG KE BUKU BESAR
 */
if ($action !== 'check') {
    $log_data = [
        'waktu' => date('Y-m-d H:i:s'),
        'trx_id' => $dedupe_trx_id,
        'original_trx_id' => $original_trx_id,
        'produk' => strtoupper($produk),
        'saldo_awal' => $last_balance,
        'nominal' => $nominal,
        'saldo_akhir' => $saldo_akhir,
        'type' => strtoupper($action),
        'is_refund' => $is_refund_event,
        'refund_base_id' => $is_refund_event ? $refund_base_id : null
    ];
    
    fseek($file_handle, 0, SEEK_END);
    fwrite($file_handle, json_encode($log_data) . PHP_EOL);
}

// 9. Lepas kunci dan tutup file
flock($file_handle, LOCK_UN);
fclose($file_handle);

/**
 * 10. VALIDASI DAN RESPON SINKRONISASI
 */
$is_valid = ($saldo_client === $saldo_akhir);
// Pengecualian: Jika migrasi, tidak perlu mencocokkan saldo client
if ($produk === 'MIGRASI_SISTEM_BARU') {
    $is_valid = true;
}
$force_sync = (!$is_valid);

echo json_encode([
    'status' => 'success',
    'audit' => [
        'valid' => $is_valid,
        'correct_balance' => $saldo_akhir,
        'force_sync' => $force_sync,
        'timestamp' => date('c')
    ]
]);
?>