<?php
namespace App\Http\Controllers\Admin\accounting;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Helpers\LogActivity;
use App\Models\{
    User,
    Role,
    School,
    Plan
};
use App\Models\accounting\{
    AccountLedger,
    AccountLedgerGroup,
    AccountBank,
    AccountItem,
    AccountItemUnit,
    AccountItemCategory,
    AccountCustomer,
    AccountDebitNote,
    AccountDebitNoteItem,
    AccountInvoice,
    AccountPurchaseBill,
    AccountExpense,
    AccountExpenseDetail,
    AccountExpenseDetailItem,
    AccountPaymentReceive,
    AccountPaymentReceiveDetail,
};
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Str;
use App\Exports\PaymentExport;
use Maatwebsite\Excel\Facades\Excel;
use Validator;

class PaymentController extends Controller
{
    protected $admin_id;
    protected $school_id, $res,$allData,$data,$validate;
    public function __construct()
    {
        $this->middleware(function ($request, $next) {
            // fetch session and use it in entire class with constructor
            if (session()->get('loggedIn')['user_type'] == 'admin') {
                $this->admin_id = session()->get('loggedIn')['id'];
                $this->school_id = School::where("admin_id",$this->admin_id)->pluck("id")->first();
            } else {
                $this->admin_id = session()->get('loggedIn')['admin_id'];
                $this->school_id = School::where("admin_id",$this->admin_id)->pluck("id")->first();
            }
         
            return $next($request);
        });
    }

    public function export()
    {        
        $filename = "payments.xlsx";
        return Excel::download(new PaymentExport($this->admin_id),$filename);
        
    }

     // Display all employees
     public function index()
     {
        $data['pagetitle'] = "account";
        $data['mainSuperAdminMenu'] = 'payment';
        $data['superadminSubMenu'] = 'payment';

        $search = isset($_GET["search"]) ? $_GET["search"] : null;
        $date = isset($_GET["date"]) ? $_GET["date"] : null;
        $vendor_name = isset($_GET["vendor_name"]) ? $_GET["vendor_name"] : null;
        
        
        $start_date = isset($_GET["start_date"]) ? $_GET["start_date"] : null;
        $end_date = isset($_GET["end_date"]) ? $_GET["end_date"] : null;
        $type = isset($_GET["type"]) ? $_GET["type"] : null;
       
       
        $query = AccountPaymentReceive::where('account_payment_receives.admin_id',$this->admin_id)
        ->leftJoin("account_customers as customer","customer.id","=","account_payment_receives.client_id");
                

        if($search)
        {
            $query->where('account_payment_receives.expense_number', 'LIKE', '%' . $search . '%');
            
        }
        if($type)
        {
            $query->where('account_payment_receives.type', $type);
            
        }
        if($date)
        {
            $query->whereDate('account_payment_receives.date', $date);
            
        }
        if($vendor_name)
        {
            $query->where('customer.name','LIKE', '%'.$vendor_name.'%');
            
        }
        
        if($start_date && $end_date)
        {
            $query->whereDate('account_payment_receives.created_at','>=', $start_date);
            $query->whereDate('account_payment_receives.created_at','<=', $end_date);
            
        }

        

        $data['payments'] = $query->select(
            "account_payment_receives.*",
            "customer.name as customer_name"
        )->orderBy('account_payment_receives.created_at','desc')->paginate(10);
       
        
        return view('accounting.payments.list',$data);
     }
 
