<?php
/**
 * Created by PhpStorm.
 * User: sunilkhorwal
 * Date: 2020-10-26
 * Time: 15:40
 */
namespace App\Http\Controllers\Admin;

use App\ApplicationEMICalculation;
use App\ConsumerApplication;
use App\EmiPayment;
use App\Exports\Exporter;
use App\ExposureCalculation;
use App\FLDGCategory;
use App\FLDGCategoryLogs;
use App\Http\Controllers\Controller;
use App\LiabilityLog;
use App\Merchant;
use App\MerchantFLDGAutoApproveLogs;
use App\MultiStageDisbursement;
use App\PaymentEmi;
use App\ProFormaInvoice;
use App\Slack;
use App\StatusLogs;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Maatwebsite\Excel\Facades\Excel;
use MathPHP\Finance;

class FLDGController extends Controller {

    private $request;
    private $internal = false;
    private $is_only_principal_outstanding = false;

    public function __construct(Request $request){
        $this->request = $request;
    }

    public function index($merchant_id){
        $merchant = Merchant::find($merchant_id);

        if (!$merchant->is_fldg_active) {
            \Session::flash('error', 'FLDG not activated');
            return redirect()->back();
        }

        $FLDGCategory = FLDGCategory::where('merchant_id', $merchant_id)->get();
        $categories = [];
        foreach ($FLDGCategory as $item){
            $categories[] = $item->id;
        }
        $ProFormaInvoice = ProFormaInvoice::/*where('fldg_applied', 1)->*/whereIn('fldg_applied_category', $categories)->get(['application_id']);
        $applications = [];
        foreach ($ProFormaInvoice as $item){
            $applications[] = $item->application_id;
        }

        $exposureCalculation = ExposureCalculation::with('category')->whereIn('category_id', $categories)->where('merchant_id', $merchant_id)->get();
        $risk_exposureDeposit = ExposureCalculation::where('merchant_id', $merchant_id)->whereIn('category_id', $categories)->where('type_of_transaction', 1)->sum('risk_exposure');
        $risk_exposure = ExposureCalculation::where('merchant_id', $merchant_id)->whereIn('category_id', $categories)->where('type_of_transaction', 2)->sum('risk_exposure');
        $risk_exposure = $risk_exposureDeposit - $risk_exposure;
        $data = $this->getWithPrincipalOutstanding($applications);

        $availableExposure = $risk_exposure - $data['exposureUtilised'];

        if($merchant->available_exposure != $availableExposure) {
            Merchant::where('id', $merchant_id)->update(['available_exposure' => round($availableExposure, 2)]);
        }

        $response = ['merchant' =>  $merchant, 'categories' => $FLDGCategory, 'applications' => $data['applications'], 'exposureCalculation' => $exposureCalculation, 'risk_exposure' => $risk_exposure, 'exposureUtilised' => $data['exposureUtilised'], 'responseExposureUtilised' => $data['response']];

        if ($this->internal)
            return $response;

        $response['FLDGSummary'] = $this->getFLDGSummary($merchant_id);
        $response['categoriesLogs'] = FLDGCategoryLogs::where('merchant_id', $merchant_id)->get();


        foreach($FLDGCategory as $category){
            $_risk_exposure = $response['FLDGSummary'][$category->id]['risk_exposure'] ?? 0;
            $_responseExposureUtilised = $response['responseExposureUtilised'][$category->id]['exposureUtilised'] ?? 0;
            $availableExposureCateWise = $_risk_exposure - $_responseExposureUtilised;

            if ($category->available_exposure != $availableExposureCateWise) {
                FLDGCategory::where('id', $category->id)->update(['available_exposure' => $availableExposureCateWise]);
            }
        }


        return view('admin.fldg.index', $response);
    }

    public function getFLDGSummary($merchant_id){
        $risk_exposureDeposit = ExposureCalculation::where('merchant_id', $merchant_id)->get(['category_id','risk_exposure','type_of_transaction']);

        $response = [];
        foreach($risk_exposureDeposit as $item){

            if (!isset($response[$item->category_id]['risk_exposure'])){
                $response[$item->category_id]['risk_exposure'] = 0;
            }

            if($item->type_of_transaction == 1){
                $response[$item->category_id]['risk_exposure'] += $item->risk_exposure;
            }else{
                $response[$item->category_id]['risk_exposure'] -= $item->risk_exposure;
            }
        }

        return $response;
    }

