<?php

namespace App\Http\Controllers;
use App\Head;
use App\Account;
use App\Payment;
use App\Commission;
use App\GenericType;
use App\Installment;
use Illuminate\Http\Request;
use Spatie\Permission\Models\Role;
use App\Http\Requests\PaymentRequest;
use Illuminate\Contracts\Encryption\DecryptException;
use Gisplus\Package\EstatechVendor\Models\Invoice;
use App\VendorPayment;
use App\Inventory\Payable;
use Crypt;
use EF;

class PaymentController extends Controller
{
    public function __construct()
    {


       $this->generic_index = EF::getGenericTableIndex();
    }
    public function index()
    {
    	$payment = new Payment;
        $head    = new Head;


    	return view('payments.manage_payments',
    		[
                'payment_list' => $payment->getAllPayments(['Unapprove']),
                'head_list'    =>  $head->getAllHeads(),
                'unique_id'    =>  uniqid(),


    	]);
    }

    
    public function inventoryPendingPayments()
    {
    	$payment = new Payment;
        $head    = new Head;

        $payment_status  =  ['Approve','Unapprove','Reversal','Reject'];

    	return view('payments.manage_payments',
    		[

                'payment_list' => $payment->getAllPayablePaymentList(EF::getGenericTableIndex()['Inventory Payable'],$payment_status),
                'head_list'    =>  $head->getAllHeads(),
                'unique_id'    =>  uniqid(),
    	]);
    }

    public function payPayment(Request $request)
    {
    	try
        {

        	$payment = new Payment;
        
            $payable = new Payable;

            $form_collect = $request->input();
            
            $form_collect['generic']       = decrypt($form_collect['generic']);

        	$form_collect['generic_type']  = decrypt($form_collect['generic_type']);

            $generic_index = EF::getGenericTableIndex();
            
            if($form_collect['generic_type'] == $generic_index['Inventory Payable'])
            {

                $curr_payable = $payable->getPayableById($form_collect['generic']);
               
                if($form_collect['amount'] > $curr_payable->total_amount)
                {
                    parent::errorMessage('Amount must be less than the total amount');
                }
                else{
        	        $payment = $payment->payGenericPayment($form_collect);
                }

            }
        
            else{
                $payment = $payment->payGenericPayment($form_collect);
            }

            if (isset($form_collect['role'])) {
                $form_collect['role']          = decrypt($form_collect['role']);
            }

        	if($payment->id)
        	{
               	parent::successMessage('Payment has been created.');

        	}

		}
        catch (DecryptException $e)
        {

        }

        return redirect()->back();
    }

    public function updatePayPayment(PaymentRequest $request)
    {
    	try
        {
        	$form_collect = $request->input();

            $generic_index = EF::getGenericTableIndex();

        	$form_collect['payment'] = decrypt($form_collect['payment']);
            
            $payment = new Payment;

            $curr_payment = $payment->getPaymentById($form_collect['payment']);

            if($curr_payment->generic_type_id == $generic_index['Inventory Payable'])
            {
               
                if($form_collect['amount'] > $curr_payment->amount)
                {
                    parent::errorMessage('Amount must be less than the total amount');
                }
                else{
                    $payment = $payment->updatePayGenericPayment($form_collect);
                }

            }
        
            else{
                $payment = $payment->updatePayGenericPayment($form_collect);
            }
            
            if (isset($form_collect['role'])) {
                $form_collect['role']          = decrypt($form_collect['role']);
            }

        	if($payment->id)
        	{
               	parent::successMessage('payment has been updated.');

        	}

		}
        catch (DecryptException $e)
        {

        }

        return redirect()->back();
    }

    public function removePayment($id)
    {


        parent::errorMessage('Payment not found.');

        try
        {
            $id = decrypt($id);

            $payment = new Payment;

            if($payment->removePayment($id))
            {
                parent::successMessage('Payment has been removed.');
            }
        }
        catch (DecryptException $e)
        {

        }

        return redirect()->back();
    }


