<?php

namespace App\Http\Controllers\Finance;

use App\Http\Controllers\Controller;
use App\Http\Controllers\RandomNumbersController;
use App\Models\AccAgentIncentive;
use App\Models\BillMasterAgentIncentive;
use App\Models\Requisition;
use App\Models\SubAgent;
use App\Models\TblMotorDebit;
use Illuminate\Http\Request;

class AgentIncentivesController extends Controller
{
    public function index(){
        $lists =  AccAgentIncentive::orderBy('month', 'desc')->orderBy('year', 'desc')->get();

        return view('finance.agents.manage-agent-incentives', compact('lists'));
    }

    /**Search for Agent Incentives Listing**/
    public function getAgentIncentivesList($month, $year, $option, $minimum, $agentRate, $subAgentRate)
    {
        $totalAmount = 0;

        /**Get the St and Ed for the Production Period**/
        $period = $this->getStartAndEndDate($month,$year);
        $st = $period['st'];
        $ed = $period['ed'];

        /**Start your Table now**/
        $table ='<script>
                    $(document).ready(function(){
                       $("#agent-incentives-table").dataTable({
                       dom: "lBfrtip",
                       buttons: [
                          { extend: "excel", className: "download-buttons" },
                          { extend: "pdf", className: "download-buttons" },
                        ]
                       });
                    });
                    var c = document.getElementsByClassName("cr");
                    for (var i = 0; i < c.length; i++) {
                        c[i].innerHTML = (i+1)+".";
                    }
                </script>

                <style>
                    #agent-incentives-table th, td {
                        text-align: left;
                        padding: 5px;
                    }
                    #agent-incentives-table tr:hover {background-color: #a3aef6;}
                </style>';
        $table .= '<div class="policy-notes">';
        $table .='<table id="agent-incentives-table" style="border-collapse: collapse; width: 100%; font-size: 10px" >';
        $table .=' <thead>
                        <tr style="background-color: #a1b5d3">
                            <th>No</th>
                            <th>Agent Code</th>
                            <th>Agent Name</th>
                            <th>Group Leader</th>
                            <th>Company</th>
                            <th>Phone Number</th>
                            <th>Period</th>
                            <th>Total Debited Premium</th>
                            <th>Total Receipted Premium</th>
                            <th>Incentive Rate</th>
                            <th>Incentive Amount</th>
                            <th>View Detailed Report</th>
                        </tr>
                        </thead>';
        $table .='<tbody>';
        /**We now Loop through the Incentives Report**/

        if($option == 'pay-only-agents'){
            /**We just only work on Paying all Agents**/
            $allAgents = SubAgent::where('type', 'agent')->orderBy('contact_person', 'asc')->get();
        }else{
            /**We just only work on Paying all Agents and SubAgents**/
            $allAgents = SubAgent::orderBy('contact_person', 'asc')->get();
        }
        /**Loop through the List**/
        foreach ($allAgents as $agent){
            if($agent->type == 'agent'){
                $production = TblMotorDebit::where('leader_id', $agent->stamp)->where('cert_issued', 1)->whereBetween('st', [$st." 00:00:00", $ed." 23:59:59"])->get();
            }else{
                /**Here We are Dealing with a Sub-Agent**/
                $production = TblMotorDebit::where('agent_one_id', $agent->stamp)->where('cert_issued', 1)->whereBetween('st', [$st." 00:00:00", $ed." 23:59:59"])->get();
            }
            /**If a Minimum Limit has been Stated, then Consider it**/
            if($production->sum('alloc_amount') >= $minimum && $production->sum('alloc_amount') != 0){
                $table .='<tr>';
                $table .='<td class="cr"></td>';
                $table .='<td style="border-bottom: 2px solid black">'.$agent->agent_code.'</td>';
                $table .='<td style="border-bottom: 2px solid black"> '.$agent->contact_person.'</td>';
                if($agent->type !=  'agent'){
                    if($agent->teamLeader != null){
                        $table .='<td style="border-bottom: 2px solid black"><b class="error">'.$agent->teamLeader->contact_person.'</b></td>';
                    }else{
                        $table .='<td style="border-bottom: 2px solid black">-</td>';
                    }
                }else{
                    $table .='<td style="border-bottom: 2px solid black">-</td>';
                }
                $table .='<td style="border-bottom: 2px solid black">'.$agent->company.'</td>';
                $table .='<td style="border-bottom: 2px solid black"><b class="error">'.$agent->phone.'</b></td>';
                $table .='<td style="border-bottom: 2px solid black">'.$month.'/'.$year.'</td>';
                $table .='<td style="border-bottom: 2px solid black">'.number_format($production->sum('amount'),2).'</td>';
                $table .='<td style="border-bottom: 2px solid black">'.number_format($production->sum('alloc_amount'),2).'</td>';
                if($agent->type !=  'agent'){
                    $agentIncentive = $subAgentRate/100*$production->sum('alloc_amount');
                    $table .='<td style="border-bottom: 2px solid black"><b>'.number_format($subAgentRate,2).'%</b></td>';
                    $table .='<td style="border-bottom: 2px solid black">'.number_format(round($agentIncentive)).'</td>';
                }else{
                    $agentIncentive = $agentRate/100*$production->sum('alloc_amount');
                    $table .='<td style="border-bottom: 2px solid black"><b>'.number_format($agentRate,2).'%</b></td>';
                    $table .='<td style="border-bottom: 2px solid black">'.number_format(round($agentIncentive)).'</td>';
                }
                $table .='<td style="border-bottom: 2px solid black"><i class="fa fa-eye error" style="font-size: 16px;cursor: pointer"></i></td>';
                $table .='</tr>';

                $totalAmount += $agentIncentive;
            }
        }
        $table .=' </tbody>';
        $table .='</table>';
        $table .= '</div>';
        $data = [
            'table' => $table,
            'totalAmount' => round($totalAmount),
        ];