    public function viewCategories($merchant_id){
        $merchant = Merchant::find($merchant_id);

        if (!$merchant->is_fldg_active) {
            \Session::flash('error', 'FLDG not activated');
            return redirect()->back();
        }

        $FLDGCategory = FLDGCategory::with('user')->where('merchant_id', $merchant_id)->get();
        return view('admin.fldg.view_categories', ['merchant' =>  $merchant, 'categories' => $FLDGCategory]);
    }

    public function createCategory(){
        if ($this->request->get('id')){
            $FLDGCategory = FLDGCategory::find($this->request->get('id'));
            $FLDGCategoryLogs = new FLDGCategoryLogs();
            $FLDGCategoryLogs->fill($FLDGCategory->toArray());
            $FLDGCategoryLogs->created_at = Carbon::now()->toDateTimeString();
            $FLDGCategoryLogs->category_id = $this->request->get('id');
            $FLDGCategoryLogs->user_id = $this->request->get('user_id');
            $FLDGCategoryLogs->action = 'Category Updated';
            $FLDGCategoryLogs->save();


            $exposure = ExposureCalculation::where('merchant_id', $this->request->get('merchant_id'))->where('category_id', $this->request->get('id'))->get();

            if($exposure) {
                foreach ($exposure as $item) {
                    $risk_exposure = ($item->amount * 100) / $this->request->get('fldg');
                    ExposureCalculation::where('id', $item->id)->update(['risk_exposure' => round($risk_exposure, 2), 'fldg' => $this->request->get('fldg')]);
                }
            }

        }else{
            $FLDGCategory = new FLDGCategory();
        }

        $FLDGCategory->user_id = Auth::user()->id;
        $FLDGCategory->fill($this->request->all());
        $FLDGCategory->save();

        if (isset($FLDGCategory->id)){
            return response(['status' => 'OK', 'data' => $FLDGCategory]);
        }else{
            return response(['status' => 'FAIL', 'message' => 'Failed to create category']);
        }
    }

    public function deleteCategory(){
        $FLDGCategory = FLDGCategory::find($this->request->get('id'))->all();
        if (FLDGCategory::find($this->request->get('id'))->delete()){

            $FLDGCategoryLogs = new FLDGCategoryLogs();
            $FLDGCategoryLogs->fill($FLDGCategory);
            $FLDGCategoryLogs->created_at = Carbon::now()->toDateTimeString();
            $FLDGCategoryLogs->category_id = $this->request->get('id');
            $FLDGCategoryLogs->user_id = $this->request->get('user_id');
            $FLDGCategoryLogs->action = 'Category Deleted';
            $FLDGCategoryLogs->save();

            return response(['status' => 'OK']);
        }

        return response(['status' => 'FAIL', 'message' => 'Failed to delete the category']);
    }

    public function exposureCalculation(){

        $exposureCalculation = new ExposureCalculation();
        $exposureCalculation->fill($this->request->all());
        $exposureCalculation->save();

        if (isset($exposureCalculation->id)){
            $merchant = Merchant::find($this->request->get('merchant_id'));

            $availableExposure = $this->getAvailableExposure($this->request->get('merchant_id'));

            $type = $this->request->get('type_of_transaction') == 1 ? 'Deposit' : 'Withdrawal';

            $exposureAvailable = $availableExposure[$this->request->get('category_id')] ?? ($availableExposure ?? 0);

            (new Slack(new Request(['title' => $type.' Entry made by '.$this->request->get('name').' for '.$merchant->merchant_name.' of Rs.'.$this->request->get('amount').'. Available exposure is Rs. '.$exposureAvailable, 'fields' => ['Merchant' => $merchant->merchant_name, 'By' => $this->request->get('name')], 'group' => 'businessdevelopment'])))->send();

            return response(['status' => 'OK']);
        }

        return response(['status' => 'FAIL', 'message' => 'Failed to delete the category']);
    }