    public function getBookingPaymentDropdown($id)
    {
        if(\Request::ajax())
        {
            $data['payment_view'] = '<option value="'.Crypt::encrypt(0).'">Select Payment</option>';

            try
            {
                $payment_list = EF::getPaymentType();

                $payment_list += ['Token'];

                $id = decrypt($id);

                $payment = new Payment;



                $payment_list = $payment->getBookingPayments($id,$payment_list,['Unapprove']);

                $data['payment_view'] = '<option value="'.Crypt::encrypt(0).'">Select Payment</option>';

                foreach($payment_list as $rows)
                {
                   $data['payment_view'] .= '<option value="'.Crypt::encrypt($rows->id).'">'.$rows->description.'</option>';
                }

            }
            catch (DecryptException $e)
            {

            }


           return $data;

        }


        return redirect()->back();
    }

    public function getPaymentById($id)
    {
        if(\Request::ajax())
        {
            $data['amount']           = 0;
            $data['date']             = '';
            $data['mode']             = '';
            $data['insrument']        = '';
            $data['insrument_date']   = '';
            $data['drawn_on']         = '';
            $data['deposit_no']         = '';
            $data['deposit_date']         = '';






            $data['type'] = ' ';

            $data['user_view'] = '<select><option value='.Crypt::encrypt(0).'>Select User</option></select>';


            try
            {
                $id = decrypt($id);

                $payment = new Payment;

                $curr_payment = $payment->getPaymentById($id);

                if(isset($curr_payment->id))
                {
                    $user = $curr_payment->user;

                    $data['amount'] = $curr_payment->amount;

                    $data['mode']   = $curr_payment->mode;

                    $data['instrument']   = $curr_payment->instrument;

                    $data['instrument_date']   = str_replace('1970-01-01','',date('Y-m-d',strtotime($curr_payment->instrument_date)));

                    $data['drawn_on']   = $curr_payment->drawn_on;

                    $data['deposit_no']   = $curr_payment->deposit_no;

                    $data['deposit_date']   = str_replace('1970-01-01','',date('Y-m-d',strtotime($curr_payment->deposit_date)));





                    $data['user_view'] = '<select><option value='.Crypt::encrypt($user->id).'>'.$user->name.'</option></select>';

                    $data['type'] = $curr_payment->role->name;

                }

            }
            catch (DecryptException $e)
            {

            }

           return $data;

        }


        return redirect()->back();
    }

