<?php

namespace App\Http\Controllers;

use App\BankAccount;
use App\AccountToAccountTransection;
use App\Expense;
use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;
use Illuminate\Pagination\Paginator;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Validator;

class BankAccountController extends Controller
{

    public function __construct()
    {
        $this->middleware('can:create-bank_account',  ['only' => ['create', 'store']]);
        // $this->middleware('can:edit-bank_account',  ['only' => ['edit', 'update']]);
        $this->middleware('can:delete-bank_account', ['only' => ['destroy']]);
        $this->middleware('can:list-bank_account', ['only' => ['index']]);
        $this->middleware('can:show-bank_account', ['only' => ['show']]);


    }

    public function paginate($items, $perPage = 15, $page = null, $options = [])
    {
        $page = $page ?: (Paginator::resolveCurrentPage() ?: 1);

        $items = $items instanceof Collection ? $items : Collection::make($items);

        // return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, $options);
        return new LengthAwarePaginator($items->forPage($page, $perPage), $items->count(), $perPage, $page, ['path' => Paginator::resolveCurrentPath()]);
    }
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $accounts = BankAccount::all();
        return view('pages.account.index', compact('accounts'));
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $request)
    {
        // validate
        $request->validate([
            'name' => 'required|string',
        ]);

        // store
        BankAccount::create($request->all());

        session()->flash('success', 'Account Added!');
        return redirect()->back();
    }

    /**
     * Display the specified resource.
     *
     * @param  \App\BankAccount  $bankAccount
     * @return \Illuminate\Http\Response
     */
    public function show(BankAccount $bankAccount)
    {
        //
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  \App\BankAccount  $bankAccount
     * @return \Illuminate\Http\Response
     */
    public function edit(BankAccount $bankAccount)
    {
        $accounts = BankAccount::latest()->paginate(25);
        return view('pages.account.index',compact('accounts'))
            ->withBankAccount($bankAccount);
            // ->withBankAccounts($bankAccounts);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \App\BankAccount  $bankAccount
     * @return \Illuminate\Http\Response
     */
    public function update(Request $request, BankAccount $bankAccount)
    {
         $this->validate($request, [
            'name' => 'required|max:255'
        ]);
        $bankAccount->name = $request->name;
        $bankAccount->save();

        session()->flash('success', 'Bank Account Updated...');
        return redirect()->route('bank_account.index');
    
    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  \App\BankAccount  $bankAccount
     * @return \Illuminate\Http\Response
     */
    public function destroy(BankAccount $bankAccount)
    {
        if($bankAccount->delete()){
         session()->flash('success', 'Bank Account Deleted...');
        }else{
            session()->flash('warning', 'Opps...');
        }
        
        return redirect()->back();
    }

     public function transfer(BankAccount $account)
    {
        // dd("HELLO");
        // dd($account);
        return view('pages.account.form.transfer', compact('account'));
    }

    public function transfer_store(Request $request)
{
    $validator = Validator::make($request->all(), [
        "from" => "required|exists:bank_accounts,id",
        "to" => "required|exists:bank_accounts,id|different:from",
        "amount" => "required|numeric|min:1",
    ]);

    if ($validator->fails()) {
        return response()->json(['error' => $validator->errors()->all()]);
    }

    $fromAccount = BankAccount::findOrFail($request->from);
    $toAccount = BankAccount::findOrFail($request->to);
    $amount = $request->amount;

    // Check if source account has enough balance
    if ($fromAccount->current_balance < $amount) {
        return response()->json(['error' => ['Insufficient balance in source account!']]);
    }

    // Perform transfer inside DB transaction
    DB::transaction(function () use ($fromAccount, $toAccount, $amount, $request) {
        // Deduct from source
        $fromAccount->current_balance -= $amount;
        $fromAccount->save();

        // Add to destination
        $toAccount->current_balance += $amount;
        $toAccount->save();

        // Record transaction
        AccountToAccountTransection::create([
            'from' => $fromAccount->id,
            'to' => $toAccount->id,
            'amount' => $amount,
            'note' => $request->note,
        ]);
    });

    return response()->json(['success' => 'Money transferred successfully.']);
}


    public function add_money(BankAccount $bank_account)
    {
        return view('pages.account.form.add_balance', compact('bank_account'));
    }

    public function add_money_store(Request $request)
    {
        $request->validate([
            'to' => 'required|exists:bank_accounts,id',
            'amount' => 'required|numeric|min:0.01',
            'note' => 'nullable|string',
        ]);

        DB::transaction(function () use ($request) {

            // 1️⃣ Save transaction history
            AccountToAccountTransection::create([
                'to' => $request->to,
                'amount' => $request->amount,
                'note' => $request->note,
            ]);

            // 2️⃣ Increase bank balance
            $bank = BankAccount::findOrFail($request->to);
            $bank->current_balance += $request->amount;
            $bank->save();
        });

        return response()->json(['success' => 'Balance added successfully']);
    }

    public function withdraw_money(BankAccount $bank_account)
    {
        return view('pages.account.form.withdraw_balance', compact('bank_account'));
    }

    public function withdraw_money_store(Request $request)
    {
        $request->validate([
            'from' => 'required|exists:bank_accounts,id',
            'amount' => 'required|numeric|min:0.01',
            'note' => 'nullable|string',
        ]);

        DB::transaction(function () use ($request) {

            // 1️⃣ Save transaction history
            AccountToAccountTransection::create([
                'from' => $request->from,
                'amount' => $request->amount,
                'note' => $request->note,
            ]);

            // 2️⃣ Decrease bank balance
            $bank = BankAccount::findOrFail($request->from);
            $bank->current_balance -= $request->amount;
            $bank->save();
        });

        return response()->json(['success' => 'Withdraw Money Successfully.']);
    }


    public function history(BankAccount $account)
{
    // Incoming (Add balance / Receive)
    $received = AccountToAccountTransection::where('to', $account->id)
        ->select([
            'id',
            'amount',
            'note',
            'created_at as payment_date',
            DB::raw("'receive' as type"),
            DB::raw("'AccountToAccountTransection' as model"),
        ]);

    // Outgoing (Withdraw / Spend)
    $paid = AccountToAccountTransection::where('from', $account->id)
        ->select([
            'id',
            'amount',
            'note',
            'created_at as payment_date',
            DB::raw("'pay' as type"),
            DB::raw("'AccountToAccountTransection' as model"),
        ]);

    // Merge both
    $history = $received
        ->unionAll($paid)
        ->orderBy('payment_date', 'desc')
        ->paginate(20);

    return view('pages.account.history', compact('history', 'account'));
}


}