     // Show the form to create a new product
     public function create()
     {
       
        $data['pagetitle'] = "account";
        $data['mainSuperAdminMenu'] = 'payment';
        $data['superadminSubMenu'] = 'payment';

        
        $payment_number = 1;
        
        $res = AccountPaymentReceive::latest()->select("payment_number")->first();

        if($res)
        {
            $payment_number = $res->payment_number + 1;
            
        }
        

        $data["payment_number"] = $payment_number;

        $customer_id = isset($_GET["customer_id"]) ? $_GET["customer_id"] : null;
        $time_duration = isset($_GET["time_duration"]) ? $_GET["time_duration"] : null;

        $data['categories'] = AccountItemCategory::where("admin_id",$this->admin_id)->get();
        $data['units'] = AccountItemUnit::where("admin_id",$this->admin_id)->get();
        $data['items'] = AccountExpense::where("admin_id",$this->admin_id)->get();
        $data['vendors'] = AccountCustomer::where("admin_id",$this->admin_id)->where("type","creditor")->get();
        $data["taxes"] = DB::table("account_tax_slabs")->get();

        
        $data['clients'] = AccountCustomer::where("admin_id",$this->admin_id)->where("type","debitor")->get();

        $query = AccountInvoice::where("account_invoices.admin_id",$this->admin_id)
        ->where("account_invoices.status","unpaid")
        ->leftJoin("account_customers","account_customers.id","=","account_invoices.customer_id");

        if($customer_id)
        {
            $query->where("account_invoices.customer_id","=", $customer_id);
        }
        if($time_duration)
        {
            if ($time_duration) {
                $now = now(); // Current date/time
                
                switch ($time_duration) {
                    case "this_month":
                        $query->whereMonth('account_invoices.created_at', $now->month)
                              ->whereYear('account_invoices.created_at', $now->year);
                        break;
                        
                    case "last_month":
                        $lastMonth = $now->subMonth();
                        $query->whereMonth('account_invoices.created_at', $lastMonth->month)
                              ->whereYear('account_invoices.created_at', $lastMonth->year);
                        break;
                        
                    case "last_six_month":
                        $sixMonthsAgo = $now->subMonths(6);
                        $query->where('account_invoices.created_at', '>=', $sixMonthsAgo);
                        break;
                        
                    case "this_year":
                        $query->whereYear('account_invoices.created_at', $now->year);
                        break;
                        
                    case "last_year":
                        $lastYear = $now->subYear();
                        $query->whereYear('account_invoices.created_at', $lastYear->year);
                        break;
                        
                    case "all":
                        // No date filter needed - show all records
                        break;
                        
                    default:
                        // Optionally handle unexpected values
                        break;
                }
            }
        }

        $data["invoices"] = $query->orderBy("account_invoices.created_at","desc")
        ->select(
            "account_invoices.*",
            "account_customers.name as client_name"
        )
        ->paginate(10);


        return view('accounting.payments.add',$data);
     }
     
