<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Services\TokopayService;
use App\Models\Deposit;
use App\Models\User;
use App\Models\ReferralCommission;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Http;
use App\Services\TelegramLogService;
class DepositController extends Controller
{
    /**
     * Halaman daftar deposit user.
     */

public function index()
{
    $deposits = Deposit::where('user_id', auth()->id())
        ->orderByDesc('id')
        ->paginate(10); 
    return view('deposit.index', compact('deposits'));
}

    /**
     * Membuat permintaan deposit baru (generate QRIS).
     */
    public function store(Request $request)
{
    $request->validate([
        // 🔹 minimal deposit Rp 5.000
        'amount' => 'required|numeric|min:5000',
    ], [
        'amount.min' => 'Minimal deposit adalah Rp 5.000.',
        'amount.required' => 'Nominal deposit wajib diisi.',
        'amount.numeric' => 'Nominal harus berupa angka.',
    ]);
$customRef = 'NDP' . now()->format('YmdHis') . Str::upper(Str::random(5));
    $tokopay = app(TokopayService::class);

$qris = $tokopay->generateQR(
    $request->amount,
    $customRef
);

    if (empty($qris['status']) || $qris['status'] !== true) {
        if ($request->ajax()) {
            return response()->json(['error' => 'Gagal generate QRIS.'], 400);
        }
        return back()->with('error', 'Gagal generate QRIS. Coba lagi.');
    }

    // === Simpan transaksi deposit ===
   $deposit = Deposit::create([
    'user_id'    => auth()->id(),
    'trx_id'     => $qris['trx_id'],
    'custom_ref' => $customRef,
    'amount'     => $request->amount,
    'status'     => 'PENDING',
]);
/*
|--------------------------------------------------------------------------
| REGISTER KE DISPATCHER
|--------------------------------------------------------------------------
*/

try {

    $dispatcher = Http::timeout(10)
        ->acceptJson()
        ->post(
            env('DISPATCHER_URL') . '/api/register',
            [

                'api_key' => env('DISPATCHER_API_KEY'),

                'trx_id' => $qris['trx_id'],

                'ref_id' => $customRef,

                'callback_url' => url('/payment/tokopay/callback'),

            ]
        );

    Log::info('Dispatcher Register', [
        'trx_id' => $qris['trx_id'],
        'status' => $dispatcher->status(),
        'body' => $dispatcher->body(),
    ]);

} catch (\Throwable $e) {

    Log::error('Dispatcher Register Failed', [

        'trx_id' => $qris['trx_id'],

        'message' => $e->getMessage(),

    ]);

}

    // 🔹 Jika request dari AJAX → kirim JSON (untuk popup)
    if ($request->ajax()) {
        return response()->json([
            'success'  => true,
            'trxId'    => $deposit->trx_id,
            'amount'   => $deposit->amount,
            'qrisData' => [
                'image'  => $qris['qr_url'],
                'string' => $qris['qr_string'],
            ],
        ]);
    }

    // 🔹 Kalau bukan AJAX (fallback untuk direct POST biasa)
    return view('deposit.qris', [
        'qrisData' => $qris,
        'trxId'    => $deposit->trx_id,
        'amount'   => $deposit->amount,
    ])->with('success', 'QRIS berhasil dibuat! Silakan scan untuk membayar.');
}