    public function getAvailableExposure($merchant_id, $application_id = null, $notification = false){

        $FLDGCategory = FLDGCategory::where('merchant_id', $merchant_id)->get();
        $merchant = Merchant::where('id', $merchant_id)->first(['id','merchant_name','available_exposure']);
        $categories = [];
        foreach ($FLDGCategory as $item){
            $categories[] = $item->id;
        }

        $risk_exposureDeposit = ExposureCalculation::where('merchant_id', $merchant_id)->whereIn('category_id', $categories)->where('type_of_transaction', 1)->get(['category_id','risk_exposure']);
        $risk_exposure = ExposureCalculation::where('merchant_id', $merchant_id)->whereIn('category_id', $categories)->where('type_of_transaction', 2)->get(['category_id','risk_exposure']);

        $deposit = [];
        $risk_exposureDepositAmt = 0;
        foreach ($risk_exposureDeposit as $item){
            if (isset($deposit[$item->category_id])) {
                $deposit[$item->category_id] += $item->risk_exposure;
            } else {
                $deposit[$item->category_id] = $item->risk_exposure;
            }

            $risk_exposureDepositAmt += $item->risk_exposure;
        }

        $withdrawal = [];
        $risk_exposureAmt = 0;
        foreach ($risk_exposure as $item){
            if (isset($withdrawal[$item->category_id])){
                $withdrawal[$item->category_id] += $item->risk_exposure;
            }else{
                $withdrawal[$item->category_id] = $item->risk_exposure;
            }

            $risk_exposureAmt += $item->risk_exposure;
        }

        $risk_exposure = $risk_exposureDepositAmt - $risk_exposureAmt;


        $risk_exposureCategories = [];
        foreach ($deposit as $category_id => $_risk_exposure){
            if (isset($withdrawal[$category_id])){
                if (isset($risk_exposureCategories[$category_id])){
                    $risk_exposureCategories[$category_id] -= $withdrawal[$category_id];
                }else{
                    $risk_exposureCategories[$category_id] = $_risk_exposure - $withdrawal[$category_id];
                }
            }else{
                $risk_exposureCategories[$category_id] = round($_risk_exposure,2);
            }
        }

        $ProFormaInvoice = ProFormaInvoice::where('fldg_applied', 1)->whereIn('fldg_applied_category', $categories)->get(['application_id','fldg_applied_category']);
        $applications = [];
        $fldg_applied_category = null;
        foreach ($ProFormaInvoice as $item){
            $applications[] = $item->application_id;
            if($application_id && $application_id == $item->application_id && isset($risk_exposureCategories[$item->fldg_applied_category])){
                $risk_exposure = $risk_exposureCategories[$item->fldg_applied_category];
                $fldg_applied_category = $item->fldg_applied_category;
            }
        }

        $data = $this->getWithPrincipalOutstanding($applications);

        $exposureUtilised = $data['exposureUtilised'];

        if($data['response'] && $fldg_applied_category){
            $exposureUtilised = isset($data['response'][$fldg_applied_category]) ? $data['response'][$fldg_applied_category]['exposureUtilised'] : 0;
        }

        $availableExposureCondition = $availableExposure = round($risk_exposure - $exposureUtilised, 2);

        if($application_id){
            $appData = ConsumerApplication::where('id', $application_id)->first(['approved_amount']);
            $statusLogs = StatusLogs::where('application_id', $application_id)->where('status', 'approved')->first(['id']);
            if (isset($appData->approved_amount) && $appData->approved_amount && !isset($statusLogs->id)) {
                $availableExposureCondition -= $appData->approved_amount;
            }
        }

        if($availableExposureCondition <= 0 && $notification){
            (new Slack(new Request(['title' => 'FLDG exposure is over for '.$merchant->merchant_name.'. Please stops the disbursement and ask merchant to give additional deposit', 'fields' => ['Merchant' => $merchant->merchant_name, 'Available Exposure' => $availableExposure == 0 ? 'Zero' : $availableExposure], 'group' => 'businessdevelopment'])))->send();
        }
        if($merchant->available_exposure != $availableExposure) {
            Merchant::where('id', $merchant_id)->update(['available_exposure' => round($availableExposure, 2)]);
        }

        $response = ['merchant' =>  $merchant, 'exposureUtilised' => $data['exposureUtilised'], 'responseExposureUtilised' => $data['response']];

        $response['FLDGSummary'] = $this->getFLDGSummary($merchant_id);
        $response['categoriesLogs'] = FLDGCategoryLogs::where('merchant_id', $merchant_id)->get();


        foreach($FLDGCategory as $category){
            $_risk_exposure = $response['FLDGSummary'][$category->id]['risk_exposure'] ?? 0;
            $_responseExposureUtilised = $response['responseExposureUtilised'][$category->id]['exposureUtilised'] ?? 0;
            $availableExposureCateWise = $_risk_exposure - $_responseExposureUtilised;

            if ($category->available_exposure != $availableExposureCateWise) {
                FLDGCategory::where('id', $category->id)->update(['available_exposure' => $availableExposureCateWise]);
            }
        }

        return $availableExposure;
    }

