<?php  

namespace App\Http\Controllers\Frontend;

use App\Events\Bills\BillPaymentSubmitted;
use App\Http\Controllers\Controller;
use App\Models\Biller;
use App\Models\BillPayment;
use App\Models\Transaction;
use App\Models\User;
use App\Models\BellNotification;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;              // ✅ for PIN check
use Illuminate\Validation\ValidationException;   // ✅ for error on wrong PIN

class PaybillController extends Controller
{
    public function index(Request $request)
    {
        $q = trim((string) $request->get('q'));

        $billers = Biller::active()
            ->with('category')
            ->when($q, fn($qb) => $qb->where(function($w) use ($q) {
                $w->where('name','like',"%$q%")
                  ->orWhere('provider','like',"%$q%");
            }))
            ->orderBy('sort_order')->orderBy('id')
            ->get();

        return view('frontend.paybills.index', compact('billers','q'));
    }

    public function show(Biller $biller)
    {
        abort_unless($biller->status === 'active', 404);
        return view('frontend.paybills.show', compact('biller'));
    }

    public function pay(Request $request, Biller $biller)
    {
        abort_unless($biller->status === 'active', 404);

        /** @var User $user */
        $user = $request->user();

        // ✅ validate + PIN field
        $data = $request->validate([
            'account_name' => ['required','string','max:100'],
            'account_no'   => ['required','string','max:60'],
            'amount'       => ['required','numeric','min:'.$biller->min_amount,'max:'.$biller->max_amount],
            'reference'    => ['nullable','string','max:80'],
            'login_pin'    => ['required','digits:4'],   // 🔐 PIN (4 digits)
        ], [
            'login_pin.digits' => 'PIN অবশ্যই ৪ ডিজিট হতে হবে।',
        ]);

        // 🔐 PIN verify
        $pin = (string) $request->input('login_pin');

        if (! Hash::check($pin, $user->login_pin)) {  // ← column নাম আলাদা হলে ঠিক করে নিও
            throw ValidationException::withMessages([
                'login_pin' => 'Incorrect PIN.',
            ]);
        }

        $userId = $user->id;

        try {
            $result = DB::transaction(function () use ($userId, $biller, $data) {

                /** @var User $user */
                $user = User::whereKey($userId)->lockForUpdate()->first();

                // পর্যাপ্ত ব্যালেন্স না থাকলে failed লগ করে থ্রো
                if (bccomp($user->balance, $data['amount'], 2) < 0) {
                    BillPayment::create([
                        'user_id'       => $user->id,
                        'biller_id'     => $biller->id,
                        'account_name'  => $data['account_name'],
                        'account_no'    => $data['account_no'],
                        'amount'        => $data['amount'],
                        'reference'     => $data['reference'] ?? null,
                        'status'        => 'failed',
                        'txn_id'        => null,
                    ]);
                    throw new \RuntimeException('INSUFFICIENT_BALANCE');
                }

                // ব্যালেন্স ডেবিট
                $user->decrement('balance', $data['amount']);

                // payment create
                $payment = BillPayment::create([
                    'user_id'       => $user->id,
                    'biller_id'     => $biller->id,
                    'account_name'  => $data['account_name'],
                    'account_no'    => $data['account_no'],
                    'amount'        => $data['amount'],
                    'reference'     => $data['reference'] ?? null,
                    'status'        => 'pending', // admin/process pending
                    'txn_id'        => 'BILL-'.Str::upper(Str::random(6)).'-'.now()->format('ymdHis'),
                ]);

                // ===== Reward Points (paybills_comm %) =====
                $settings = DB::table('reward_settings')
                    ->where('is_active', 1)
                    ->orderByDesc('id')
                    ->first();

                $percent = $settings ? (float) $settings->paybills_comm : 0.0;

                $awarded = 0;
                if ($percent > 0) {
                    // points = floor(amount * percent / 100)
                    $awarded = (int) floor(($data['amount'] * $percent) / 100);
                    if ($awarded > 0) {
                        $user->increment('reward_points', $awarded);
                    }
                }

                // OPTIONAL: bill_payments.reward_points_awarded থাকলে লগ করো
                if ($this->tableHasColumn('bill_payments', 'reward_points_awarded')) {
                    DB::table('bill_payments')->where('id', $payment->id)->update([
                        'reward_points_awarded' => $awarded,
                    ]);
                }

                // ✅ Transaction রেকর্ড তৈরি (debit)
                Transaction::create([
                    'user_id'       => $user->id,
                    'type'          => 'debit',
                    'amount'        => (float) $data['amount'],
                    'balance_after' => $user->fresh()->balance, // ডেবিটের পর ব্যালেন্স
                    'related_type'  => BillPayment::class,
                    'related_id'    => $payment->id,
                    'meta'          => json_encode([
                        'biller_id'     => $biller->id,
                        'biller_name'   => $biller->name,
                        'account_name'  => $data['account_name'],
                        'account_no'    => $data['account_no'],
                        'txn_id'        => $payment->txn_id,
                        'reward_points_awarded' => $awarded,
                        'reference'     => $data['reference'] ?? null,
                    ]),
                ]);

                // ✅ 🔔 Bell Notification (bill_payment)
                $refText = (!empty($data['reference']))
                    ? " Ref: {$data['reference']}."
                    : '';

                BellNotification::create([
                    'user_id' => $user->id,
                    'title'   => 'Bill Payment Submitted',
                    'status'  => 'unread',
                    'type'    => 'bill_payment',
                    'amount'  => (float) $data['amount'],
                    'message' => "Your bill payment of {$data['amount']} TK to {$biller->name} "
                               . "for account {$data['account_no']} has been submitted and is pending approval. "
                               . "TXN: {$payment->txn_id}"
                               . ($awarded > 0 ? " | Reward: +{$awarded} pts." : '')
                               . $refText,
                    'read_at' => null,
                ]);

                return [
                    'payment'      => $payment,
                    'txn_id'       => $payment->txn_id,
                    'awarded'      => $awarded,
                    'new_points'   => (int) $user->reward_points,
                    'new_balance'  => (float) $user->balance,
                ];
            });
        } catch (\RuntimeException $e) {
            if ($e->getMessage() === 'INSUFFICIENT_BALANCE') {
                if ($request->wantsJson()) {
                    return response()->json([
                        'ok'      => false,
                        'message' => 'আপনার ব্যালেন্স পর্যাপ্ত নয়।',
                    ], 422);
                }
                return back()
                    ->withErrors(['amount' => 'আপনার ব্যালেন্স পর্যাপ্ত নয়।'])
                    ->withInput();
            }
            throw $e;
        }

        // ✅ transaction সফল হওয়ার পর event fire
        $paymentForEvent = $result['payment']->fresh('biller');
        event(new BillPaymentSubmitted($paymentForEvent));

        // JSON রেসপন্স চাইলে
        if ($request->wantsJson()) {
            return response()->json([
                'ok'             => true,
                'message'        => 'বিল পেমেন্ট সফল হয়েছে।',
                'txn_id'         => $result['txn_id'],
                'reward_awarded' => $result['awarded'],
                'reward_points'  => $result['new_points'],
                'balance'        => $result['new_balance'],
            ]);
        }

        // 🟢 normal form submit ⇒ success page redirect
        $payment = $result['payment'];  // BillPayment model

        $msg = 'বিল পেমেন্ট সফল হয়েছে! ট্রান্স্যাকশন: '.$result['txn_id'];
        if ($result['awarded'] > 0) {
            $msg .= ' | রিওয়ার্ড +'.$result['awarded'].' পয়েন্ট';
        }

        return redirect()
            ->route('paybills.success', $payment)   // 🔗 success page
            ->with('success', $msg);
    }

    /**
     * Success পেজ
     */
    public function success(Request $request, BillPayment $payment)
    {
        // নিজের payment না হলে show করতে দিবো না
        // if ($payment->user_id !== $request->user()->id) {
        //     abort(403);
        // }

        $payment->load('biller');

        return view('frontend.paybills.success', [
            'payment' => $payment,
        ]);
    }

    /**
     * অপশনাল: টেবিলে কলাম আছে কি না চেক করার ছোট হেল্পার
     */
    protected function tableHasColumn(string $table, string $column): bool
    {
        try {
            /** @var \Illuminate\Database\Schema\Builder $schema */
            $schema = app('db.schema');
            return $schema->hasColumn($table, $column);
        } catch (\Throwable $e) {
            return false;
        }
    }
}