     public function storePaymentReceive(Request $request)
     {
                
        $this->allData = $request->all();       
       
        //return $this->allData;
        $this->validate = Validator::make($request->all(),[
            "client_id"=>"required",
            "payment_number"=>"required",
            "date"=>"required",
            "payment_method"=>"required",
            "amount"=>"required"
            
        ]);

        if($this->validate->fails())
        {
            return back()->withErrors($this->validate)->withInput();
        }

        if(isset($request->payment_received_id) && !empty($request->payment_received_id))
        {
            unset($this->allData["payment_received_id"]);
            unset($this->allData["_token"]);
            unset($this->allData["invoice_id"]);
            unset($this->allData["payment_value"]);        
            

            $this->res = AccountPaymentReceive::where("id",$request->payment_received_id)->update($this->allData);

            if($this->res)
            {
                if (isset($request->invoice_id) && is_array($request->invoice_id)) 
                {
                    foreach ($request->invoice_id as $i=>$id) 
                    {
                        $fetch_invoice = AccountInvoice::where("id",$id)->first();
                        if($fetch_invoice)
                        {
                            $amount_due = intVal($fetch_invoice->amount_due) - intVal($request->payment_value[$i]);
                            
                            if($amount_due<0)
                            {
                                return back()->with("error","Received payment is greater than Due Amount \n if you want to advance payment choose advance payment option !");
                            }
                            if($amount_due==0)
                            {
                                AccountInvoice::where("id",$id)->update(["status"=>"paid"]);
                            }
                                
                            $payemntDetails = AccountPaymentReceiveDetail::where("invoice_id",$id)
                            ->where("payment_id",$request->payment_received_id)
                            ->update([
                                "payment_value"=>$request->payment_value[$i] ?? 0
                            ]);
                            
                            AccountInvoice::where("id",$id)->update(["amount_due"=>$amount_due]);

                        }
                    }
                }
                return back()->with("success","Payment update successfully !");
            }
            return back()->with("error","failed !");
        }

        $this->allData["admin_id"] = $this->admin_id;
        $this->allData["type"] = "received";

        unset($this->allData["payment_received_id"]);
        unset($this->allData["invoice_id"]);
        unset($this->allData["payment_value"]);

        

        $this->res = AccountPaymentReceive::create($this->allData);

        if($this->res)
        {
            if (isset($request->invoice_id) && is_array($request->invoice_id)) 
            {
                foreach ($request->invoice_id as $i=>$id) 
                {
                    $fetch_invoice = AccountInvoice::where("id",$id)->first();
                    if($fetch_invoice)
                    {
                        $amount_due = intVal($fetch_invoice->amount_due) - intVal($request->payment_value[$i]);
                        
                        if($amount_due<0)
                        {
                            return back()->with("error","Received payment is greater than Due Amount \n if you want to advance payment choose advance payment option !");
                        }
                        if($amount_due==0)
                        {
                            AccountInvoice::where("id",$id)->update(["status"=>"paid"]);
                        }
                            
                        $payemntDetails = AccountPaymentReceiveDetail::create([
                            "payment_id"=>$this->res->id,
                            "admin_id"=>$this->admin_id,
                            "invoice_id"=>$id,
                            "payment_value"=>$request->payment_value[$i] ?? 0,
                            "type"=>"received"
                        ]);
                        
                        AccountInvoice::where("id",$id)->update(["amount_due"=>$amount_due]);

                    }
                }
            }
            
            return back()->with("success","Payment received successfully !");
        }
        return back()->with("success","failed !");
     }
     
 
     // Show the form to edit an existing product
     public function edit($id)
     {        
        
        $data['pagetitle'] = "account";
        $data['mainSuperAdminMenu'] = 'payment';
        $data['superadminSubMenu'] = 'payment';

        $customer_id = isset($_GET["customer_id"]) ? $_GET["customer_id"] : null;
        $time_duration = isset($_GET["time_duration"]) ? $_GET["time_duration"] : null;

        $data["payment"] = AccountPaymentReceive::where("id",$id)->first();
        $data["payment_details"] = AccountPaymentReceiveDetail::where("payment_id",$id)->get();

        $data['categories'] = AccountItemCategory::where("admin_id",$this->admin_id)->get();
        $data['units'] = AccountItemUnit::where("admin_id",$this->admin_id)->get();
        $data['items'] = AccountExpense::where("admin_id",$this->admin_id)->get();
        $data['vendors'] = AccountCustomer::where("admin_id",$this->admin_id)->where("type","creditor")->get();
        $data["taxes"] = DB::table("account_tax_slabs")->get();


        
        $data['clients'] = AccountCustomer::where("admin_id",$this->admin_id)->where("type","debitor")->get();

        $query = AccountInvoice::where("account_invoices.admin_id",$this->admin_id)
        ->where("account_invoices.status","unpaid")
        ->leftJoin("account_customers","account_customers.id","=","account_invoices.customer_id");

        if($customer_id)
        {
            $query->where("account_invoices.customer_id","=", $customer_id);
        }
        if($time_duration)
        {
            if ($time_duration) {
                $now = now(); // Current date/time
                
                switch ($time_duration) {
                    case "this_month":
                        $query->whereMonth('account_invoices.created_at', $now->month)
                              ->whereYear('account_invoices.created_at', $now->year);
                        break;
                        
                    case "last_month":
                        $lastMonth = $now->subMonth();
                        $query->whereMonth('account_invoices.created_at', $lastMonth->month)
                              ->whereYear('account_invoices.created_at', $lastMonth->year);
                        break;
                        
                    case "last_six_month":
                        $sixMonthsAgo = $now->subMonths(6);
                        $query->where('account_invoices.created_at', '>=', $sixMonthsAgo);
                        break;
                        
                    case "this_year":
                        $query->whereYear('account_invoices.created_at', $now->year);
                        break;
                        
                    case "last_year":
                        $lastYear = $now->subYear();
                        $query->whereYear('account_invoices.created_at', $lastYear->year);
                        break;
                        
                    case "all":
                        // No date filter needed - show all records
                        break;
                        
                    default:
                        // Optionally handle unexpected values
                        break;
                }
            }
        }

        $data["invoices"] = $query->orderBy("account_invoices.created_at","desc")
        ->select(
            "account_invoices.*",
            "account_customers.name as client_name"
        )
        ->paginate(10);


        return view('accounting.payments.edit',$data);
     }
 