    public function getWithPrincipalOutstanding($applications)
    {

        $response = [];
        $applications = ConsumerApplication::with('proFormaInvoice.fldg_category','disbursed')->whereIn('id', $applications)->whereIn('state', ['disbursed','nach registered', 'closed'])->get(['id', 'state', 'name','loan_amount','approved_amount']);
        $exposureUtilised = 0;

        foreach ($applications as $key => $application) {
            $payment = new PaymentEmi();
            $emi_dues = $payment->generateDues($application->id, 1);

            $emi = ApplicationEMICalculation::where('application_id', $application->id)->first(['upfront_from_customer']);
            $upfront_from_customer = isset($emi->upfront_from_customer) ? $emi->upfront_from_customer : 0;

            $loanamount = ((isset($application->approved_amount) && $application->approved_amount != 0) ? $application->approved_amount : $application->loan_amount) - $upfront_from_customer;


            $emis_array = array();
            array_push($emis_array, -$loanamount);

            if (isset($emi_dues['payload'])) {
                foreach ($emi_dues['payload'] as $emis) {
                    array_push($emis_array, $emis['amount'] - $emis['moratorium_amount']);

                }
            }
            $rate = (Finance::irr($emis_array)) * 100;
            if ($rate < 0) {
                $rate = 0;
            }


            $emiPayment = EmiPayment::where('application_id', $application->id)->get(['emi_date','payment_status','amount_due','bounce_charges','delay_penalty','charges_waived']);

            $emiPaymentData = [];
            $emiPaymentAmountPending = [];

            if($emiPayment) {
                foreach ($emiPayment as $itemEMI) {
                    $emiPaymentData[$itemEMI->emi_date] = $itemEMI->payment_status;
                    if($itemEMI->payment_status == 'partial') {
                        $emiPaymentAmountPending[$itemEMI->emi_date] = ($itemEMI->amount_due - ($itemEMI->bounce_charges + $itemEMI->delay_penalty));
                    }
                }
            }

            $i = 0;
            if(isset($emi_dues['payload'])){
                $principal_oustanding = $loanamount;
                foreach ($emi_dues['payload'] as $emis){

                    if ($application->state == 'closed'){
                        $applications[$key]->principal_outstanding = 0;
                        break;
                    }

                    if(strtotime($emis['emi_date']) <= Carbon::now()->endOfDay()->timestamp && isset($emiPaymentData) && $emiPaymentData && isset($emiPaymentData[$emi_dues['payload'][$i]['emi_date']]) && in_array($emiPaymentData[$emi_dues['payload'][$i]['emi_date']], ['success','partial'])) {
                        $emi_dues['payload'][$i]['interest'] = $principal_oustanding * ($rate / 100);
                        $emi_dues['payload'][$i]['principal'] = $emis['amount'] - $emi_dues['payload'][$i]['interest'];
                        $principal_oustanding = $principal_oustanding - $emi_dues['payload'][$i]['principal'];

                        if(isset($emiPaymentAmountPending) && isset($emiPaymentAmountPending[$emi_dues['payload'][$i]['emi_date']]) && $emiPaymentAmountPending[$emi_dues['payload'][$i]['emi_date']] && in_array($emiPaymentData[$emi_dues['payload'][$i]['emi_date']], ['success','partial'])){
                            $principal_oustanding += $emiPaymentAmountPending[$emi_dues['payload'][$i]['emi_date']];
                        }

                        $emi_dues['payload'][$i]['principal_outstanding'] = $principal_oustanding;
                        if (round($principal_oustanding, 2)) {
                            $applications[$key]->principal_outstanding = round(($principal_oustanding + $emi_dues['payload'][$i]['amount']), 2);
                        }else if ($emiStatus = array_unique(array_values($emiPaymentData))){
                            if (count($emiStatus) == 1 && isset($emiStatus[0]) && $emiStatus[0] == 'success') {
                                $applications[$key]->principal_outstanding = 0;
                            }
                        }
                    }else if (isset($emiPaymentData) && $emiPaymentData && isset($emiPaymentData[$emi_dues['payload'][$i]['emi_date']]) && !in_array($emiPaymentData[$emi_dues['payload'][$i]['emi_date']], ['success','partial'])){
                        $emi_dues['payload'][$i]['interest'] = $principal_oustanding * ($rate / 100);
                        $emi_dues['payload'][$i]['principal'] = $emis['amount'] - $emi_dues['payload'][$i]['interest'];
                        $principal_oustanding = $principal_oustanding - $emi_dues['payload'][$i]['principal'];
                        $emi_dues['payload'][$i]['principal_outstanding'] = $principal_oustanding;
                        /*if (round($principal_oustanding, 2)) {
                            $applications[$key]->principal_outstanding = round(($principal_oustanding + $emi_dues['payload'][$i]['amount']), 2);
                        }*/
                        $applications[$key]->principal_outstanding = round(($principal_oustanding + $emi_dues['payload'][$i]['amount']), 2);
                        break;
                    }else if ($emiPaymentData && count(array_unique(array_values($emiPaymentData))) == 1 && isset(array_unique(array_values($emiPaymentData))[0]) && array_unique(array_values($emiPaymentData))[0] == 'success'){
                        $applications[$key]->principal_outstanding = 0;
                    }

                    $i++;
                }
            }

            if ($this->is_only_principal_outstanding){
                return $applications[$key]->principal_outstanding;
            }

            $emiStatus = array_unique(array_values($emiPaymentData));
            $exposureUtilisedEMILevel = !is_object($applications[$key]->principal_outstanding) ? ($emiPaymentData && count($emiStatus) == 1 && isset($emiStatus[0]) && $emiStatus[0] == 'success' ? 0 : $applications[$key]->principal_outstanding) : 0;
            $exposureUtilised += $exposureUtilisedEMILevel;

            if (!isset($response[$application->proFormaInvoice->fldg_category->id])){
                $response[$application->proFormaInvoice->fldg_category->id]['exposureUtilised'] = $exposureUtilisedEMILevel;
            }else {
                $response[$application->proFormaInvoice->fldg_category->id]['exposureUtilised'] += $exposureUtilisedEMILevel;
            }
        }

        return ['applications' => $applications, 'exposureUtilised' => $exposureUtilised, 'response' => $response];
    }

