<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\BellNotification;
use App\Models\Transaction;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class UserBalanceController extends Controller
{
    // সব user list (simple)
    public function index(Request $request)
    {
        $q = trim((string) $request->get('q'));

        $users = User::query()
            ->when($q, function ($query) use ($q) {
                $query->where('name', 'like', "%{$q}%")
                      ->orWhere('phone', 'like', "%{$q}%")
                      ->orWhere('email', 'like', "%{$q}%");
            })
            ->orderBy('id', 'desc')
            ->paginate(20)
            ->withQueryString();

        return view('admin.users.balance.index', compact('users', 'q'));
    }

    // Single user balance form
    public function edit(User $user)
    {
        return view('admin.users.balance.edit', compact('user'));
    }

    // Balance add / return (minus) – AJAX + normal
    public function update(Request $request, User $user)
    {
        $data = $request->validate([
            'type'   => ['required', 'in:add,return'],   // add = credit, return = minus
            'amount' => ['required', 'numeric', 'min:0.01'],
            'note'   => ['nullable', 'string', 'max:255'],
        ]);

        $admin = $request->user();

        try {
            $result = DB::transaction(function () use ($data, $user, $admin) {
                // fresh lock
                $u = User::whereKey($user->id)->lockForUpdate()->firstOrFail();

                $amount = (float) $data['amount'];

                if ($data['type'] === 'return') {
                    // minus করার সময় পর্যাপ্ত balance আছে কিনা চেক
                    if (bccomp($u->balance, $amount, 2) < 0) {
                        throw new \RuntimeException('INSUFFICIENT_BALANCE_FOR_RETURN');
                    }
                    $newBalance = bcsub($u->balance, $amount, 2);
                    $txnType    = 'debit';
                    $title      = 'Balance Deducted by Admin';
                    $msgPrefix  = 'Admin has deducted';
                } else {
                    // add
                    $newBalance = bcadd($u->balance, $amount, 2);
                    $txnType    = 'credit';
                    $title      = 'Balance Added by Admin';
                    $msgPrefix  = 'Admin has added';
                }

                // user balance update
                $u->update([
                    'balance' => $newBalance,
                ]);

                // Transaction create
                $txn = Transaction::create([
                    'user_id'       => $u->id,
                    'type'          => $txnType,
                    'amount'        => $amount,
                    'balance_after' => $newBalance,
                    'related_type'  => User::class,         // manual adjust reference
                    'related_id'    => $u->id,
                    'meta'          => [
                        'source'     => 'admin_manual_adjust',
                        'admin_id'   => $admin->id,
                        'admin_name' => $admin->name,
                        'action'     => $data['type'],      // add / return
                        'note'       => $data['note'] ?? null,
                    ],
                ]);

                // Bell Notification create
                $noteText   = $data['note'] ? " Note: {$data['note']}." : '';
                $amountText = number_format($amount, 2);

                BellNotification::create([
                    'user_id' => $u->id,
                    'title'   => $title,
                    'status'  => 'unread',
                    'type'    => 'admin_balance_adjust',
                    'amount'  => $amount,
                    'message' => "{$msgPrefix} {$amountText} TK to your wallet (Txn ID: {$txn->id}).{$noteText}",
                    'read_at' => null,
                ]);

                return [
                    'new_balance' => (float) $newBalance,
                    'txn_id'      => $txn->id,
                    'direction'   => $data['type'],   // add / return
                    'amount'      => $amount,
                ];
            });

        } catch (\RuntimeException $e) {
            if ($e->getMessage() === 'INSUFFICIENT_BALANCE_FOR_RETURN') {

                if ($request->ajax() || $request->wantsJson()) {
                    return response()->json([
                        'success' => false,
                        'message' => 'User does not have enough balance to deduct this amount.',
                    ], 422);
                }

                return back()
                    ->withErrors(['amount' => 'User এর ব্যালেন্সে এত টাকা নেই, deduct করা যাবে না.'])
                    ->withInput();
            }

            throw $e;
        }

        // ✅ AJAX হলে JSON রিটার্ন
        if ($request->ajax() || $request->wantsJson()) {
            return response()->json([
                'success'     => true,
                'message'     => 'Balance updated successfully.',
                'new_balance' => $result['new_balance'],
                'txn_id'      => $result['txn_id'],
                'direction'   => $result['direction'],
                'amount'      => $result['amount'],
            ]);
        }

        // normal form submit হলে redirect
        return redirect()
            ->route('admin.users.balance.edit', $user)
            ->with('success', 'Balance updated successfully.');
    }
}