     public function getReceipt($id)
     {
        
        $data['pagetitle'] = "account";
        $data['mainSuperAdminMenu'] = 'payment';
        $data['superadminSubMenu'] = 'payment';

        $data['invoice'] = AccountPaymentReceive::where("account_payment_receives.id",$id)
        ->leftJoin("account_customers","account_customers.id","=","account_payment_receives.client_id")
        ->leftJoin("states","states.id","=","account_customers.shipping_state")
        ->select(
            "account_payment_receives.*",
            "account_customers.name as customer_name",
            "account_customers.billing_address",
            "account_customers.billing_city",
            "account_customers.billing_country",
            "account_customers.billing_state",
            "account_customers.gstin",
            "account_customers.shipping_address",
            "account_customers.shipping_city",
            "account_customers.shipping_country",
            "account_customers.shipping_state",
            "account_customers.email",
            "account_customers.mobile",
            "states.state_name"

        )
        ->first(); 
        
        $data['invoice_items'] = AccountPaymentReceiveDetail::where("account_payment_receive_details.payment_id",$id)
        ->leftJoin("account_invoices","account_invoices.id","=","account_payment_receive_details.invoice_id")
        ->select(
            "account_payment_receive_details.*",
            "account_invoices.invoice_number",
            "account_invoices.due_date",
            "account_invoices.amount_due",
            
        )
        ->get();
        
        $data['categories'] = AccountItemCategory::where("admin_id",$this->admin_id)->get();
        $data['units'] = AccountItemUnit::where("admin_id",$this->admin_id)->get();
        $data['items'] = AccountItem::where("admin_id",$this->admin_id)->get();
        $data["taxes"] = DB::table("account_tax_slabs")->get();

        return view('accounting.payments.receipt',$data); 
     }
     
     // Delete a product
     public function delete(Request $request)
     {
        //return $request->id;

         $this->res = AccountPaymentReceive::where('id',$request->id)->delete();
         if($this->res)
         {
            AccountPaymentReceiveDetail::where('payment_id',$request->id)->delete();

            $logMessage = $request->rolename . ' Payment delete successfully!';
			    LogActivity::addToLog($logMessage);
                
            
            return response()->json(["message"=>"success"],200);
         }
         
            return response()->json(["message"=>"failed"],424);
         
     }

     public function deleteMultiple(Request $request)
     {
        
        $this->res = AccountPaymentReceive::whereIn('id',$request->ids)->delete();
        if($this->res)
        {
            AccountPaymentReceiveDetail::whereIn('payment_id',$request->ids)->delete();

           $logMessage = $request->rolename . ' Payment delete successfully!';
               LogActivity::addToLog($logMessage);
               
           
           return response()->json(["message"=>"success"],200);
        }
        
           return response()->json(["message"=>"failed"],424);
     }


     //payment made code