    public function exportData($merchant_id){

        $this->internal = true;
        $response = $this->index($merchant_id);

        $data = [
            ['FLDG'],
            ['Total Exposure Allowed', $response['risk_exposure']],
            ['Exposure Utilised', $response['exposureUtilised']],
            ['Pending Exposure', ($response['risk_exposure'] - $response['exposureUtilised'])],
            ['',''],
            ['',''],
            ['',''],
            ['Exposure Calculation', '', ''],
            ['Date of FLDG transaction', 'Category of FLDG', 'Amount Deposited / Withdrawn (to be entered by Arpita Mam)', '% of FLDG (Agreed by BD team and Merchant) (To be entered by BD team)', 'Exposure Allowed'],
        ];


        foreach($response['exposureCalculation'] as $exposureCalculationItem) {

            $data[] = [
                'date' => $exposureCalculationItem->date_of_transaction,
                'category' => $exposureCalculationItem->category->name,
                'amount' => $exposureCalculationItem->amount,
                'fldg' => $exposureCalculationItem->category->fldg,
                'exposure_allowed' => $exposureCalculationItem->risk_exposure,
                'type_of_fldg' => $exposureCalculationItem->type_of_fldg,
                'narration' => $exposureCalculationItem->narration

            ];
        }

        $data[] = ['',''];
        $data[] = ['',''];
        $data[] = ['',''];

        $data[] = ['Principal outstanding tracking'];
        $data[] = ['Application ID','Name of Customer', 'Disbursement Date', 'FLDG Category','Principal outstanding', 'Type of Case'];

        foreach($response['applications'] as $application) {

            $liabilityLog = LiabilityLog::where('application_id', $application->id)->first(['id', 'liability_percent']);

            $data[] = [
                'id' => $application->id,
                'name' => ucwords($application->name),
                'date' => $application->disbursed->created_at,
//                'liability_hold_amount' => $liabilityLog->liability_percent ?? ($application->proFormaInvoice->fldg_category->fldg ?? ''),
                'category' => $application->proFormaInvoice->fldg_category->name,
                'principal_outstanding' => $application->principal_outstanding,
                'type' => (isset($liabilityLog->id)) || (isset($application->proFormaInvoice->liability_hold) && $application->proFormaInvoice->liability_hold == 1) ? 'Liability Hold' : 'FLDG'
            ];
        }

        $request = new Request(['data' => $data, 'sheet' => 'Sheet1']);
        return Excel::download((new Exporter($request)), $response['merchant']->merchant_name.'_FLDG_Report_'.Carbon::now()->toDateTimeString().'.xls');
    }

