<?php

namespace App\Http\Controllers;

use App\Models\Banking;
use App\Models\BankTransfar;
use App\Exports\BankTransfarExport;
use Maatwebsite\Excel\Facades\Excel;
use Brian2694\Toastr\Facades\Toastr;
use Illuminate\Http\Request;
use niklasravnsborg\LaravelPdf\Facades\Pdf;

class BankTransfarController extends Controller
{

    protected function buildFilteredQuery(Request $request)
    {
        $query = BankTransfar::with('bank')->orderBy('id', 'desc');

        if ($request->filled('search')) {
            $search = $request->get('search');
            $filterBy = $request->get('filter_by');

            $query->where(function ($q) use ($search, $filterBy) {
                // When a specific field is selected
                if ($filterBy === 'account_name' || $filterBy === 'account_no' || $filterBy === 'bank_name' || $filterBy === 'branch_name') {
                    $q->whereHas('bank', function ($qb) use ($search, $filterBy) {
                        if ($filterBy === 'account_name') {
                            $qb->where('account_name', 'like', '%' . $search . '%');
                        } elseif ($filterBy === 'account_no') {
                            $qb->where('account_no', 'like', '%' . $search . '%');
                        } elseif ($filterBy === 'bank_name') {
                            $qb->where('bank_name', 'like', '%' . $search . '%');
                        } elseif ($filterBy === 'branch_name') {
                            $qb->where('branch_name', 'like', '%' . $search . '%');
                        }
                    });
                } elseif ($filterBy === 'description') {
                    $q->where('description', 'like', '%' . $search . '%');
                } elseif ($filterBy === 'by') {
                    $q->where('by', 'like', '%' . $search . '%');
                } elseif ($filterBy === 'check_no') {
                    $q->where('check_no', 'like', '%' . $search . '%');
                } else {
                    // Default: search across all common fields
                    $q->whereHas('bank', function ($qb) use ($search) {
                        $qb->where('account_name', 'like', '%' . $search . '%')
                            ->orWhere('account_no', 'like', '%' . $search . '%')
                            ->orWhere('bank_name', 'like', '%' . $search . '%')
                            ->orWhere('branch_name', 'like', '%' . $search . '%');
                    })
                        ->orWhere('description', 'like', '%' . $search . '%')
                        ->orWhere('by', 'like', '%' . $search . '%')
                        ->orWhere('check_no', 'like', '%' . $search . '%');
                }
            });
        }

        if ($request->filled('date_from')) {
            $query->whereDate('created_at', '>=', $request->get('date_from'));
        }

        if ($request->filled('date_to')) {
            $query->whereDate('created_at', '<=', $request->get('date_to'));
        }

        return $query;
    }

    public function index(Request $request)
    {
        $query = $this->buildFilteredQuery($request);

        // Calculate totals for filtered data
        $totalTransactions = $query->count();
        $totalDeposits = $query->sum('diposit_amount') ?? 0;
        $totalWithdrawals = $query->sum('withdraw_amount') ?? 0;
        $netBalance = $totalDeposits - $totalWithdrawals;

        $bank_transfar = $query->paginate(50)->appends($request->query());

        // Get active bank accounts for edit modals
        $active_bank_accounts = Banking::where('status', 1)->get();

        return view("banking.bank_transfar", [
            'page_title' => "Bank Transfar",
            'bank_transfar' => $bank_transfar,
            'totalTransactions' => $totalTransactions,
            'totalDeposits' => $totalDeposits,
            'totalWithdrawals' => $totalWithdrawals,
            'netBalance' => $netBalance,
            'active_bank_accounts' => $active_bank_accounts,
        ]);
    }

    public function exportExcel(Request $request)
    {
        $query = $this->buildFilteredQuery($request);
        $data = $query->get();

        return Excel::download(new BankTransfarExport($data), 'bank_transactions_' . date('Y_m_d_H_i_s') . '.xlsx');
    }

    public function exportPdf(Request $request)
    {
        $query = $this->buildFilteredQuery($request);
        $data = $query->get();

        $pdf = Pdf::loadView('banking.bank_transfar_pdf', [
            'bank_transfar' => $data,
            'page_title' => 'Bank Transaction Report',
            'filters' => $request->all(),
        ]);

        return $pdf->download('bank_transactions_' . date('Y_m_d_H_i_s') . '.pdf');
    }

    public function diposit()
    {
        $account_information = Banking::where('status', 1)->get();
        return view("banking.diposit", [
            'page_title' => "Bank Account Diposit",
            'bank_accounts' => $account_information,
        ]);
    }