     public function paymentMadeAdd()
     {
        $data['pagetitle'] = "account";
        $data['mainSuperAdminMenu'] = 'payment';
        $data['superadminSubMenu'] = 'payment';

        $customer_id = isset($_GET["vendor_id"]) ? $_GET["vendor_id"] : null;
        $time_duration = isset($_GET["time_duration"]) ? $_GET["time_duration"] : null;

        
        $payment_number = 1;
        
        $res = AccountPaymentReceive::latest()->select("payment_number")->first();

        if($res)
        {
            $payment_number = $res->payment_number + 1;
            
        }
        

        $data["payment_number"] = $payment_number;

        $data['categories'] = AccountItemCategory::where("admin_id",$this->admin_id)->get();
        $data['units'] = AccountItemUnit::where("admin_id",$this->admin_id)->get();
        $data['items'] = AccountExpense::where("admin_id",$this->admin_id)->get();
        $data['vendors'] = AccountCustomer::where("admin_id",$this->admin_id)->where("type","creditor")->get();
        $data["taxes"] = DB::table("account_tax_slabs")->get();

        
       // $data['clients'] = AccountCustomer::where("admin_id",$this->admin_id)->where("type","debitor")->get();

        $query = AccountPurchaseBill::where("account_purchase_bills.admin_id",$this->admin_id)
        ->where("account_purchase_bills.status","!=","paid")
        ->leftJoin("account_customers","account_customers.id","=","account_purchase_bills.vendor_id");

        if($customer_id)
        {
            $query->where("account_purchase_bills.vendor_id","=", $customer_id);
        }
        if($time_duration)
        {
            if ($time_duration) {
                $now = now(); // Current date/time
                
                switch ($time_duration) {
                    case "this_month":
                        $query->whereMonth('account_purchase_bills.created_at', $now->month)
                              ->whereYear('account_purchase_bills.created_at', $now->year);
                        break;
                        
                    case "last_month":
                        $lastMonth = $now->subMonth();
                        $query->whereMonth('account_purchase_bills.created_at', $lastMonth->month)
                              ->whereYear('account_purchase_bills.created_at', $lastMonth->year);
                        break;
                        
                    case "last_six_month":
                        $sixMonthsAgo = $now->subMonths(6);
                        $query->where('account_purchase_bills.created_at', '>=', $sixMonthsAgo);
                        break;
                        
                    case "this_year":
                        $query->whereYear('account_purchase_bills.created_at', $now->year);
                        break;
                        
                    case "last_year":
                        $lastYear = $now->subYear();
                        $query->whereYear('account_purchase_bills.created_at', $lastYear->year);
                        break;
                        
                    case "all":
                        // No date filter needed - show all records
                        break;
                        
                    default:
                        // Optionally handle unexpected values
                        break;
                }
            }
        }

        $data["invoices"] = $query->orderBy("account_purchase_bills.created_at","desc")
        ->select(
            "account_purchase_bills.*",
            "account_customers.name as client_name"
        )
        ->paginate(10);
       
        
        return view('accounting.payments.payment_made.add',$data);
     }

     public function savePaymentMade(Request $request)
     {
        
        $this->allData = $request->all();       
       
        //return $this->allData;
        $this->validate = Validator::make($request->all(),[
            "client_id"=>"required",
            "payment_number"=>"required",
            "date"=>"required",
            "payment_method"=>"required",
            "amount"=>"required"
            
        ]);

        if($this->validate->fails())
        {
            return back()->withErrors($this->validate)->withInput();
        }

        if(isset($request->payment_received_id) && !empty($request->payment_received_id))
        {
            unset($this->allData["payment_received_id"]);
            unset($this->allData["_token"]);
            unset($this->allData["invoice_id"]);
            unset($this->allData["payment_value"]);        
            unset($this->allData["amount_due"]);

            $this->res = AccountPaymentReceive::where("id",$request->payment_received_id)->update($this->allData);

            if($this->res)
            {
                if (isset($request->invoice_id) && is_array($request->invoice_id)) 
                {
                    foreach ($request->invoice_id as $i=>$id) 
                    {
                        $fetch_invoice = AccountPurchaseBill::where("id",$id)->first();
                        if($fetch_invoice)
                        {
                            $amount_due = intVal($request->amount_due) - intVal($request->payment_value[$i]);
                            
                            if($amount_due<0)
                            {
                                return $amount_due; back()->with("error","payment is greater than Due Amount \n if you want to advance payment choose advance payment option !");
                            }

                            if($amount_due == 0)
                            {
                                AccountPurchaseBill::where("id",$id)->update(["status"=>"paid"]);
                            }
                                
                            $payemntDetails = AccountPaymentReceiveDetail::where("invoice_id",$id)
                            ->where("payment_id",$request->payment_received_id)
                            ->update([
                                "payment_value"=>$request->payment_value[$i] ?? 0
                            ]);
                            
                            AccountPurchaseBill::where("id",$id)->update(["amount_due"=>$amount_due]);

                        }
                    }
                }
                return back()->with("success","Payment update successfully !");
            }
            return back()->with("error","failed !");
        }

        $this->allData["admin_id"] = $this->admin_id;
        

        unset($this->allData["payment_received_id"]);
        unset($this->allData["invoice_id"]);
        unset($this->allData["payment_value"]);

        

        $this->res = AccountPaymentReceive::create($this->allData);

        if($this->res)
        {
            if (isset($request->invoice_id) && is_array($request->invoice_id)) 
            {
                foreach ($request->invoice_id as $i=>$id) 
                {
                    $fetch_invoice = AccountPurchaseBill::where("id",$id)->first();
                    if($fetch_invoice)
                    {
                        $amount_due = intVal($fetch_invoice->amount_due) - intVal($request->payment_value[$i]);
                        
                        if($amount_due<0)
                        {
                            return back()->with("error","payment is greater than Due Amount \n if you want to advance payment choose advance payment option !");
                        }

                        if($amount_due == 0)
                        {
                            AccountPurchaseBill::where("id",$id)->update(["status"=>"paid"]);
                        }
                            
                        $payemntDetails = AccountPaymentReceiveDetail::create([
                            "payment_id"=>$this->res->id,
                            "admin_id"=>$this->admin_id,
                            "invoice_id"=>$id,
                            "payment_value"=>$request->payment_value[$i] ?? 0,
                            "type"=>"payment"
                        ]);
                        
                        AccountPurchaseBill::where("id",$id)->update(["amount_due"=>$amount_due]);

                    }
                }
            }
            
            return back()->with("success","Payment done successfully !");
        }
        return back()->with("success","failed !");
     }

     