    public function showPayPaymentModel($type,$generic_id)
    {
        try
        {
            $generic_index = EF::getGenericTableIndex();
            $data = [

                'branch_name'      => '',
                'user_type'        => '',
                'user_name'        => '',
                'booking_name'     => '',
                'payment_type'     => '',
                'description'      => '',
                'amount'           => 0,
                'generic'          => $generic_id, //ENCRYPTED
                'generic_type'     => $type,      // ENCRYPTED
                'section'          => '',
                'receipt'          => NULL,


            ];

            $generic_id = decrypt($generic_id);
            $type       = decrypt($type);

            if($type === $generic_index["Installment"])
            {
                $installment = new Installment;

                $installment = $installment->getInstallmentById($generic_id);

                $payment = new Payment;

                $code =  $payment->generateReceiptNumber($installment->booking->branch->id);

                if(isset($code['code']))
                {
                   $code = $code['code'];
                }
                else
                {
                   $code = 0;
                }

                $role = new Role;

                $role = $role->findByName('Customer');


                $data['branch_name']    = $installment->booking->branch->name;
                if (isset($role->id)) {
                    $data['user_type']      = $role->name;
                    $data['role']           = encrypt($role->id);
                }

                if(isset($installment->id))
                {
                    $role = new Role;

                    $role = $role->findByName('Customer');

                    if (isset($role->id)) {
                        $data['user_type']      = $role->name;
                        $data['role']           = encrypt($role->id);
                    }

                    $data['branch_name']    = $installment->booking->branch->name;
                    // $data['user_type']      = $installment->booking->role->name;
                    $data['user_name']      = $installment->booking->user->name;
                    $data['booking_name']   = EF::showPlotFormat($installment->booking->plot);
                    $data['payment_type']   = $installment->type_of_installment;
                    $data['description']    = $installment->description;
                    $data['amount']         = $installment->amount - $installment->received_amount;
                    $data['section']        = 'Booking Information';

                    $data['receipt']        = $code;

                }

            }
            elseif($type === $generic_index["Commission"])
            {
                $commission = new Commission;

                $commission = $commission->getCommissionById($generic_id);

                // dd($commission);

                if(isset($commission->id))
                {
                    if (isset($commission->role_id)) {
                        $role = new Role;

                        $role = $role->findById($commission->role_id);

                        if (isset($role->id)) {
                            $data['user_type']        = $role->name;
                            $data['role']             = encrypt($role->id);
                        }
                    }
                    $data['branch_name']    = $commission->booking->branch->name;
                    // $data['user_type']      = $commission->booking->user->type;
                    $data['user_name']      = $commission->booking->user->name;
                    $data['booking_name']   = EF::showPlotFormat($commission->booking->plot);
                    $data['payment_type']   = $commission->payment_type;
                    $data['description']    = $commission->description;

                    $data['amount']         = $commission->amount - $commission->received_amount;

                    if (isset($commission->role_id)) {
                        $role = new Role;

                        $role = $role->findById($commission->role_id);

                        if (isset($role->id)) {
                            $data['user_type']        = $role->name;
                            $data['role']             = encrypt($role->id);
                        }
                    }
                }
            }
            elseif($type === $generic_index["Invoice"])
            {
                $invoice = new Invoice;

                $invoice = $invoice->getInvoiceById($generic_id);

                //dd($invoice);

                if(isset($invoice->id))
                {
                    $description = $invoice->purchaseItems->pluck('description')->toarray();
                    
                    $description = implode(',',$description);
                    
                    $data['user_type']      = 'Vendor';
                    $data['role']           = encrypt($invoice->role_id);
                    $data['branch_name']    = $invoice->branch->name;
                    $data['user_name']      = $invoice->user->name;
                    $data['payment_type']   = 'Pay Invoice';
                    $data['description']    = $description;
                    $data['section']        = 'Pay Invoice';


                    $data['amount']         = $invoice->amount - $invoice->received_amount;

                    
                }
            }
            elseif($type === $generic_index["Vendor Payment"])
            {
                $vendor_payment = new VendorPayment;

                $vendor_payment = $vendor_payment->getVendorPaymentById($generic_id);

                if(isset($vendor_payment->id))
                {
                    $data['branch_name']    = $vendor_payment->vendor->branch->name;
                    $data['user_type']      = NULL;
                    $data['user_name']      = NULL;
                    $data['booking_name']   = NULL;
                    $data['payment_type']   = 'Vendor Payment';
                    $data['description']    = $vendor_payment->description;
                    $data['invoice']        = $vendor_payment->invoice_no;


                    $data['amount']         = $vendor_payment->amount - $vendor_payment->received_amount;

                    $data['date']           = EF::dateHtml($vendor_payment->created_at);

                    // $data['start_limit']    = $commission->booking->approve_date;

                }
            }  
            elseif($type === $generic_index["Inventory Payable"])
            {
                $payable         = new Payable;

                $payable = $payable->getPayableById($generic_id);
                $role_name =$payable->purchaseOrder->user->userRoles->pluck('name')->toArray();
                
                $role = new Role;

                $role = $role->findByName($role_name[0]);
                
                if (isset($role->id)) {
                    $data['user_type']      = $role->name;
                    $data['role']           = encrypt($role->id);
                }
 
                $data['branch_name']    = $payable->purchaseOrder->boq->branch->name;
            
                
                if(isset($payable->id))
                {
                    $data['branch_name']    = $payable->purchaseOrder->boq->branch->name;
                    $data['user_name']      = $payable->purchaseOrder->user->name;
                    $data['booking_name']   = NULL;
                    $data['payment_type']   = "Inventory Payable";
                    $data['description']    = 'Inventory Payable against '.$payable->grn->grn_number;
                    $data['amount']         = $payable->total_amount - $payable->received_amount;
                    $data['section']        = 'Inventory Payable';

                    $data['invoice']        = $payable->grn->grn_number;

                }

            }
            

            return view('payments.modals.add_payment',$data);



        }
        catch (DecryptException $e)
        {

        }
    }