    public function dipositStore(Request $request)
    {
        $request->validate([
            'account_id' => 'required',
            'diposit_amount' => 'required',
            'by' => 'required',
        ]);
        $diposit = new BankTransfar();

        $diposit->account_id = $request->account_id;
        $diposit->diposit_amount = $request->diposit_amount;
        $diposit->description = $request->description;
        $diposit->by = $request->by;
        $diposit->save();

        Toastr::success('Bank Account Deposit Successfully', 'Success');

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Bank Account Deposit Successfully'
            ]);
        }

        return back();
    }

    public function withdraw()
    {
        $account_information = Banking::where('status', 1)->get();
        return view("banking.withdraw", [
            'page_title' => "Bank Account withdraw",
            'bank_accounts' => $account_information,
        ]);
    }

    public function withdrawStore(Request $request)
    {
        $request->validate([
            'account_id' => 'required',
            'withdraw_amount' => 'required',
            'by' => 'required',
        ]);

        $banking = Banking::find($request->account_id);
        $balance = $banking->opening_balance;

        $total_deposit = BankTransfar::where('account_id', $request->account_id)->sum('diposit_amount');
        $total_withdrawal = BankTransfar::where('account_id', $request->account_id)->sum('withdraw_amount');

        $balance += $total_deposit - $total_withdrawal;

        if($request->withdraw_amount > $balance){
            $errorMessage = 'Withdraw Amount is greater than Balance';
            Toastr::error($errorMessage, 'Error');

            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $errorMessage
                ], 400);
            }

            return back();
        }

        $withdraw = new BankTransfar();
        $withdraw->account_id = $request->account_id;
        $withdraw->check_no = $request->check_no;
        $withdraw->withdraw_amount = $request->withdraw_amount;
        $withdraw->description = $request->description;
        $withdraw->by = $request->by;
        $withdraw->save();

        Toastr::success('Bank Account Withdraw Successfully', 'Success');

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Bank Account Withdraw Successfully'
            ]);
        }

        return back();
    }

    public function approve($id)
    {
        $transection = BankTransfar::find($id);
        $transection->status = 1;
        $transection->save();

        Toastr::success('Bank Account Transection Approve Successfully', 'Success');
        return back();
    }

    public function edit($id)
    {
        $transection = BankTransfar::find($id);

        // Return JSON for AJAX requests
        if (request()->ajax()) {
            if($transection->diposit_amount != null){
                return response()->json([
                    'type' => 'deposit',
                    'id' => $transection->id,
                    'account_id' => $transection->account_id,
                    'diposit_amount' => $transection->diposit_amount,
                    'by' => $transection->by,
                    'description' => $transection->description,
                ]);
            }else{
                return response()->json([
                    'type' => 'withdraw',
                    'id' => $transection->id,
                    'account_id' => $transection->account_id,
                    'check_no' => $transection->check_no,
                    'withdraw_amount' => $transection->withdraw_amount,
                    'by' => $transection->by,
                    'description' => $transection->description,
                ]);
            }
        }

        $account_information = Banking::where('status', 1)->get();

        if($transection->diposit_amount != null){
            return view("banking.diposit_edit", [
                'page_title' => "Bank Account Diposit Edit",
                'bank_accounts' => $account_information,
                'transection' => $transection,
            ]);
        }else{
            return view("banking.withdraw_edit", [
                'page_title' => "Bank Account Withdraw Edit",
                'bank_accounts' => $account_information,
                'transection' => $transection,
            ]);
        }
    }

    public function dipositupdate(Request $request, $id)
    {
        $request->validate([
            'account_id' => 'required',
            'diposit_amount' => 'required',
            'by' => 'required',
        ]);

        $transection = BankTransfar::find($id);

        $transection->account_id = $request->account_id;
        $transection->diposit_amount = $request->diposit_amount;
        $transection->description = $request->description;
        $transection->by = $request->by;
        $transection->save();

        Toastr::success('Bank Account Transection Update Successfully', 'Success');

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Bank Account Transaction Updated Successfully'
            ]);
        }

        return redirect()->route('bank.index');
    }

    public function withdrawupdate(Request $request, $id)
    {
        $request->validate([
            'account_id' => 'required',
            'withdraw_amount' => 'required',
            'by' => 'required',
        ]);

        $banking = Banking::find($request->account_id);
        $balance = $banking->opening_balance;

        // Get current transaction to exclude it from balance calculation
        $currentTransaction = BankTransfar::find($id);

        // Calculate balance excluding current transaction
        $total_deposit = BankTransfar::where('account_id', $request->account_id)
            ->where('id', '!=', $id)
            ->sum('diposit_amount');
        $total_withdrawal = BankTransfar::where('account_id', $request->account_id)
            ->where('id', '!=', $id)
            ->sum('withdraw_amount');

        $balance += $total_deposit - $total_withdrawal;

        if($request->withdraw_amount > $balance){
            $errorMessage = 'Withdraw Amount is greater than Balance';
            Toastr::error($errorMessage, 'Error');

            if ($request->ajax()) {
                return response()->json([
                    'success' => false,
                    'message' => $errorMessage
                ], 400);
            }

            return back();
        }

        $transection = BankTransfar::find($id);

        $transection->account_id = $request->account_id;
        $transection->check_no = $request->check_no;
        $transection->withdraw_amount = $request->withdraw_amount;
        $transection->description = $request->description;
        $transection->by = $request->by;
        $transection->save();

        Toastr::success('Bank Account Transection Update Successfully', 'Success');

        if ($request->ajax()) {
            return response()->json([
                'success' => true,
                'message' => 'Bank Account Transaction Updated Successfully'
            ]);
        }

        return redirect()->route('bank.index');
    }

    public function delete($id)
    {
        $transection = BankTransfar::find($id);
        $transection->delete();

        Toastr::success('Bank Account Transection Delete Successfully', 'Success');
        return back();
    }
}