    public function exportLiabilityCases($merchant_id){

        $this->internal = true;
        $merchant = Merchant::where('id', $merchant_id)->first(['merchant_name']);
        $month = Carbon::now()->startOfMonth()->toDateTimeString();

        $data[] = ['Loan Application ID', 'Name of Customer', 'Date of Disbursement', 'Liability Hold Percent', 'Liability Hold Amount', 'FLDG Category'];

        $applications = ConsumerApplication::with('proFormaInvoice', 'proFormaInvoice.fldg_category', 'disbursed', 'emi')->whereIn('state', ['disbursed', 'nach registered'])
            ->whereHas('disbursed', function ($query) use ($month) {
                $query->where('created_at', '>', date('Y-m-d', strtotime($month)));
            })
            ->get();

        foreach($applications as $application) {

            if($application->proFormaInvoice->liability_hold == 1){

                $disbursement_amount = (new DisbursementController(new Request()))->getDisbursementAmount($application);

                $data[] = [
                    'id' => $application->proFormaInvoice->loan_application_no,
                    'name' => $application->name,
                    'date' => Carbon::parse($application->disbursed->created_at)->format('d/m/Y'),
                    'percent' => $application->proFormaInvoice->fldg_category->fldg,
                    'amount' => $disbursement_amount['net_disbursement'] * $application->proFormaInvoice->fldg_category->fldg / 100,
                    'category' => $application->proFormaInvoice->fldg_category->name,
                ];
            }
        }

        $request = new Request(['data' => $data, 'sheet' => 'Sheet1']);
        return Excel::download((new Exporter($request)), $merchant->merchant_name.'_Liability_Hold_Report_'.Carbon::now()->toDateTimeString().'.xls');
    }

    public function checkExistCategories(){
        $count = FLDGCategory::where('merchant_id', $this->request->get('merchant_id'))->whereNull('deleted_at')->count();
        return response(['status' => 'OK', 'message' => 'Success', 'data' => ['count' => $count]]);
    }

    public function exportDataAllData($merchant_id){
        $this->internal = true;
        $response = $this->index($merchant_id);
        $ids = [];
        if(!$response instanceof RedirectResponse) {

            $data = [
                ['FLDG'],
                ['Total Exposure Allowed', $response['risk_exposure']],
                ['Exposure Utilised', $response['exposureUtilised']],
                ['Pending Exposure', ($response['risk_exposure'] - $response['exposureUtilised'])],
                ['', ''],
                ['', ''],
                ['', ''],
                ['Exposure Calculation', '', ''],
                ['Date of FLDG transaction', 'Category of FLDG', 'Amount Deposited / Withdrawn (to be entered by Arpita Mam)', '% of FLDG (Agreed by BD team and Merchant) (To be entered by BD team)', 'Exposure Allowed'],
            ];


            foreach ($response['exposureCalculation'] as $exposureCalculationItem) {

                $data[] = [
                    'date' => $exposureCalculationItem->date_of_transaction,
                    'category' => $exposureCalculationItem->category->name,
                    'amount' => $exposureCalculationItem->amount,
                    'fldg' => $exposureCalculationItem->category->fldg,
                    'exposure_allowed' => $exposureCalculationItem->risk_exposure
                ];
            }

            $data[] = ['', ''];
            $data[] = ['', ''];
            $data[] = ['', ''];

            $data[] = ['Principal outstanding tracking'];
            $data[] = ['Application ID', 'Name of Customer', 'Disbursement Date', 'FLDG Category', 'Principal outstanding', 'Type of Case'];

            foreach ($response['applications'] as $application) {

                $liabilityLog = LiabilityLog::where('application_id', $application->id)->first(['id']);

                $data[] = [
                    'id' => $application->id,
                    'name' => ucwords($application->name),
                    'date' => $application->disbursed->created_at,
                    'category' => $application->proFormaInvoice->fldg_category->name,
                    'principal_outstanding' => $application->principal_outstanding,
                    'type' => isset($liabilityLog->id) || (isset($liabilityLog) && $liabilityLog->liability_hold == 1) ? 'Liability Hold' : 'FLDG'
                ];

                $ids[] = $application->id;
            }
        }else{
            $data[] = ['Application ID', 'Name of Customer', 'Disbursement Date', 'FLDG Category', 'Principal outstanding', 'Type of Case'];
        }

        $applicationsData = ConsumerApplication::with('proFormaInvoice', 'liability_log', 'disbursed')->where('merchant_id', $merchant_id)->whereNotIn('id', $ids)->where('state', ['disbursed', 'nach registered'])->get(['id', 'name']);
        if ($applicationsData){
            $this->is_only_principal_outstanding = true;
            foreach($applicationsData as $applicationsDatum){
                $principal_outstanding = $this->getWithPrincipalOutstanding([$applicationsDatum->id]);
                if (isset($applicationsDatum->disbursed)) {
                    $data[] = [
                        'id' => $applicationsDatum->id,
                        'name' => ucwords($applicationsDatum->name),
                        'date' => $applicationsDatum->disbursed->created_at,
                        'category' => '',
                        'principal_outstanding' => $principal_outstanding,
                        'type' => (isset($applicationsDatum->liability_log) && $applicationsDatum->liability_log) || (isset($applicationsDatum->proFormaInvoice->liability_hold) && $applicationsDatum->proFormaInvoice->liability_hold == 1) ? 'Liability Hold' : 'Regular case'
                    ];
                }
            }
        }

        $request = new Request(['data' => $data, 'sheet' => 'Sheet1']);
        return Excel::download((new Exporter($request)), 'FLDG_Report_'.Carbon::now()->toDateTimeString().'.xls');
    }

