<?php

namespace App\Http\Controllers\Finance;

use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\JournalVourcher;
use App\Models\Policy;
use App\Models\TblMotorDebit;
use Illuminate\Http\Request;

class JvsController extends Controller
{
   /**View a List of All Jvs**/
    public function viewJvs(Request $request){
        /**Our List will have JVs Done in a particular Day**/
        $list = JournalVourcher::whereBetween('created_at', [date('Y-m-d'.' 00:00:00'), date('Y-m-d H:i:s')])->get();
        if($request->has('search')){
            $list = JournalVourcher::where('status', 1)->where([
                [function($query) use ($request) {
                    /**CHECK FOR JV RECEIPT TYPE**/
                    if($type = $request['jv-type']){
                        if($request['jv-type'] != 'all'){
                            $query = $query->where('jv_type', $type);
                        }
                    }
                    /**CHECK FOR SELECTED JV STATUS**/
                    if($status = $request['jv-status']){
                        if($request['jv-status'] != 'all'){
                            $query = $query->where('jv_status', $status);
                        }
                    }
                    /**CHeck if Date Period is specified **/
                    if($request['from'] != null && $request['to'] != null){
                        $query = $query->whereBetween('created_at', [$request['from'].' 00:00:00', $request['to'].' 23:59:59']);
                    }
                }]
            ])->orderBy('jv_date', 'desc')->get();
        }
        return view('finance.jvs.journal-vouchers', compact('list'));
    }

    /**Creat a Function to View Journal Voucher Item and its Details**/
    public function viewJv($id){
        $jv = JournalVourcher::findOrFail($id);
        $acc_dr = $acc_cr = '';
        $acc_dr_link = $acc_cr_link = '#';
        $acc_dr_bal = $acc_cr_bal = '0';
        $debits = [];
        if($jv->jv_type == 'client-client'){
            $acc_dr = 'DN'.$jv->acc_dr;
            $acc_cr = 'DN'.$jv->acc_cr;
            $acc_dr_link = 'policy/'.$jv->acc_dr;
            $acc_cr_link = 'policy/'.$jv->acc_cr;

            $plcy_cr = Policy::where('pl_cd', $jv->acc_cr)->first();
            $plcy_dr = Policy::where('pl_cd', $jv->acc_dr)->first();
            /**Check if the above policies Exists, get their Balances**/
            if($plcy_cr){
                $acc_cr_bal = $plcy_cr->policyBalance($jv->acc_cr);
            }
            if($plcy_dr){
                $acc_dr_bal = $plcy_dr->policyBalance($jv->acc_dr);
            }

            /**Sometimes, the above Credit Jvs are related to a Motor Insurance Policy that requires one to activate Motor Debit to be issued a Certificate with**/
            if($plcy_cr->prod_id == 42){
                /**Find a Motor Debit related to this Policy that doesn't have a certificate issued to it: This means, premiums have not been fully paid**/
                $debits = TblMotorDebit::where('pl_cd', $jv->acc_cr)->where('amount_cleared', 0)->where('cert_issued', 0)->get();
            }
        }

        return view('finance.jvs.journal-voucher', compact('jv', 'debits','acc_cr', 'acc_dr', 'acc_cr_link', 'acc_dr_link', 'acc_cr_bal', 'acc_dr_bal'));
    }
    /**Approve a Jv**/
    public function jvFirstApproval($id){
        $jv = JournalVourcher::findOrFail($id);

        $res = 'error';
        if($jv){
            $update = $jv->update(['first_approved'=>1, 'first_approved_by'=>auth()->user()->id, 'first_approved_at'=>date('Y-m-d'), 'jv_status' => 'pending second approval']);
            if($update){
                $res = 'success';
            }
        }
        return $res;
    }

    public function jvSecondApproval($id){
        $jv = JournalVourcher::findOrFail($id);
        $res = 'error';
        if($jv){
            $update = $jv->update(['jv_status'=>'paid', 'second_approved'=>1, 'second_approved_by'=>auth()->user()->id, 'second_approved_at' =>date('Y-m-d')]);
            if($update){
                $res = 'success';
            }
        }
        return $res;
    }

    /**Create a Function to allocate specific JV amount to a Motor Debit**/
    public function showAllocateJvToMotorDebit($id){
        $jv = JournalVourcher::findOrFail($id);
        $debits = TblMotorDebit::where('pl_cd', $jv->acc_cr)->where('amount_cleared', 0)->where('cert_issued', 0)->get();

        return view('finance.jvs.allocate-jv-to-motor-debit', compact('jv','debits'));
    }