    /**
     * Callback PGA VIP (dipanggil otomatis setelah pembayaran sukses).
     */
public function callback(Request $request)
{
    // =====================================
    // 1️⃣ BALAS PGA SECEPAT MUNGKIN (ANTI STREAM ABORTED)
    // =====================================
    ignore_user_abort(true);
    set_time_limit(0);

    // Response duluan ke PGA (supaya tidak timeout)
    echo json_encode(['success' => true]);
    @flush();
    @ob_flush();
    if (function_exists('fastcgi_finish_request')) {
        fastcgi_finish_request(); // PGA sudah dapat respon
    }

    // Lanjut proses backend tanpa bikin PGA timeout
    // =====================================
    Log::info('📩 Callback Deposit diterima:', $request->all());

    $trxId = $request->input('reference');

$customRef = $request->input('reff_id');

$statusRaw = $request->input('status','');

$status = strtolower(trim($statusRaw));

    if (!$trxId && !$customRef) {
        Log::warning('❌ Callback tanpa trx_id/custom_ref!', $request->all());
        return; // backend lanjut tanpa balasan kedua
    }

    $deposit = Deposit::where('trx_id', $trxId)
        ->orWhere('custom_ref', $customRef)
        ->first();

    if (!$deposit) {
        Log::warning("❌ Deposit tidak ditemukan untuk trx_id/custom_ref: {$trxId} / {$customRef}");
        return;
    }

    $isPaid = in_array($status, ['paid', 'success', 'done', 'completed']);
    $isFailed = in_array($status, ['failed', 'cancelled', 'expired']);

// ====== STATUS PAID ======
if ($isPaid) {

    DB::transaction(function () use ($deposit, $trxId, $customRef) {

        // Lock deposit agar callback dobel tidak memproses saldo dobel
        $lockedDeposit = Deposit::where('id', $deposit->id)
            ->lockForUpdate()
            ->first();

        if (!$lockedDeposit || $lockedDeposit->status === 'PAID') {
            Log::info("⚠️ Deposit sudah pernah diproses: {$trxId} / {$customRef}");
            return;
        }

        $lockedDeposit->update(['status' => 'PAID']);

        $user = User::where('id', $lockedDeposit->user_id)
            ->lockForUpdate()
            ->first();

        if (!$user) {
            return;
        }

        // Saldo deposit user tetap masuk ke saldo utama user yang deposit
        $user->increment('balance', $lockedDeposit->amount);
        // Reload relasi user
$lockedDeposit->load('user');

// Kirim log ke Telegram
TelegramLogService::deposit($lockedDeposit);

        // ===== Referral Bonus =====
        // Komisi referral masuk ke referral_commissions saja.
        // Tidak langsung masuk ke users.balance referrer.
        if ($user->referrer_id) {
            $referrer = User::where('id', $user->referrer_id)
                ->lockForUpdate()
                ->first();

            if ($referrer) {
                $paidCount = Deposit::where('user_id', $user->id)
                    ->where('status', 'PAID')
                    ->count();

                if ($paidCount === 1 && $lockedDeposit->amount >= 5000) {
                    $bonusAmount = 600;

                    $alreadyCommission = ReferralCommission::where('referrer_id', $referrer->id)
                        ->where('referred_user_id', $user->id)
                        ->exists();

                    if (!$alreadyCommission) {
                        ReferralCommission::create([
                            'referrer_id'      => $referrer->id,
                            'referred_user_id' => $user->id,
                            'deposit_id'       => $lockedDeposit->id,
                            'amount'           => $bonusAmount,
                            'status'           => 'PENDING',
                        ]);

                        \App\Models\Referral::where('referred_user_id', $user->id)
                            ->update([
                                'deposit_amount' => $lockedDeposit->amount,
                                'bonus'          => $bonusAmount,
                            ]);

                        Log::info("🎉 Komisi referral Rp{$bonusAmount} masuk ke saldo komisi {$referrer->name} dari {$user->name}");
                    }
                }
            }
        }
    });

    Log::info("✅ Deposit sukses untuk {$trxId} / {$customRef}");
    return;
}

    // ===== STATUS FAILED / EXPIRED =====
    if ($isFailed) {
        $deposit->update(['status' => 'FAILED']);
        Log::warning("⚠️ Deposit gagal / expired untuk trx_id {$trxId}");
        return;
    }

    Log::info("⚠️ Status tidak dikenali: {$status}");
}


    /**
     * Membatalkan deposit yang masih pending.
     */
    public function cancel($trxId)
    {
        $deposit = Deposit::where('trx_id', $trxId)
            ->where('user_id', auth()->id())
            ->where('status', 'PENDING')
            ->first();

        if (!$deposit) {
            return response()->json(['success' => false, 'message' => 'Deposit tidak ditemukan atau sudah diproses.']);
        }

        $deposit->update(['status' => 'CANCELED']);
        Log::info("❌ Deposit dibatalkan: {$trxId} oleh user " . auth()->user()->name);

        return response()->json(['success' => true]);
    }
    public function riwayatApk(Request $request)
{
    $deposits = Deposit::where('user_id', auth()->id())

        ->when(
            $request->search,
            fn ($q) =>
            $q->where('trx_id', 'like', '%' . $request->search . '%')
        )

        ->latest()

        ->paginate(20)

        ->withQueryString();

    return view(
        'apk.riwayat-deposit',
        compact('deposits')
    );
}
public function recentDeposits()
{
    $items = Deposit::with('user')
        ->where('status', 'PAID')
        ->latest()
        ->take(8)
        ->get()
        ->map(function ($row) {

            return [
                'id'         => $row->id,
                'user'       => $row->user->name,
                'amount'     => $row->amount,
                'created_at' => $row->created_at,
            ];
        });

    return response()->json($items);
}

}