    public function saveAutoApproveCategory(){
        $merchant = Merchant::find($this->request->get('merchant_id'));
        $merchant->auto_approve_category = $this->request->has('auto_approve_category') ? $this->request->get('auto_approve_category') : 0;
        $merchant->save();

        $merchantFLDGAutoApproveLogs = MerchantFLDGAutoApproveLogs::insertGetId([
            'merchant_id' => $this->request->get('merchant_id'),
            'auto_approve_category_id' => $this->request->has('auto_approve_category') ? $this->request->get('auto_approve_category') : 0,
            'created_by' => $this->request->get('user_id'),
            'created_at' => Carbon::now()->toDateTimeString(),
        ]);

        if (!isset($merchantFLDGAutoApproveLogs->id)){
            if(Auth::check()){
                $user = ucwords(Auth::user()->name);
            }else{
                $user = User::where('id', $this->request->get('user_id'))->first(['name']);
                $user = ucwords($user->name);
            }

            $type = $this->request->has('auto_approve_category') ? 'on' : 'off';
            $message = $this->request->has('auto_approve_category') ? 'FLDG category added successfully for auto approved cases' : 'FLDG category disabled successfully for auto approved cases';

            (new Slack(new Request(['title' => 'Permission to add auto approved cases for '.$merchant->merchant_name.' is turned '.$type.' by '.$user, 'fields' => ['Name' => $merchant->merchant_name, 'ID' => $merchant->id], 'group' => 'businessdevelopment'])))->send();

            return response()->json(['status' => 'OK', 'message' => $message]);
        }else{
            return response()->json(['status' => 'FAIL', 'message' => 'Something went wrong. Please try again later']);
        }
    }