        return response()->json($data);
    }

    /**Get Dates given Month and Year**/
    public function getStartAndEndDate($month, $year)
    {
        $st = $ed = $monthNumber = null;
        if ($month == 'jan' || $month == 1){
            $st = $year.'-01-01';
            $ed = $year.'-01-31';
            $monthNumber = 1;
        }elseif ($month == 'feb' || $month == 2){
            $st = $year.'-02-01';
            $ed = $year.'-02-28';
            if($year % 4 == 0){
                $ed = $year.'-02-29';
            }
            $monthNumber = 2;
        }elseif ($month == 'mar' || $month == 3){
            $st = $year.'-03-01';
            $ed = $year.'-03-31';
            $monthNumber = 3;
        }elseif ($month == 'apr' || $month == 4){
            $st = $year.'-04-01';
            $ed = $year.'-04-30';
            $monthNumber = 4;
        }elseif ($month == 'may' || $month == 5){
            $st = $year.'-05-01';
            $ed = $year.'-05-31';
            $monthNumber = 5;
        }elseif ($month == 'jun' || $month == 6){
            $st = $year.'-06-01';
            $ed = $year.'-06-30';
            $monthNumber = 6;
        }elseif ($month == 'jul' || $month == 7){
            $st = $year.'-07-01';
            $ed = $year.'-07-31';
            $monthNumber = 7;
        }elseif ($month == 'aug' || $month == 8){
            $st = $year.'-08-01';
            $ed = $year.'-08-31';
            $monthNumber = 8;
        }elseif ($month == 'sep' || $month == 9){
            $st = $year.'-09-01';
            $ed = $year.'-09-30';
            $monthNumber = 9;
        }elseif ($month == 'oct' || $month == 10){
            $st = $year.'-10-01';
            $ed = $year.'-10-31';
            $monthNumber = 10;
        }elseif ($month == 'nov' || $month == 11){
            $st = $year.'-11-01';
            $ed = $year.'-11-30';
            $monthNumber = 11;
        }elseif ($month == 'dec' || $month == 12){
            $st = $year.'-12-01';
            $ed = $year.'-12-31';
            $monthNumber = 12;
        }

        return [
            'st' => $st,
            'ed' => $ed,
            'month' => $monthNumber
        ];
    }

    /**Display Pop Up window to store a New Incentive Period**/
    public function showNewIncentivePeriod(){
        return view('finance.agents.add-new-incentive-period');
    }

    /**A Function to Store a Bill**/
    public function storeNewIncentivePeriod(Request $request){
        $branch = $request['branch'];
        $ledger = $request['ledger'];
        $month = $request['period'];
        $year = $request['search-year'];
        $minLimit = $request['minimum-limit'];
        $option = $request['incentive-option'];
        $amount = $request['incentive-gross-amount'];
        $agentRate = $request['agent-percentage'];
        $subAgentRate = $request['sub-percentage'] ?? 0;
        $ref = $request['ref'];
        $date = $request['incentive-date'];
        $due_date = $request['incentive-due-date'];
        $narration = $request['narration'];

        /**Get the St and Ed for the Production Period**/
        $period = $this->getStartAndEndDate($month,$year);
        $st = $period['st'];
        $ed = $period['ed'];
        $monthNumber = $period['month'];

        $res = 'empty fields';
        if(!empty($ledger) && !empty($amount) && !empty($ref) && !empty($due_date) && !empty($narration)){
            $res = 'zero amount';
            if($amount > 0){
                /**Check if the Incentive already Exists**/
                $incentiveExists = AccAgentIncentive::where('month', $monthNumber)->where('year', $year)->first();
                $res = 'incentive period exists';
                if(!$incentiveExists){
                    /**At this stage, prepare to Store the Bill**/
                    $stamp = (new RandomNumbersController)->getRandomMix(10);
                    $res = 'stamp exist';
                    if(!AccAgentIncentive::where('stamp', $stamp)->first()){
                        $createBill = AccAgentIncentive::create(
                            [
                                'branch' => $branch,
                                'month' => $monthNumber,
                                'year' => $year,
                                'ledger_id' => $ledger,
                                'amount' => $amount,
                                'min_amount' => $minLimit,
                                'incentive_option' => $option,
                                'agent_rate' => $agentRate,
                                'sub_agent_rate' => $subAgentRate,
                                'ref' => $ref,
                                'narration' => $narration,
                                'stamp' => $stamp,
                                'date' =>  $date ?? date('Y-m-d'),
                                'due_date' =>  $due_date,
                                'created_by' => auth()->user()->id,
                            ]
                        );

                        $res = 'error';
                        if($createBill){
                            $createdId = $createBill->id;
                            /**Since an Incentive Plan has Successfully been Created, Add the Entry in Bill Master for Agent Incentive:- This will assist to compile Agent's Incentives Statements**/
                            /**We now Loop through the Incentives Report**/
                            if($option == 'pay-only-agents'){
                                /**We just only work on Paying all Agents**/
                                $allAgents = SubAgent::where('type', 'agent')->orderBy('contact_person', 'asc')->get();
                            }else{
                                /**We just only work on Paying all Agents and SubAgents**/
                                $allAgents = SubAgent::orderBy('contact_person', 'asc')->get();
                            }

                            /**Loop through the Agents and Store the Records**/
                            $postBill = [];
                            foreach ($allAgents as $agent){
                                if($agent->type == 'agent'){
                                    $production = TblMotorDebit::where('leader_id', $agent->stamp)->where('cert_issued', 1)->whereBetween('st', [$st." 00:00:00", $ed." 23:59:59"])->get();
                                    $agentIncentive = $agentRate/100*$production->sum('alloc_amount');
                                }else{
                                    /**Here We are Dealing with a Sub-Agent**/
                                    $production = TblMotorDebit::where('agent_one_id', $agent->stamp)->where('cert_issued', 1)->whereBetween('st', [$st." 00:00:00", $ed." 23:59:59"])->get();
                                    $agentIncentive = $subAgentRate/100*$production->sum('alloc_amount');
                                }
                                /**If a Minimum Limit has been Stated, then Consider it**/
                                if($production->sum('alloc_amount') >= $minLimit && $production->sum('alloc_amount') != 0){

                                    /**Prepare to Store the Records in the Bill Master Incentives Table**/
                                    $createBill = BillMasterAgentIncentive::create(
                                        [
                                            'incentive_id' =>  $createdId,
                                            'agent_id' =>  $agent->stamp,
                                            'type' =>  'credit',
                                            'ref' =>  $ref,
                                            'date' =>  $date ?? date('Y-m-d'),
                                            'due_date' =>  $due_date,
                                            'trans_type' =>  'INCENTIVE',
                                            'details' =>  $narration,
                                            'amount' =>  round($agentIncentive),
                                        ]
                                    );
                                    if($createBill){
                                        $postBill[] = 'success';
                                    }else{
                                        $postBill[] = 'error';
                                    }
                                }
                            }
                            if(!in_array('error', $postBill)){
                                $res = 'success';
                            }
                        }
                    }
                }
            }
        }
        return $res;
    }

    /**An Agent Incentive Period has a certain Amount of Money paid to It**/
    public function incentivesPaidAmount($id){
        /**Above Id is the agent Bill Master Id**/
        $paidAmount = 0;
        $bill = BillMasterAgentIncentive::find($id);
        if($bill){
            $paidAmount = BillMasterAgentIncentive::where('incentive_id',$bill->incentive_id)->where('agent_id', $bill->agent_id)->where('trans_type', 'PAYMENT')->sum('amount');
        }
        return $paidAmount;
    }

    /**Create a Function to get an Incentive Period Current Balance**/
    public function incentivesBalance($id){
        /**The above $id is the id of the Bill Master Table**/
        $incentiveBalance = 0;
        $bill = BillMasterAgentIncentive::find($id);
        if($bill){
            $incentiveBalance = BillMasterAgentIncentive::where('incentive_id',$bill->incentive_id)->where('agent_id', $bill->agent_id)->sum('amount');
        }
        return $incentiveBalance;
    }

    /**Create a Function to Display Agent Incentive Information**/
    public function showAgentIncentive($id){
        $incentive = AccAgentIncentive::where('stamp', $id)->first();
        $incentives = AccAgentIncentive::orderBy('month', 'asc')->orderBy('year', 'asc')->get();
        /**The above Incentive has Bill records that end up having requistions on them**/
        $pendingRequisitions = [];
        if($incentive->billMasterAgentIncentive){
            foreach ($incentive->billMasterAgentIncentive as $row){
                $list = Requisition::where('batch',$row->id)->where('req_type', 'agent-incentives')->where('second_approved', 0)->first();
                if($list){
                    $pendingRequisitions[] = $list;
                }
            }
        }

        if($incentive){
            $recentTransactions = BillMasterAgentIncentive::where('incentive_id', $incentive->id)->where('trans_type','INCENTIVE')->orderBy('created_at', 'desc')->get();
            return view('finance.agents.agent-incentive', compact('incentive', 'incentives', 'recentTransactions', 'pendingRequisitions'));
        }
        return view('errors.404');
    }

    /**Display Payments Made to a specific Bill**/
    public function showAgentIncentivePaymentDetails($id){
        /**The above Id is the Id of the Bill Master**/
        $billMaster = BillMasterAgentIncentive::find($id);
        $bill = AccAgentIncentive::find($billMaster->incentive_id);
        /**Get all Paid Requisitions to this Bill**/
        $paidReqs = Requisition::where('req_type', 'agent-incentives')->where('batch', $id)->where('req_status', 'paid')->get();

        return view('finance.agents.view-agent-incentive-payment-details', compact('bill','billMaster','paidReqs'));
    }

    /**Create a Function that will be used to Display the Production Report for a Particular Agent on the Bill Master Table**/
    public function showAgentIncentiveProductionReport($id){
        /**The above Id is the Id of the Bill Master**/
        $billMaster = BillMasterAgentIncentive::find($id);
        $bill = AccAgentIncentive::find($billMaster->incentive_id);

        /**The above Incentive Period will give us the Production Period**/
        /**Get the St and Ed for the Production Period**/
        $period = $this->getStartAndEndDate($bill->month,$bill->year);
        $st = $period['st'];
        $ed = $period['ed'];
        /**Using the above periods we are able to find Production report for the said agent**/
        $agent = $billMaster->agentDetails;
        $production = [];
        if($agent){
            /**If the Agent is an Agent, we will search data for Leader_id**/
            if($agent->type == 'agent'){
                /**This is an Agent and has many Sub-agent affiliated on Him**/
                $production = TblMotorDebit::where('leader_id', $agent->stamp)->where('cert_issued', 1)->whereBetween('st', [$st." 00:00:00", $ed." 23:59:59"])->get();
            }else{
                /**This is a Sub-Agent**/
                $production = TblMotorDebit::where('agent_one_id', $agent->stamp)->where('cert_issued', 1)->whereBetween('st', [$st." 00:00:00", $ed." 23:59:59"])->get();
            }
        }

        return view('finance.agents.view-agent-incentive-production-report', compact('bill','billMaster','production'));
    }
}