     public function editPaymentMade($id)
     {
        $data['pagetitle'] = "account";
        $data['mainSuperAdminMenu'] = 'payment';
        $data['superadminSubMenu'] = 'payment';

        $customer_id = isset($_GET["customer_id"]) ? $_GET["customer_id"] : null;
        $time_duration = isset($_GET["time_duration"]) ? $_GET["time_duration"] : null;

        $data["payment"] = AccountPaymentReceive::where("id",$id)->first();
        $data["payment_details"] = AccountPaymentReceiveDetail::where("payment_id",$id)->get();

        $data['categories'] = AccountItemCategory::where("admin_id",$this->admin_id)->get();
        $data['units'] = AccountItemUnit::where("admin_id",$this->admin_id)->get();
        $data['items'] = AccountExpense::where("admin_id",$this->admin_id)->get();
        $data['vendors'] = AccountCustomer::where("admin_id",$this->admin_id)->where("type","creditor")->get();
        $data["taxes"] = DB::table("account_tax_slabs")->get();


        
        $data['clients'] = AccountCustomer::where("admin_id",$this->admin_id)->where("type","debitor")->get();

        $query = AccountPurchaseBill::where("account_purchase_bills.admin_id",$this->admin_id)
        ->leftJoin("account_customers","account_customers.id","=","account_purchase_bills.vendor_id");

        if($customer_id)
        {
            $query->where("account_purchase_bills.customer_id","=", $customer_id);
        }
        if($time_duration)
        {
            if ($time_duration) {
                $now = now(); // Current date/time
                
                switch ($time_duration) {
                    case "this_month":
                        $query->whereMonth('account_purchase_bills.created_at', $now->month)
                              ->whereYear('account_purchase_bills.created_at', $now->year);
                        break;
                        
                    case "last_month":
                        $lastMonth = $now->subMonth();
                        $query->whereMonth('account_purchase_bills.created_at', $lastMonth->month)
                              ->whereYear('account_purchase_bills.created_at', $lastMonth->year);
                        break;
                        
                    case "last_six_month":
                        $sixMonthsAgo = $now->subMonths(6);
                        $query->where('account_purchase_bills.created_at', '>=', $sixMonthsAgo);
                        break;
                        
                    case "this_year":
                        $query->whereYear('account_purchase_bills.created_at', $now->year);
                        break;
                        
                    case "last_year":
                        $lastYear = $now->subYear();
                        $query->whereYear('account_purchase_bills.created_at', $lastYear->year);
                        break;
                        
                    case "all":
                        // No date filter needed - show all records
                        break;
                        
                    default:
                        // Optionally handle unexpected values
                        break;
                }
            }
        }

        $data["invoices"] = $query->orderBy("account_purchase_bills.created_at","desc")
        ->select(
            "account_purchase_bills.*",
            "account_customers.name as client_name"
        )
        ->paginate(10);


        return view('accounting.payments.payment_made.edit',$data);  
     }
     

     

}