    public function fetchLiabilityHoldCases(){
        $statusLogs = StatusLogs::where('status', 'disbursed')
            ->where('created_at', '>=', Carbon::now()->startOfDay()->toDateTimeString())
            ->where('created_at', '<=', Carbon::now()->endOfDay()->toDateTimeString())
            ->where('is_reversed',0)->get(['application_id']);

//        $statusLogs = StatusLogs::with('application', 'applcation.merchant', 'application.proFormaInvoice', 'application_element', 'application.offer', 'application.emi', 'application.lender')
//            ->where('status', 'disbursed')
//            ->where('created_at', '>=', Carbon::now()->startOfDay()->toDateTimeString())
//            ->where('created_at', '<=', Carbon::now()->endOfDay()->toDateTimeString())
//            ->groupBy('application_id')
//            ->get(['application_id']);

        $applications=[];
        foreach($statusLogs as $log){
            if(!in_array($log->application_id, $applications))
                $applications[] = $log->application_id;
//            else
//                $common_apps[] = $log->application_id;
        }

        $data = ConsumerApplication::with('proFormaInvoice', 'proFormaInvoice.fldg_category', 'lender','merchant', 'emi', 'offer', 'application_element', 'merchant.fldg_categories')
            ->whereIn('id', $applications)->whereIn('state', ['disbursed', 'nach registered', 'closed'])
            ->whereNull('is_deleted')->get()->groupBy(['merchant.id', 'proFormaInvoice.fldg_category.id']);

        $fldg=0;
        $amount = 0;
        $risk_exposure = 0;
        foreach ($data as $merchant => $applications){
            foreach($applications as $fldg => $application_list){
                $fldg_percent=0;
                $fldg_category_id=0;
                $total_amount = 0;
                $total_exposure = 0;
                foreach($application_list as $application) {
                    if ($application->proFormaInvoice && $application->proFormaInvoice->liability_hold) {

                        $net_disbursement_amount = (new DisbursementController(new Request()))->getDisbursementAmount($application);

                        $fldg_percent = $application->proFormaInvoice->fldg_category->fldg;
                        $fldg_category_id = $application->proFormaInvoice->fldg_category->id;
                        $amount = $net_disbursement_amount['net_disbursement'] * $fldg_percent / 100;
                        $risk_exposure = $amount * 100 / $fldg_percent;
                        /*
                         * 'amount' => $application->application_element->hold_amount,
                         * 'risk_exposure' => round((($application->application_element->hold_amount * 100) / $FLDGCategory->fldg), 2)
                         */

                        $total_amount += $amount;
                        $total_exposure += $risk_exposure;
                    }
                }

                if($total_amount > 0 && $total_exposure > 0) {
                    $data = [
                        'merchant_id' => $merchant,
                        'date_of_transaction' => Carbon::now()->format('d/m/Y'),
                        'type_of_transaction' => 1,
                        'type_of_fldg' => 2,
                        'narration' => 'Liability hold entry made by the system.',
                        'category_id' => $fldg_category_id,
                        'amount' => round($total_amount, 2),
                        'fldg' => $fldg_percent,
                        'user_id' => 107,
                        'name' => 'Credit Fair',
                        'risk_exposure' => round($total_exposure, 2)
                    ];
                    $this->request->merge($data);
                    $this->exposureCalculation();
                }
            }
        }
        return true;
    }

    public function getNetDisbursedAmount($app){
        // Logic is the same as the one on the DA
        $multiStageDisbursement = new MultiStageDisbursement();
        $disbursementController = new DisbursementController(new Request());
        $application = new ConsumerApplicationController();

        if ($cf_advance_amount = $disbursementController->isCFCollectingAdvance($app)) {
            $advance_amount_link = $application->sendAdvanceAmountLink($cf_advance_amount, $app);
        }

        $withheld_percent = 0;
        $insurance_premium_amount = isset($app->proFormaInvoice->insurance_premium_amount) && isset($app->proFormaInvoice->insurance_premium_applicable) && $app->proFormaInvoice->insurance_premium_applicable == 1 && $app->proFormaInvoice->insurance_premium_by_merchant == 1 ? $app->proFormaInvoice->insurance_premium_amount : 0;
        if ($multiStageDisbursement->canPartialDisbursement($app->offer->id, $app)) {
            $insurance_premium_amount = 0;
        }
        $merchant_processing_collected = isset($app->merchant->is_collected) && $app->merchant->is_collected == 1 ? $app->merchant->is_collected : (isset($app->proFormaInvoice) && $app->proFormaInvoice->processing_fee_by_merchant == 1 ? $app->proFormaInvoice->processing_fee_by_merchant : 0);

        $withheld_amount = 0;
        if(isset($advance_amount_link)){
            $cf_advance_amount = 1;
        }

//        if($merchant_processing_collected == 1){
        $net_disbursement = $app->approved_amount;

        if(!$cf_advance_amount){
            $net_disbursement -= $app->emi->upfront_from_customer;
        }
        $subvention_amount = $net_disbursement * $app->emi->subvention / 100;
        $net_disbursement = $net_disbursement - ($app->emi->processing_fee + $insurance_premium_amount +
                $subvention_amount + $app->emi->subvention_igst + $app->emi->subvention_cgst + $app->emi->subvention_sgst);

        if((isset($app->offer->processing_fee_first_emi) && $app->offer->processing_fee_first_emi) || $merchant_processing_collected == 0){
            $net_disbursement = $net_disbursement + $app->emi->processing_fee;
        }

//        }else{
//            $net_disbursement = $app->approved_amount - ($insurance_premium_amount);
//            if(!$cf_advance_amount){
//                $net_disbursement += $app->emi->upfront_from_customer;
//            }
//            $withheld_amount = ($withheld_percent * $net_disbursement)/100;
//        }


        return $net_disbursement - $withheld_amount;
    }
}