    /**Create a Function to Update the Allocated JV Amount to a Motor Debit**/
    public function storeAllocateJvToMotorDebit($id, Request $request){
        $jv = JournalVourcher::findOrFail($id);
        //$jvBalance = $jv->amount;
        $res = 'error';
        foreach ($request['debit-id'] as $key => $value){
            /**We get the Debit ID and amount to be allocated**/
            $debitId = $request['debit-id'][$key];
            $amount = $request['amount'][$key];

            $debit = TblMotorDebit::find($debitId);
            if($debit){
                $debitedAmount = $debit->amount;
                $paidAmount =  $debit->alloc_amount;
                $debitBalance = $debitedAmount - $paidAmount;

                if($amount >= $debitBalance && $amount <= $jv->amount){
                    /**Update the Debit now**/
                    $updateDebit = $debit->update(['alloc_amount'=>$paidAmount+$amount, 'amount_cleared'=>1, 'issued_on_credit'=>1, 'credit_reason'=>'JV', 'credit_issued_by'=>auth()->user()->id]);
                    if($updateDebit){
                        $res = 'success';
                    }
                }
            }
        }

        return $res;
    }




    /**Show Client to Client Jvs **/
    public function showClientToClientJv(){
        //$clients = Client::where('status', 1)->orderBy('nms', 'asc')->get();
        return view('finance.jvs.client-client-jv');
    }

    /**Store a Client to Client JV**/
    public function storeClientToClientJv(Request $request){
        /**At this Stage, we are able to get two account, One to be Debited, and the Other to be credited**/
        $cr_id = $request['credited-item']; //This one should be having a Positive Balance for us to do a Credit on it
        $dr_id = $request['debited-item']; //This one should be having a Negative Balance for use to do a Debit on it
        $jvAmount = preg_replace(['/,/', '/%/',], ["",""], abs($request['jv-amount']) ?? 0);
        $jvDate = $request['jv-date'];
        $narration = $request['narration'] ?? 'Client to Client Journal Entry';

        $res = 'empty cr';
        if(!empty($cr_id)){
            $res = 'empty dr';
            if(!empty($dr_id)){
                $res = 'empty amount';
                if(!empty($jvAmount)){
                    $res = 'empty date';
                    if(!empty($jvDate)){
                        /**Get Policy Balances for the Given Risk Notes**/
                        $cr_id_bal = 0;
                        $dr_id_bal = 0;
                        $plcy_cr = Policy::where('pl_cd', $cr_id)->first();
                        $plcy_dr = Policy::where('pl_cd', $dr_id)->first();
                        /**Check if the above policies Exists, get their Balances**/
                        if($plcy_cr){
                            $cr_id_bal = $plcy_cr->policyBalance($cr_id);
                        }
                        if($plcy_dr){
                            $dr_id_bal = $plcy_dr->policyBalance($dr_id);
                        }

                        /**Policy to be Debited should be having a Negative balance**/
                        $res = 'dr greater than zero';
                        if($dr_id_bal < 0){
                            /**Policy to be credited should be having a positive balance**/
                            $res = 'cr less than zero';
                            if($cr_id_bal > 0){
                                /**JV amount should be less than or equal to the absolute value of the $dr_id_bal**/
                                $res = 'more amount';
                                if($jvAmount <= abs(round($dr_id_bal))){
                                    /**At this Point, we are sure Everything is okay and we should Post the JV Now**/
                                    $createJv = JournalVourcher::create(
                                        [
                                            'jv_type' => 'client-client',
                                            'jv_date' => $jvDate,
                                            'acc_dr' => $dr_id,
                                            'acc_cr' => $cr_id,
                                            'amount' => $jvAmount,
                                            'nar' => $narration,
                                            'jv_status' => 'pending first approval',
                                            'created_by' => auth()->user()->id
                                        ]
                                    );
                                    $res = 'error';
                                    if($createJv){
                                        $res = $createJv->id;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return $res;
    }

    /**Create a Function to be used to get Debit Amount on a JV as a Sum**/
    public function policyDebitJvAmount($pl_cd){
        $amount = 0;
        if(JournalVourcher::where('jv_type', 'client-client')->where('acc_dr', $pl_cd)->where('jv_status', 'paid')->sum('amount') > 0){
            $amount = JournalVourcher::where('jv_type', 'client-client')->where('acc_dr', $pl_cd)->where('jv_status', 'paid')->sum('amount');
        }
        return $amount;
    }

    /**Create a Function to be used to get Credit Amount on a JV as a Sum**/
    public function policyCreditJvAmount($pl_cd){
        $amount = 0;
        if(JournalVourcher::where('jv_type', 'client-client')->where('acc_cr', $pl_cd)->where('jv_status', 'paid')->sum('amount') > 0){
            $amount = JournalVourcher::where('jv_type', 'client-client')->where('acc_cr', $pl_cd)->where('jv_status', 'paid')->sum('amount');
        }
        return $amount;
    }

    /**Create a Function that will fetch all JVs on a particular Policy**/
    public function policyJvs($id)
    {
        /**The above id is the pl_cd**/
        $jvs = JournalVourcher::where('jv_type', 'client-client')->where('acc_cr', $id)->where('jv_status', 'paid')
            ->orWhere('jv_type', 'client-client')->where('acc_dr', $id)->where('jv_status', 'paid')->get();

        return view('finance.jvs.policy-jv-utilization', compact('id','jvs'));
    }
}
