<?php

namespace App\Http\Controllers;

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

class BillPaymentController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Bill Payment Controller
    |--------------------------------------------------------------------------
    | Handles the full lifecycle of a user's bill payment:
    |   index      → list all bills with search/filter
    |   create     → show the bill payment form
    |   store      → validate + debit wallet + create bill record
    |   show       → detail view of a single bill
    |   cancel     → user cancels a pending bill
    |--------------------------------------------------------------------------
    */

    /**
     * List all bill payments for the authenticated user.
     * Supports search (bill_number | biller_name | trx) and date filter.
     */
    public function index(Request $request)
    {
        $user = auth()->user();

        $bills = BillPayment::where('user_id', $user->id)
            ->when($request->search, fn($q) => $q->search($request->search))
            ->when($request->date,   fn($q) => $q->dateFilter($request->date))
            ->when($request->category, fn($q) => $q->byCategory($request->category))
            ->when($request->status !== null, fn($q) => $q->where('status', $request->status))
            ->latest()
            ->paginate(getPaginate());

        $emptyMessage = 'No bill payments found.';
        $pageTitle    = 'My Bill Payments';

        return view($this->activeTemplate . 'user.bill_payment.index', compact(
            'bills',
            'emptyMessage',
            'pageTitle'
        ));
    }

    /**
     * Show the bill payment form.
     */
    public function create(Request $request)
    {
        $user = auth()->user();

        $bills = BillPayment::where('user_id', $user->id)
            ->when($request->search, fn($q) => $q->search($request->search))
            ->when($request->date,   fn($q) => $q->dateFilter($request->date))
            ->when($request->category, fn($q) => $q->byCategory($request->category))
            ->when($request->status !== null, fn($q) => $q->where('status', $request->status))
            ->latest()
            ->paginate(getPaginate());

        $emptyMessage = 'No bill payments found.';
        $pageTitle    = 'My Bill Payments';
        $general      = gs();
        $pageTitle    = 'Pay a Bill';

        return view($this->activeTemplate . 'user.bills.index', compact(
             'bills',
            'emptyMessage',
            'pageTitle'
        ));
    }

    /**
     * Validate, debit wallet and persist a new bill payment.
     */
    public function store(Request $request)
    {
        $request->validate([
            'category'       => 'required|in:electricity,water,mobile,internet,rent,credit_card,insurance,education,mortgage,healthcare',
            'biller_name'    => 'required|string|max:255',
            'account_number' => 'required|string|max:255',
            'amount'         => 'required|numeric|gt:0',
            'due_date'       => 'nullable|date',
            'note'           => 'nullable|string|max:1000',
        ]);

        $user    = auth()->user();
        $general = gs();

        // Charge calculation (extend this with plan-based charges if needed)
        $charge      = 0;
        $finalAmount = $request->amount + $charge;

        // Insufficient balance check
        if ($user->balance < $finalAmount) {
            $notify[] = ['error', 'Insufficient balance to complete this payment.'];
            return back()->withNotify($notify);
        }

        DB::transaction(function () use ($request, $user, $general, $charge, $finalAmount) {

            // Debit user wallet
            $user->balance -= $finalAmount;
            $user->save();

            // Generate reference
            $trx        = getTrx();
            $billNumber = BillPayment::generateBillNumber();

            // Create bill record
            $bill = BillPayment::create([
                'user_id'        => $user->id,
                'bill_number'    => $billNumber,
                'category'       => $request->category,
                'biller_name'    => $request->biller_name,
                'account_number' => $request->account_number,
                'amount'         => $request->amount,
                'charge'         => $charge,
                'final_amount'   => $finalAmount,
                'currency'       => $general->cur_text,
                'post_balance'   => $user->balance,
                'due_date'       => $request->due_date,
                'note'           => $request->note,
                'status'         => BillPayment::STATUS_PROCESSING,
                'trx'            => $trx,
            ]);

            // Wallet transaction log
            $transaction               = new Transaction();
            $transaction->user_id      = $user->id;
            $transaction->amount       = $finalAmount;
            $transaction->post_balance = $user->balance;
            $transaction->charge       = $charge;
            $transaction->trx_type     = '-';
            $transaction->details      = 'Bill Payment — ' . $bill->category_label . ' (' . $bill->biller_name . ')';
            $transaction->trx          = $trx;
            $transaction->remark       = 'bill_payment';
            $transaction->save();
        });

        $notify[] = ['success', 'Bill payment submitted successfully.'];
        return redirect()->route('bills.create')->withNotify($notify);
    }

    /**
     * Show a single bill payment detail.
     */
    public function show(string $billNumber)
    {
        $user = auth()->user();

        $bill = BillPayment::where('user_id', $user->id)
            ->where('bill_number', $billNumber)
            ->firstOrFail();

        $general   = gs();
        $pageTitle = 'Bill Payment Detail';

        return view($this->activeTemplate . 'user.bill_payment.show', compact(
            'bill',
            'general',
            'pageTitle'
        ));
    }

    /**
     * Cancel a pending bill payment and refund the wallet.
     */
    public function cancel(string $billNumber)
    {
        $user = auth()->user();

        $bill = BillPayment::where('user_id', $user->id)
            ->where('bill_number', $billNumber)
            ->where('status', BillPayment::STATUS_PENDING)
            ->firstOrFail();

        DB::transaction(function () use ($bill, $user) {

            // Refund wallet
            $user->balance += $bill->final_amount;
            $user->save();

            // Update bill status
            $bill->status = BillPayment::STATUS_CANCELLED;
            $bill->save();

            // Refund transaction log
            $trx                       = getTrx();
            $transaction               = new Transaction();
            $transaction->user_id      = $user->id;
            $transaction->amount       = $bill->final_amount;
            $transaction->post_balance = $user->balance;
            $transaction->charge       = 0;
            $transaction->trx_type     = '+';
            $transaction->details      = 'Bill Payment Refund — ' . $bill->category_label . ' (' . $bill->biller_name . ')';
            $transaction->trx          = $trx;
            $transaction->remark       = 'bill_payment_refund';
            $transaction->save();
        });

        $notify[] = ['success', 'Bill payment cancelled and amount refunded to your wallet.'];
        return redirect()->route('user.bill.payment.index')->withNotify($notify);
    }

    /**
     * Download a PDF receipt for a completed bill payment.
     */
    public function download(string $billNumber)
    {
        $user = auth()->user();

        $bill = BillPayment::where('user_id', $user->id)
            ->where('bill_number', $billNumber)
            ->firstOrFail();

        $general = gs();

        return view($this->activeTemplate . 'user.bill_payment.download', compact(
            'bill',
            'general',
            'user'
        ));
    }
}