    public function showUpdatePayPaymentModel($payment_id)
    {
        try
        {
            $generic_index = EF::getGenericTableIndex();

            $data = [

                'booking_name'     => '',
                'payment'          => $payment_id, //ENCRYPTED
                'section'          => '',
                'curr_payment'     => '',
            ];

            $payment_id = decrypt($payment_id);

            $payment = new Payment;

            $payment = $payment->getPaymentById($payment_id);

            if(isset($payment->id) && $payment->status == "Unapprove")
            {
                $data['curr_payment'] = $payment;
                // INSTALLMENT
                if($payment->generic_type_id == $generic_index['Installment'])
                {
                    $data['booking_name']   = EF::showPlotFormat($payment->installment->booking->plot);

                    $data['section'] = 'Booking Information';

                }// COMMISSION
                elseif($payment->generic_type_id == $generic_index['Commission'])
                {
                    $data['booking_name']   = EF::showPlotFormat($payment->commission->booking->plot);

                    $data['section'] = 'Booking Information';

                }
                elseif($payment->generic_type_id == $generic_index['Vendor Payment'])
                {
                    $vendor_payment = new VendorPayment;

                    $vendor_payment = $vendor_payment->getVendorPaymentById($payment->generic_id);

                    if(isset($vendor_payment->id))
                    {
                        $data['invoice']        = $vendor_payment->invoice_no;
                        $data['vendor_payment'] = $vendor_payment;
                    }



                    $data['start_limit']    = $vendor_payment->created_at;

                    
                }
                 // INVENTORY PAYABLE
                 elseif($payment->generic_type_id == $generic_index['Inventory Payable'])
                 {
                     $payable = new Payable;

                     $payable = $payable->getPayableById($payment->generic_id);

                     $data['booking_name']   = NULL;
 
                     $data['section'] = 'Inventory Information';

                     $data['invoice']        = $payable->grn->grn_number;
 
                 }


                return view('payments.modals.update_payment',$data);

            }





        }
        catch (DecryptException $e)
        {

        }
    }


    public function getGenericPaymentList(Request $request)
    {
        if($request->ajax())
        {

            try
            {
                $data = ['view' => '', 'show_section'];

                $data['view'] = '<option selected value="'.Crypt::encrypt(0).'">Select Payment List</option>';

                $payment_list = [];

                $args   = decrypt($request->args);

                $generic_id = decrypt($request->generic_type);

                $generic_type = new GenericType;

                $generic_type = $generic_type->getGenericTypeById($generic_id);

                if(isset($generic_type->id))
                {
                    if($generic_type->id === $this->generic_index['Installment'])
                    {
                        $data['show_section'] = "Booking"; // DISPLAY THE BOOKING DROPDOWN

                        $payment = new Payment;

                        $payment_list = $payment->getInstallmentPaymentList($args,$generic_type->id,['Unapprove']);
                    }
                    else if($generic_type->id === $this->generic_index['Commission'])
                    {
                        $payment = new Payment;

                        $data['show_section'] = "Booking";


                        $payment_list = $payment->getCommissionPaymentList($args,$generic_type->id,['Unapprove']);
                    }
                    else if($generic_type->id === $this->generic_index['Booking'])
                    {
                         $data['show_section'] = "Booking";

                        $payment = new Payment;

                        $payment_list = $payment->getPaymentByGenericIdWithType($args,$generic_type->id,['Unapprove']);
                    }
                    else if($generic_type->id === $this->generic_index['Inventory Payable'])
                    {

                        $payment = new Payment;

                        $payment_list = $payment->getOtherPaymentList($generic_type->id,['Unapprove']);
                    }
                    else
                    {
                        $payment = new Payment;

                        $payment_list = $payment->getOtherPaymentList($generic_type->id,['Unapprove']);
                    }

                    if($generic_type->id === $this->generic_index['Inventory Payable'])
                    {
                        foreach ($payment_list as $rows)
                        {
                            
                            $data['view'].= '<option value="'.Crypt::encrypt($rows->id).'">'.$rows->inventoryPayable->grn->grn_number.' -'.$rows->amount.'</option>';
                        }
                    }
                    else{
                        foreach ($payment_list as $rows)
                        {
                            $data['view'].= '<option value="'.Crypt::encrypt($rows->id).'">'.$rows->description.'</option>';
                        }
                    }




                }

                return $data;

            }
            catch (DecryptException $e)
            {

            }
        }

        return 'No Record Found';
    }


    public function showPaymentVoucher($payment_id,$type)
    {
        try
        {
            $generic_index = EF::getGenericTableIndex();

            $generic_type = new GenericType;

            $head = new Head;

            $account = new Account;


            $data = [

                'approve_transaction'       => false,
                'payment'                   => false,
                'booking'                   => false,
                'generic_type'              => false,
                'unique_id'                 => uniqid(),
                'head_list'                 => $head->getAllHeads(),
                'filter_subhead_list'       => $account->getAllSubheadByType('BRV'),
                'subhead_list'              => $account->getAllSubhead(),
                'voucher_type'              => 'BRV',
                'mode'                      => '',
                'instrument'                => '',
                'instrument_date'           => '',
                'drawn_on'                  => '',




            ];

            $payment_id = decrypt($payment_id);

            $payment = new Payment;

            $payment = $payment->getPaymentById($payment_id);

            if(isset($payment->id))
            {

                $data['payment'] = $payment;

                if (isset($payment->role->id)) {
                    $data['role'] = $payment->role->id;
                }
                $data['generic_type'] = $generic_type->getGenericTypeById($payment->generic_type_id);

                // INSTALLMENT
                if($payment->generic_type_id == $generic_index['Installment'])
                {
                    $data['booking']   = $payment->installment->booking;

                }// COMMISSION
                elseif($payment->generic_type_id == $generic_index['Commission'])
                {
                    $data['booking']   = $payment->commission->booking;
                }


                $data['mode']               =  $payment->mode;
                $data['instrument']         =  $payment->instrument;
                $data['instrument_date']    =  $payment->instrument_date;
                $data['drawn_on']           =  $payment->drawn_on;

                // $account_info = $this->getAccountsByPaymentMode($payment);

                // $data['filter_subhead_list'] = $account_info['debit_account_list'];
                // $data['subhead_list']        = $account_info['credit_account_list'];
                // $data['approve_transaction'] = $account_info['approve_transaction'];


              $data['voucher_type'] = NULL;

              if(in_array($payment->payment_type,['Installment','Baloon Charges','Document Charges']) && $data['mode'] == "Cash" )
              {
                $data['voucher_type'] = 'CRV';
            
                $data['filter_subhead_list']       = $account->getAllSubheadByType($data['voucher_type']);
                $data['subhead_list']              = $account->getAllSubhead();

              }

              else if(in_array($payment->payment_type,['Installment','Baloon Charges','Document Charges']) && $data['mode'] != "Cash" )
              {
              $data['voucher_type'] = 'BRV';
             

               $data['filter_subhead_list']       = $account->getAllSubheadByType($data['voucher_type']);
                $data['subhead_list']              = $account->getAllSubhead();

              }

              else if(!in_array($payment->payment_type,['Installment','Baloon Charges','Document Charges']) && $data['mode'] == "Cash" )
              {
                $data['voucher_type'] = 'CPV';
                  $data['subhead_list']          = $account->getAllSubhead();
                $data['filter_subhead_list'] =  $account->getAllSubheadByType($data['voucher_type']);
              }


              else if(!in_array($payment->payment_type,['Installment','Baloon Charges','Document Charges']) && $data['mode'] != "Cash")
              {
              $data['voucher_type'] = 'BPV';
              
              $data['subhead_list']          = $account->getAllSubhead();
                $data['filter_subhead_list'] =  $account->getAllSubheadByType($data['voucher_type']);

              }



                


                return view('voucher.modals.payment_voucher',$data);

            }
        }
        catch (DecryptException $e)
        {

        }
    }

    public function getAccountsByPaymentMode($payment)
    {
        $account = new Account;

        $account_info = EF::getAccountInfo();

        $data = ['debit_account_list' => [], 'credit_account_list' => [], 'approve_transaction' => false];

        if($payment->generic_type_id == $this->generic_index['Invoice'])
        {
            if($payment->mode == "Cash")
            {
                $data['credit_account_list']  = $account->getAllSubheadByType('CPV');

                $data['debit_account_list'] = $account->getArrayAccountById($account_info['control account']);
            }
            else
            {
                $data['credit_account_list'] = $account->getAllSubheadByType('BPV');

                $data['debit_account_list'] = $account->getArrayAccountById($account_info['control account']);


            }

            $data['approve_transaction'] = true;

        }
        else
        {
            $data['debit_account_list']  = $account->getAllSubheadByType('BRV');
            $data['credit_account_list'] = $account->getAllSubhead();



        }

        return $data;
    }


}

