<?php

namespace App\Http\Controllers\Admin;

use App\ApplicationEMICalculation;
use App\ApplicationEMICalculationLock;
use App\AvanseCreateFinance;
use App\ConsumerApplication;
use App\ConsumerApplicationElement;
use App\ConsumerApplicationFiles;
use App\CreditReport;
use App\EmiPayment;
use App\ForeclosureBreakup;
use App\Http\Controllers\Controller;
use App\Http\Controllers\FrontController;
use App\LoanManagement;
use App\Logging\CloudWatchLoggerFactory;
use App\MultiStageDisbursement;
use App\Moratorium;
use App\PaymentLogs;
use App\PaymentTransaction;
use App\Reconciliation_Logs;
use App\RiskBasedConfiguration;
use App\RiskBasedConfigurationLogs;
use App\RPS_Logs;
use App\Slack;
use App\StatusLogs;
use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Google\Service\DataprocMetastore\Consumer;
use Hashids\Hashids;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class RepaymentController extends Controller{

    /**
     * @var string
     */
    private $endPointRPS;
    private $endPointRPSSubvention;
    private $endPointReconciliation;
    private $endPointSettlementReconciliation;
    private $endPointOverdueUpdate;
    private $endPointBouncePenalUpdate;
    /**
     * @var array|Request
     */
    private $payload;
    private $application_id;
    private $payment_details;
    private $reconciliation_id;
    private $is_pre_part_payment = false;
    /**
     * @var bool
     */
    //ToDo:: handle for old cases, for cases less than CF_RPS_START_DATE
    private $is_bpi_applicable = true;

    public function __construct(){
        $this->endPointRPS = _env('CF_RPS_ENDPOINT', 'http://65.1.61.53:8000/api/5th_emi_date');
        $this->endPointRPSSubvention = _env('CF_RPS_SUBVENTION_ENDPOINT', 'http://65.1.61.53:8000/api/subvention_rps');
        $this->endPointReconciliation = _env('CF_PAYMENT_RECON', 'http://65.1.61.53:8000/api/payment_allocation_st');
        $this->endPointSettlementReconciliation = _env('CF_PAYMENT_SETTLE_RECON', 'http://65.1.61.53:8000/api/settlement_reconcile');
        $this->endPointOverdueUpdate = _env('CF_OVERDUE_UPDATE', 'http://65.1.61.53:8000/api/update_loan_data');
        $this->endPointBouncePenalUpdate = _env('CF_BOUNCE_PENAL_UPDATE', 'http://65.1.61.53:8000/api/bounce_penal_update');
    }

    // Public function to gether RPS details
    public function getRPSDetails($app_id, $returnJson = false, $docType = '', $is_payment = false, $isHybrid = true){
        try {
            $exceptionList = [262979,262999,263304,258629,253121,258629,270925];
            $application = ConsumerApplication::with('emi', 'emi.offer')->where('id', $app_id)->whereNotIn('id', $exceptionList)->first(['id','state']);
            $multiStageDisbursement = new MultiStageDisbursement();
            $activatedForAll = true;
            $isMultiTranche = false;//$multiStageDisbursement->canPartialDisbursement($application->emi->offer->id, $application);
            if ($activatedForAll) { //Activated for all the cases, earlier multi tranche was not considered
                if (strtotime(Carbon::now()->format('d-m-Y')) >= strtotime(_env('CF_RPS_START_DATE')) && isset($application->state)) {
                    if ((in_array($application->state, ['nach registered', 'closed', 'cancelled']) ||
                        ($application->state == 'disbursed' && $docType != 'Welcome Letter') ||
                        ($application->state == 'disbursed' && $is_payment)) && !$this->is_pre_part_payment
                    ) {
                        (new Slack(new Request(['title' => 'Reco Logs getRPSDetails out', 'fields' => ['id' => $app_id,'type' => $docType], 'group' => Slack::$STAGE_TESTING])))->send();
                        $is_exist = RPS_Logs::where('application_id', $app_id)->exists();
                        if ($is_exist) {
                            return RPS_Logs::where('application_id', $app_id)->get()->toArray();
                        }
                        return false;
                    }

                    $this->application_id = $app_id;
                    $this->setRPSPayload();
                    $response = $this->apiCall($isHybrid ? 'rps' : 'rps_subvention');

                    (new Slack(new Request(['title' => 'Reco Logs apiCall', 'fields' => ['response' => json_encode($response), 'payload' => $this->payload], 'group' => Slack::$STAGE_TESTING])))->send();

                    $isIn = true;
                    if (isset($response['rps_json'])) {
                        $rps_summary = $response;
                        $rps_json = $response['rps_json'];
                        unset($rps_summary['rps_json']);

                        foreach ($rps_json as $index => $resp) {
                            if((($this->isBPIApplicable($app_id, $isMultiTranche) || (!$this->is_bpi_applicable)) && isset($resp['bpi_interest']) && $resp['bpi_interest'] != 0) && $isIn){
                                $isIn = false;
                                $isMultiTranche = false;

                                if ($resp['bpi_interest'] > 0 && $resp['emi_amount'] > 0){
                                    $rps_json[$index]['total_payable'] = $rps_json[$index]['total_payable'] - $rps_json[$index]['bpi_interest'];
                                    $rps_json[$index]['bpi_interest'] = 0;
                                }else {
                                    unset($rps_json[$index]);
                                    continue;
                                }
                            }
                            $rps_json[$index]['application_id'] = (int)$this->application_id ?? $app_id ?? 0;
                            $rps_json[$index]['created_at'] = Carbon::now()->toDateTimeString();
                            if($index == 0){
                                $rps_json[$index]['loan_summary'] = json_encode($rps_summary);
                            }else{
                                if ($index == 1 && !isset($rps_json[0])){
                                    $rps_json[$index]['loan_summary'] = json_encode($rps_summary);
                                }else {
                                    $rps_json[$index]['loan_summary'] = null;
                                }
                            }
                        }

                        $rps_json = array_values($rps_json);
                        $is_update = RPS_Logs::where('application_id', $this->application_id)->exists();

                        if ($is_update) {
                            (new Slack(new Request(['title' => 'RPS Delete 1', 'fields' => ['application_id' => $this->application_id], 'group' => Slack::$STAGE_TESTING])))->send();
                            RPS_Logs::where('application_id', $this->application_id)->delete();
                        }

                        RPS_Logs::insert($rps_json);

//                    if($docType == 'Welcome Letter'){
                        if(!$this->is_pre_part_payment) {
                            $this->setEMIdetails($app_id, $rps_json);
                        }
//                    }

                        if ($returnJson) {
                            return $rps_json;
                        }
                        return true;
                    }
                    return false;
                }
            }
            return false;
        } catch (\Exception $e) {
            $cwFactory = new CloudWatchLoggerFactory();
            $_data = array(
                'exception' => 'Error while calling RPS API',
                'message' => $e->getMessage(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString()
            );
            $cwFactory->logger(json_encode($_data));
        }
    }

    private function isBPIApplicable($id, $isMultiTranche = false){
        $exceptionApplicationIds = explode(',', _env('AATTA_CHAKKI_EXCEPTION', ''));
        if (in_array($id, $exceptionApplicationIds)) {
            return false;
        }

        if($isMultiTranche){
            return true;
        }

        $application = ConsumerApplicationElement::where('application_id', $id)->where('type_of_customer_sub_category', 'Aatta Chakki')->first(['id']);
        return isset($application->id);
    }

    // Public function to check if present
    public function checkRPSExists($app_id){
        return RPS_Logs::where('application_id', $app_id)->whereNull('deleted_at')->exists();
    }
    // Public function to reset entry
    public function deleteRPSRecord($app_id){
        (new Slack(new Request(['title' => 'RPS Delete', 'fields' => ['app_id' => $app_id], 'group' => Slack::$STAGE_TESTING])))->send();
        RPS_Logs::where('application_id', $app_id)->whereNull('deleted_at')->delete();
        return true;
    }

    private function setRPSPayload(){

        $application_details =  ConsumerApplication::with(['offer' => function ($query) {
                    $query->select('id', 'tenure', 'advance_emi', 'interest_rate', 'annualised_irr');
                }, 'emi' => function ($query) {
                    $query->select('application_id', 'offer_id', 'tenure', 'remaining_emi', 'advance_emi', 'emi_date',
                        'subvention', 'processing_fee',
                        'annualised_interest', 'annualised_irr', 'upfront_from_customer');
                }, 'proFormaInvoice' => function ($query) {
                    $query->select('application_id', 'insurance_premium_amount', 'insurance_premium_by_merchant');
                }, 'application_element' => function ($query) {
                    $query->select('application_id', 'payment_transfer_date');
                }
            ])
            ->where('id', $this->application_id)->first(['id', 'loan_amount', 'approved_amount', 'offer_id']);

        $statusLogs = StatusLogs::where('application_id', $this->application_id)->where('status', 'disbursed')->orderBy('created_at', 'desc')->first(['id', 'created_at']);

        $payment_transfer_date = null; //$application_details->application_element->payment_transfer_date;

        $statusLog = StatusLogs::where('application_id', $this->application_id)->where('status', 'disbursed')->orderBy('created_at', 'desc')->first(['application_id', 'created_at']);

        $disbursal_date_str = $this->is_pre_part_payment && isset($statusLog->created_at) ? Carbon::parse($statusLog->created_at)->format('d-m-Y') : Carbon::now()->format('d-m-Y');

        $loan_amount = $application_details->loan_amount;
        $approved_amount = $application_details->approved_amount;
        $insurance_fee = $application_details->proFormaInvoice->insurance_premium_amount ?? 0;

        $emiCalculation = new EMICalculation(new Request());
        if ($emiCalculation->isLoanAmountAddedInLoanAmount($this->application_id, $application_details->pro_forma_invoice)){
            $loan_amount += $insurance_fee;
            $approved_amount += $insurance_fee;
        }

        $payload = [
            'application_id' => $this->application_id,
            'loan_principal' => $approved_amount - $application_details->emi->upfront_from_customer  ?? $loan_amount - $application_details->emi->upfront_from_customer ?? 0,
            'annualised_interest' => (float)$application_details->emi->annualised_interest ?? (int)$application_details->offer->annualised_irr ?? 0,
            'annualised_irr' => (float)$application_details->emi->annualised_irr ?? (int)$application_details->offer->annualised_irr ?? 0,
            'remaining_emi' => $application_details->emi->remaining_emi ?? $application_details->offer->tenure-$application_details->offer->advance_emi ?? 0,
//            'disbursal_date_str' => $payment_transfer_date != null ? Carbon::parse($payment_transfer_date)->format('d-m-Y') : Carbon::now()->toDate()->format('d-m-Y'),
            'disbursal_date_str' => $disbursal_date_str,
            'first_emi_date_str' => Carbon::parse($application_details->emi->emi_date)->format('d-m-Y'),
            'morat_months' => 0,
            'morat_start_date_str' => '',
            'subvention' => $application_details->emi->subvention ?? 0,
            'insurance_amount' => $insurance_fee,
            'processing_fee' => $application_details->emi->processing_fee ?? 0,
        ];
        $this->payload = json_encode($payload);
    }

    /*// Private function to call and do the necessary changes after RPS API
    private function callRPSAPI(){
        $response = $this->apiCall();
        return json_decode($response, 1);
    }*/

    // public function to set EMI details for the application
    public function setEMIdetails($app_id, $rps_json = ''){
        if($rps_json == ''){
            $rps_json = RPS_Logs::where('application_id', $app_id)->get();
        }
        $emi_exists = EmiPayment::where('application_id', $app_id)->exists();
        if($emi_exists){
            EmiPayment::where('application_id', $app_id)->delete();
        }
        (new Slack(new Request(['title' => 'Reco Logs setEMIdetails', 'fields' => ['payload' => json_encode($rps_json)], 'group' => Slack::$STAGE_TESTING])))->send();

        foreach($rps_json as $rps){
            $emi_update = new EmiPayment();
            $emi_update->emi_date = $rps->emi_date ?? $rps['emi_date'];
            $emi_update->pre_emi_amount = $rps->bpi_interest ?? $rps['bpi_interest'] ?? 0;
            $emi_update->emi_amount = $rps->emi_amount ?? $rps['emi_amount'] ?? 0;
            $emi_update->bounce_charges = 0;
            $emi_update->delay_penalty = 0;
            $emi_update->payment_status = 'pending';
            $emi_update->application_id = $rps->application_id ?? $rps['application_id'] ?? 0;
            $emi_update->due_date = $rps->due_date ?? $rps['due_date'];
            $emi_update->total_payable = $rps->total_payable ?? $rps['total_payable'] ?? 0;
            $emi_update->amount_due = $rps->total_payable ?? $rps['total_payable'] ?? 0;
            $emi_update->charges_waived = 0;
            $emi_update->created_at = Carbon::now()->toDateTimeString();
            $emi_update->save();
        }

        return true;
    }

    // Public function to perform Reconciliation
    public function reconcilePayment($app_id, $data){
        $_data = array_slice($data, 0, 2);
        $this->application_id = $app_id;
        $this->payment_details = $_data;
        $this->setReconciliationPayload('reconciliation');
        $response = $this->apiCall('reconciliation');
        if($response){
            $this->getReconciliationDetails($response, $data);
        }
        return $response;
    }

    public function callReconcileApi($app_id, $data){
        $this->application_id = $app_id;
        $this->payment_details = $data;
        $this->setReconciliationPayload('settlement_reconcile');
        $response = $this->apiCall('settlement_reconcile');

        // if($response){
        //     $this->getReconciliationDetails($response, $data);
        // }
        return $response;
    }

    // Private function to get details and set the values of reconciliation in tables
    private function getReconciliationDetails($response, $data){
        $emi_payment_date = [];

        Reconciliation_Logs::where('id', $this->reconciliation_id)->update([
            'response' => json_encode($response),
            'updated_at' => Carbon::now()->toDateTimeString()
        ]);

        $emi_paid = 0;
        $emi_due = 0;
        $overdue_amount = 0;
        $today = Carbon::now()->toDateString();
        $overPayment = $response['over_payment'] ?? 0;
        $total_amount_due = 0;

        if($overPayment > 0){
            PaymentTransaction::insert([
                'emi_payment_id' => 0,
                'application_id' => $this->application_id,
                'amount' => $overPayment ?? 0,
                'mode' => $data['payment_mode'],
                'trasanction_id' => $data['trasanction_id'],
                'trasanction_acknowledgement' => $data['trasanction_acknowledgement'],
                'payment_date' => Carbon::parse($data['payment_date'])->format('Y-m-d'),
                'status' => $data['status'],
                'paid_by' => $data['paid_by'],
                'created_at' => Carbon::now()->toDateTimeString(),
                'collected_by' => $data['collected_by'],
                'collected_by_type' => $data['collected_by_type'],
                'payment_for' => 'Over Payment',
                'payment_reconciliation_date' => Carbon::parse($data['payment_reconciliation_date'])->format('Y-m-d'),
                'cf_transaction_id' => $data['cf_transaction_id'],
                'bank_id' => $data['bank_id'],
                'umrn' => $data['umrn'],
                'wallet_name' => $data['wallet_name'],
                'reason' => $data['reason'],
                'adjust_with_disbursement' => $data['adjust_with_disbursement']
            ]);
        }

        foreach($response['payment_allocation_json'] as $value){
            $_payment_details = explode(',', $value['payment_details']);
            if($_payment_details[0] != '') {
                foreach ($_payment_details as $val) {
                    $_payment = explode(' - ', $val);
                    $_payment_date = $_payment[0];
                    $_payment_amount = $_payment[1];
                    $_payment_for = $_payment[2];

                    if($this->isBPIReceived($this->application_id, $_payment_for)) {
                        if ($_payment_amount > 0) {
                            PaymentTransaction::insert([
                                'emi_payment_id' => $value['emi_payment_id'],
                                'application_id' => $this->application_id,
                                'amount' => $_payment_amount ?? 0,
                                'mode' => $data['payment_mode'],
                                'trasanction_id' => $data['trasanction_id'],
                                'trasanction_acknowledgement' => $data['trasanction_acknowledgement'],
                                'payment_date' => Carbon::parse($_payment_date)->format('Y-m-d'),
                                'status' => $data['status'],
                                'paid_by' => $data['paid_by'],
                                'created_at' => Carbon::now()->toDateTimeString(),
                                'collected_by' => $data['collected_by'],
                                'collected_by_type' => $data['collected_by_type'],
                                'payment_for' => $_payment_for == 'bpi' ? 'Pre-EMI' : 'EMI',
                                'payment_reconciliation_date' => Carbon::parse($data['payment_reconciliation_date'])->format('Y-m-d'),
                                'cf_transaction_id' => $data['cf_transaction_id'],
                                'bank_id' => $data['bank_id'],
                                'umrn' => $data['umrn'],
                                'wallet_name' => $data['wallet_name'],
                                'reason' => $data['reason'],
                                'adjust_with_disbursement' => $data['adjust_with_disbursement']
                            ]);
                        }
                    }
                }
                unset($value['payment_details']);
            }
            $emi_payment_date[$value['emi_payment_id']] = $value;
            $emi_payment_date[$value['emi_payment_id']]['payment_date'] = $_payment_date ?? $value['payment_date'];
            if($value['payment_status'] == 'success'){
                $emi_paid += 1;
            }else{
                $emi_due += 1;
                $_due_amount = $value['total_payable'] - $value['total_paid'];
                if($today > $value['due_date']){
                    $overdue_amount += $_due_amount;
                }
            }
        }

        $emi_payments = EmiPayment::whereIn('id', array_keys($emi_payment_date))->get();
        foreach ($emi_payments as $epayment) {
            $epayment->bounce_charges = $emi_payment_date[$epayment->id]['bounce_charges'];
            $epayment->delay_penalty = $emi_payment_date[$epayment->id]['delay_penalty'];
//            $epayment->payment_mode = $data['payment_mode'];
            $epayment->charges_waived = $emi_payment_date[$epayment->id]['charges_waived'];
            if($emi_payment_date[$epayment->id]['payment_date'] != " "){
                $epayment->payment_date = Carbon::parse($emi_payment_date[$epayment->id]['payment_date'])->toDateTimeString();
            }else{
                $epayment->payment_date = Carbon::parse($epayment->payment_date)->toDateTimeString();
            }
            $epayment->payment_status = $emi_payment_date[$epayment->id]['payment_status'];
            $epayment->total_payable = $emi_payment_date[$epayment->id]['total_payable'];
            $epayment->amount_due = $emi_payment_date[$epayment->id]['amount_due'];
            $epayment->delay_days = $emi_payment_date[$epayment->id]['delay_days'];
//            $epayment->moratorium = $emi_payment_date[$epayment->id]['moratorium'] ?? 0;
//            $epayment->moratorium_amount = $emi_payment_date[$epayment->id]['moratorium_amount'] ?? 0;
            $epayment->updated_at = Carbon::now()->toDateTimeString();
            $epayment->save();
        }

        $total_amount_due = EmiPayment::where('application_id', $this->application_id)->get(['id', 'amount_due'])->sum('amount_due');

        $this->updateForeclosure($this->application_id, [
            'emi_pending' => $emi_due,
            'emi_paid' => $emi_paid,
            'amount_over_due' => $overdue_amount,
            'total_amount_due' => $total_amount_due
        ]);
    }

    public function isBPIReceived($id, $_payment_for){
        if ($_payment_for == 'bpi'){
            $paymentTransaction = PaymentTransaction::where('application_id', $id)->where('payment_for', 'Pre-EMI')->first(['id']);
            if (isset($paymentTransaction->id)){
                return false;
            }
        }

        return true;
    }

    // Private function to set Payload for Reconciliation API
    private function setReconciliationPayload($type){
        if($type == 'settlement_reconcile'){
            $payload = $this->payment_details;
        }else{
            $payload = [
                'application_id' => (int)$this->application_id,
                'payment_list' => $this->payment_details
            ];
        }

        $this->payload = json_encode($payload,1);

        $this->reconciliation_id = Reconciliation_Logs::insertGetId([
            'application_id' => $this->application_id,
            'request' => json_encode($payload),
            'created_at' => Carbon::now()->toDateTimeString()
        ]);
    }

    public function callPaymentUpdateApis($app_id){

        $payload = [
            'app_id_list' => [
                (int)$app_id
            ]
        ];
        $this->payload = json_encode($payload,1);
        $this->apiCall('payment_api_overdue');
        //$this->apiCall('payment_api_penal');
        return true;
    }
   /*// Private function to call and set all changes after Recon API
    private function callReconciliationAPI(){
        $response = $this->apiCall();
        return json_decode($response, 1);
    }*/

    // Generic API call for all APIS
    private function apiCall($type){
        $curl = curl_init();

        $url = $type == 'rps' ? $this->endPointRPS : $this->endPointReconciliation;

        if($type == 'rps_subvention') {
            $url = $this->endPointRPSSubvention;
        }
        if($type == 'settlement_reconcile') {
            $url = $this->endPointSettlementReconciliation;
        }

        if($type == 'bounce_penal_update' || $type == 'payment_api_penal') {
            $url = $this->endPointBouncePenalUpdate;
        }

        if($type == 'overdue_update' || $type == 'payment_api_overdue') {
            $url = $this->endPointOverdueUpdate;
        }

        curl_setopt_array($curl, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $this->payload,
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/json',
            ),
        ));

        $curl1 = $curl;

        $response = curl_exec($curl1);
        (new Slack(new Request(['title' => 'Recon API Response', 'fields' => [json_encode($response)]])))->send();
        if (curl_error($curl1)) {
            $error = curl_error($curl1);
            (new Slack(new Request(['title' => 'Recon API Error', 'fields' => [$error]])))->send();
        }
        curl_close($curl1);

        return json_decode($response, 1);
    }

    //Public function to get updated repayment status
    public function getRepaymentUpdates($app_id){
        $data = [
            'amount' => 0,
            'payment_date' => Carbon::now()->format('d-m-Y')
        ];
        return $this->reconcilePayment($app_id, $data);
    }

    //Public function to get updated details for account statement
    public function getStatementDetails($app_id){
        $consumerApplicationController = new ConsumerApplicationController();
        $frontController = new FrontController();
        $hashids = new Hashids('Creditfair by CS', 20);
        $hashed_id = $hashids->encode($app_id);

        $response = $this->getRepaymentUpdates($app_id);

        /* Account statement return response */
        $application = ConsumerApplication::with([
            'merchant' => function ($query) {
                $query->select('id', 'merchant_name');
            },
            'category' => function ($query) {
                $query->select('id', 'name');
            },
            'disbursed' => function ($query) {
                $query->select('application_id', 'created_at');
            },
            'emi' => function ($query) {
                $query->select('application_id', 'tenure', 'remaining_emi','advance_emi','emi_date', 'emi', 'processing_fee', 'interest_rate', 'upfront_from_customer');
            },
            'proFormaInvoice' => function ($query) {
                $query->select('application_id', 'loan_application_no', 'created_at');
            },
            'application_element' => function ($query) {
                $query->select('application_id', 'product_name',  'total_amount_due', 'amount_over_due', 'emi_paid', 'emi_pending');
            },
            'emi.offer' => function ($query) {
                $query->select('id', 'processing_fee_first_emi');
            },
            'foreclosed_transaction'
        ])->where('id', $app_id)->first(['id', 'merchant_id', 'purpose', 'name', 'lender_id', 'offer_id', 'state', 'approved_amount']);

        $_principal_outstanding = 0;
        $_principal_outstanding_paid = 0;
        $rev_response_json = array_reverse($response['payment_allocation_json']);
        $length = count($rev_response_json);
        $scheduleData = [];
        $pending_transaction = [];
        $success_transaction = [];
        $last_transaction = [];
        $pre_emi_transaction = [];
        $total_amount_paid = 0;
        $installment_number = 0;
        foreach($rev_response_json as $key => $resp){
            $index = ($key + 1);

            $_principal_outstanding_paid += $resp['principal_comp_paid'];
            //$_principal_outstanding_old = $_principal_outstanding;
            //$_principal_outstanding += $resp['principal_comp'];
            //$_principal_outstanding_old -= $resp['principal_comp_paid'];

            if($resp['bpi_interest'] > 0){
                $pre_emi_transaction [] = [
                    'id' => 'Pre-EMI',
                    'due_date' => date('d-M-Y', strtotime($resp['due_date'])),
                    'next_emi_word' => $frontController->getWordsFromInstallment($installment_number),
                    'principal_outstanding' => $resp['principal_outstanding'],
                    'installment_amount' => $resp['bpi_interest'],
                    'principal' => 0,
                    'interest' => $resp['bpi_interest'],
                    'closing_balance' => 0,
                    'bounce' => 0,
                    'penal' => 0,
                    'charges_waived' => $resp['emi_amount'] > 0 ? 0 : $resp['charges_waived'],
                    'total_due' => $resp['amount_due'],
                    'amount_received' => $resp['total_paid_for_bpi'],
                    'payment_date' => $resp['payment_status'] == 'pending' ? '' : date('d-M-Y', strtotime($resp['payment_date'])),
                    'last_payment_date' => '',
                    'payment_mode' => '',
                    'moratorium_amount' => 0,
                    'payment_status' => $resp['total_paid_for_bpi'] == $resp['bpi_interest'] ? 'success' : $resp['payment_status']
                ];
            }

            if($resp['emi_amount'] > 0 ) {
                $installment_number++;
                $_schedule_var = [
                    'id' => $installment_number,
                    'due_date' => date('d-M-Y', strtotime($resp['due_date'])),
                    'next_emi_word' => $frontController->getWordsFromInstallment($installment_number),
                    'principal_outstanding' => $resp['principal_outstanding'],
                    'installment_amount' => $resp['emi_amount'],
                    'principal' => $resp['principal_comp'],
                    'interest' => $resp['interest_comp'],
                    'closing_balance' => 0,
                    'bounce' => $resp['bounce_charges'],
                    'penal' => $resp['delay_penalty'],
                    'charges_waived' => $resp['charges_waived'],
                    'total_due' => $resp['amount_due'],
                    'amount_received' => $resp['total_paid'],
                    'payment_date' => $resp['payment_status'] == 'pending' ? '' : date('d-M-Y', strtotime($resp['payment_date'])),
                    'last_payment_date' => '',
                    'payment_mode' => '',
                    'moratorium_amount' => 0,
                    'payment_status' => $resp['payment_status']
                ];

                $scheduleData[$length - $index] = $_schedule_var;

                $total_amount_paid += $resp['total_paid'];

                if ($resp['payment_status'] == 'pending') {
                    $pending_transaction[] = $_schedule_var;
                } else {
                    $success_transaction[] = $_schedule_var;
                }
            }
        }

        $scheduleData = array_reverse($scheduleData);
        $pending_transaction = array_reverse($pending_transaction);
        $success_transaction = array_reverse($success_transaction);
        $last_transaction = end($success_transaction);

        $disbursed_date = $consumerApplicationController->getDisbursedDate($application->id);
        if($disbursed_date) {
            $disbursed_date = date('d M Y', strtotime($disbursed_date));
        }

        $pre_part_payment_amount = PaymentTransaction::where('application_id', $app_id)->whereNull('is_deleted_at')->where('payment_for', 'pre_part_payment')->sum('amount');
        if($pre_part_payment_amount){
            $total_amount_paid += $pre_part_payment_amount;
        }

        $isForeclosed = 0;
        $advance_amount = 0;
        $processing_fee = 0;
        $processing_fee_due = (isset($application->emi->processing_fee)) ? ($application->emi->processing_fee - $processing_fee) : 0;
        $advance_amount_due = (isset($application->proFormaInvoice->merchant_collected_advance_amount) && $application->proFormaInvoice->merchant_collected_advance_amount && $application->emi) ? ($application->emi->upfront_from_customer - $advance_amount) : 0;

        $overPayments = PaymentTransaction::with('refundPayment')->where('application_id', $app_id)->whereIn('payment_for', ['processing_fee', 'Advance Payment', 'Foreclosure'])->whereNull('is_deleted_at')->get();
        if ($overPayments) {
            foreach ($overPayments as $overpayment) {
                if ($overpayment->amount > 0 && ($overpayment->payment_for == "processing_fee")) {
                    $processing_fee = $processing_fee + $overpayment->amount;
                }
                if ($overpayment->amount > 0 && ($overpayment->payment_for == "Foreclosure") && $overpayment->status != "rejected") {
                    $isForeclosed = 1;
                }
            }
        }

        $foreclosure_breakup = $this->getNewForeclosureBreakup($app_id, $response, $processing_fee_due, $isForeclosed, $advance_amount_due);

        $amount_financed = EMICalculation::getLoanAmountWithInsuranceAmount($app_id);

        $data = [
            'id' => $hashed_id,
            'lender_id' => $application->lender_id,
            'merchant_id' => $application->merchant_id,
            'category_id' => $application->purpose,
            'customer_name' => $application->name,
            'merchant_name' => $application->merchant->merchant_name,
            'amount_pending' => $application->application_element->total_amount_due ?? 0,
            'amount_paid' => $total_amount_paid,
            'emi_paid' => $application->application_element->emi_paid ?? 0,
            'category_name' => $application->category->name ?? '',
            'disbursed_date' => $disbursed_date ?? $application->disbursed->created_at ?? '',
            'emi_due' => $application->application_element->emi_pending ?? 0,
            'amount_due' => $application->application_element->amount_over_due ?? 0,
            'advance_amount' => $application->emi->upfront_from_customer,
            'total_emi' => $application->emi->tenure,
            'advance_emi' => ($application->emi->tenure - $application->emi->remaining_emi),
            'product' => isset($application->application_element) && !empty($application->application_element->product_name) ? $application->application_element->product_name : '',
            'agreement_no' => $application->proFormaInvoice && $application->proFormaInvoice->loan_application_no ? $application->proFormaInvoice->loan_application_no : '',
            'agreement_date' => date('d-m-Y', strtotime($application->proFormaInvoice->created_at)),
            'frequency' => 'Monthly',
            'amount_financed' => $amount_financed,
            'interest' => $application->emi->interest_rate,
            'tenure' => $application->emi->tenure,
            'processing_fee' => $application->emi->processing_fee,
            'processing_fee_first_emi' => $application->emi->offer->processing_fee_first_emi ?? 0,
            'remaining_emi' => $application->application_element->emi_pending ?? 0,
            'status' => (in_array($application->state, ['disbursed', 'nach registered'])) ? 'Active' : 'Inactive',
            'schedule' => array_merge($pre_emi_transaction,$scheduleData),
            'last_transaction' => $last_transaction,
            'pending_transaction' => $pending_transaction,
            'success_transaction' => $success_transaction,
            'fore_closure_amount' => $foreclosure_breakup['total_foreclosure_amount'],
            'account_statement' => asset('/consumer/account-statement/'.$app_id),
            'isMoratorium' => false, //TODO:
            'isForeclosed' => (bool)$application->foreclosed_transaction
        ];

        if(isset($application->foreclosed_transaction->id)){
            $data['foreclosedAmount'] =  $application->foreclosed_transaction->amount;
            $data['foreclosedMode'] =  $application->foreclosed_transaction->mode;
            $data['foreclosedDate'] =  $application->application_element->foreclosure_date;
        }

        return $data;
    }

    //Public function to get updated details for Loan Schedule Page
    public function getLoanScheduleDetails($app_id){
        $response =  $this->getRepaymentUpdates($app_id)['payment_allocation_json'];

        $_total_due = 0;
        $_principal_outstanding = 0;
        $_principal_outstanding_paid = 0;
        $principal_outstanding = [];
        $rev_response_json = array_reverse($response);
        $length = count($rev_response_json);
        $emi_payment_ids = [];
        $amount_due = [];
        foreach($rev_response_json as $key => $resp) {

//            $_principal_outstanding_paid += $resp['principal_comp_paid'];
//            $_principal_outstanding_old = $_principal_outstanding;
//            $_principal_outstanding += $resp['principal_comp'];

            $_total_due += $resp['payment_status'] != 'success' ? $resp['amount_due'] : 0;
            $emi_payment_ids[$length-$key] = $resp['emi_payment_id'];

            $amount_due[$length-$key] = $_total_due;
//            $principal_outstanding[$length-$key] = $_principal_outstanding;
        }

//        $principal_outstanding = array_reverse($principal_outstanding);
        $amount_due = array_reverse($amount_due);
        $emi_payment_ids = array_reverse($emi_payment_ids);
        $transactions = EmiPayment::with('transaction')->whereIn('id', $emi_payment_ids)->get()->toArray();

        foreach($response as $i => $item){
            $response[$i]['id'] = $item['emi_payment_id'];
//            $response[$i]['principal_outstanding'] = $principal_outstanding[$i];
            $response[$i]['foreclosure_amount'] = $item['payment_status'] != 'success' && isset($response[$i+1]['interest_comp']) ? $item['principal_outstanding'] + $response[$i+1]['interest_comp'] + $item['amount_due'] : $item['principal_outstanding'];
            $response[$i]['transaction'] = $transactions[$i]['transaction'] ?? [];
            unset($response[$i]['emi_payment_id']);
        }

        return $response;
    }

    //Public function to get updated details for Payment Page
    public function getPaymentPageDetails($app_id){
        try {
            $pre_paid_ids = explode(',', _env('PRE_PAID_CASE_IDS', '0,0'));
            $response = !in_array($app_id, $pre_paid_ids) ? $this->getRepaymentUpdates($app_id) : false;

            $application = ConsumerApplication::with([
                'emi' => function ($query) {
                    $query->select('application_id', 'tenure', 'remaining_emi', 'advance_emi', 'emi_date', 'emi', 'processing_fee', 'upfront_from_customer');
                },
                'proFormaInvoice' => function ($query) {
                    $query->select('application_id', 'loan_application_no', 'merchant_collected_advance_amount');
                },
                'application_element' => function ($query) {
                    $query->select('id','application_id', 'product_name', 'total_amount_due', 'amount_over_due', 'emi_paid', 'emi_pending', 'foreclosure_date');
                },
                'lender' => function ($query) {
                    $query->select('id', 'name');
                },
                'emi_payment' => function ($query) {
                    $query->select('id', 'emi_date', 'payment_date', 'payment_status', 'application_id');
                },
                'emi_payment.transaction' => function ($query) {
                    $query->select('application_id', 'id', 'emi_payment_id', 'cf_transaction_id', 'amount', 'trasanction_id', 'payment_date', 'payment_reconciliation_date', 'mode', 'paid_by', 'trasanction_acknowledgement', 'refunded_at', 'bank_id');
                },
                'emi_payment.transaction.bank' => function ($query) {
                    $query->select('id', 'bank_name');
                },
                'emi_payment.moratoriums' => function ($query) {
                    $query->select('id', 'emi_date', 'application_id', 'interest_rate', 'started_date', 'stopped_date');
                },
                'settlement_payment'
            ])->where('id', $app_id)->first(['id', 'name', 'lender_id', 'state']);

            $foreclosure_date = '';
            $over_payment = 0;
            $over_payment_amount = 0;
            $adhoc_payment = 0;
            $advance_amount = 0;
            $processing_fee = 0;
            $foreclosure_amount_cals = 0;
            $foreclosed_info = [];
            $settled_info = [];
            $isForeclosed = 0;

            $isSettled = false;
            $settlement_amount = 0;
            if(isset($application->settlement_payment) && $application->settlement_payment->sum('amount') > 0){
                $settlement_amount = $application->settlement_payment->sum('amount');
                $isSettled = true;
            }

            $amount_paid = PaymentTransaction::where('application_id', $app_id)->whereIn('payment_for', ['EMI', 'Pre-EMI', 'Foreclosure', 'Advance Payment', 'Over Payment'])->whereNull('is_deleted_at')->get(['id', 'amount'])->sum('amount');

            $foreclosure_breakup = $application->foreclosure_breakup;
            $application_details = $application;
            unset($application->foreclosure_breakup);
            unset($application_details->emi_payment);

            $waived_off_data = (new LoanManagement())->getWaivedOff($app_id);
            $can_waive_off = (new AccountingController())->canWaiveOff($app_id) ? 1 : 0;

            $overPayments = PaymentTransaction::with('refundPayment')->where('application_id', $app_id)->whereIn('payment_for', ['processing_fee', 'Over Payment', 'Advance Payment', 'rejected', 'Foreclosure', 'refund', 'collection_charges', 'insurance_fee', 'adhoc_transaction', 'advance_amount', 'cancellation_charges', 'Write-off', 'legal_charges', 'pre_payment', 'pre_part_payment', 'settled_principal', 'settled_interest', 'settled_bounce', 'settled_penal'])->whereNull('is_deleted_at')->get();
            $adhoc_transactions = $overPayments;
            if ($overPayments) {
                foreach ($overPayments as $overpayment) {
                    if ($overpayment->amount > 0 && ($overpayment->payment_for == "Over Payment") && $overpayment->status != "rejected") {
                        $over_payment = $over_payment + $overpayment->amount;
                        if ($overpayment->refunded_at && $overpayment->refunded_by && $overpayment->refund_maker_id && $overpayment->refund_maker_at) {
                            $over_payment = $over_payment - $overpayment->amount;
                        }
                    }
                    if ($overpayment->amount > 0 && ($overpayment->payment_for == "processing_fee")) {
                        $processing_fee = $processing_fee + $overpayment->amount;
                    }
                    if ($overpayment->amount > 0 && $overpayment->payment_for == "refund") {
                        $over_payment = $over_payment - $overpayment->amount;
                    }
                    if ($overpayment->amount > 0 && ($overpayment->payment_for == "Over Payment" || $overpayment->payment_for == "Advance Payment" || $overpayment->payment_for == "Foreclosure") && $overpayment->status != "rejected") {
                        $adhoc_payment = $adhoc_payment + $overpayment->amount;
                    }
                    if ($overpayment->amount > 0 && ($overpayment->payment_for == "advance_amount")) {
                        $advance_amount = $advance_amount + $overpayment->amount;
                    }
                    if ($overpayment->amount > 0 && ($overpayment->payment_for == "Foreclosure") && $overpayment->status != "rejected") {
                        $isForeclosed = 1;
                    }

                    if ($overpayment->payment_for == "Foreclosure") {
                        $foreclosure_date = $overpayment->payment_date;
                        $foreclosed_info = [
                            'foreclosed_amount' => $foreclosure_amount_cals + $overpayment->amount,
                            'foreclosed_payment_date' => $overpayment->payment_date,
//                        'foreclosed_payment_reconcile_date' => $overpayment->payment_reconciliation_date,
                            'foreclosed_payment_mode' => $overpayment->mode,
                            'foreclosed_transaction_id' => $overpayment->trasanction_id,
                            'foreclosed_cf_transaction_id' => $overpayment->cf_transaction_id,
                        ];

                    }

                    if ($isSettled && ($overpayment->payment_for == "settled_principal")){
                        $settled_info = [
                            'settled_amount' => $settlement_amount,
                            'settled_payment_date' => $overpayment->payment_date,
    //                        'settled_payment_reconcile_date' => $overpayment->payment_reconciliation_date,
                            'settled_payment_mode' => $overpayment->mode,
                            'settled_transaction_id' => $overpayment->trasanction_id,
                            'settled_cf_transaction_id' => $overpayment->cf_transaction_id,
                        ];
                    }

                }
                $over_payment_amount = $over_payment;
            } else {
                $over_payment_amount = 0;
            }

            $processing_fee_due = (isset($application->emi->processing_fee)) ? ($application->emi->processing_fee - $processing_fee) : 0;
            $advance_amount_due = (isset($application->proFormaInvoice->merchant_collected_advance_amount) && $application->proFormaInvoice->merchant_collected_advance_amount && $application->emi) ? ($application->emi->upfront_from_customer - $advance_amount) : 0;
            $max_payable = $application->application_element->total_amount_due > 0 ? $application->application_element->amount_over_due : 0;
            $payment_logs = PaymentLogs::where('application_id', $app_id)->orderBy('created_at', 'desc')->get();
            $_payment_logs = [];
            foreach ($payment_logs as $payment_log) {
                $_payment_logs[$app_id][$payment_log->emi_payment_id][] = $payment_log;
            }

            $foreclosure_breakup = [];
            /*$foreclosure_breakup = !in_array($app_id, $pre_paid_ids) ?
                $this->getNewForeclosureBreakup($app_id, $response, $processing_fee_due, $isForeclosed, $advance_amount_due) :
                [
                    'is_foreclosed' => 1,
                    'principal_due' => 0,
                    'interest_due' => 0,
                    'moratorium_due' => 0,
                    'bounce_charges' => 0,
                    'penal_charges' => 0,
                    'emi_due' => 0,
                    'pf_due' => 0,
                    'advance_due' => 0,
                    'total_foreclosure_amount' => 0,
                ];*/

            $foreclosedAmount = DB::select("select sum(amount) as 'amount' from payment_transactions_temp where trasanction_id=(select trasanction_id from payment_transactions_temp where application_id=" . $app_id . " and payment_for='Foreclosure');");
            if (isset($foreclosedAmount[0]->amount) && isset($data['foreclosure_amount']) && $foreclosedAmount[0]->amount < $data['foreclosure_amount']) {
                $isForeclosed = 0;
            }

            if ($foreclosure_date == "") {
                $foreclosure_date = date('Y-m-d', (strtotime('29 day', time())));
            }

            return [
                "paymentsData" => $application->emi_payment,
                "application" => $application_details,
                "over_payment" => $over_payment_amount,
                "adhoc_transactions" => $adhoc_transactions,
                "amount_paid" => $amount_paid,
                "max_payable" => $max_payable,
                "moratoriumsLogs" => Moratorium::with('user', 'stopped')->where('application_id', $app_id)->get(),
                "frequencyDetails" => ApplicationEMICalculation::where('application_id', $app_id)->first(['payment_frequency'])->toArray(),
                "processing_fee_due" => $processing_fee_due,
                "advance_amount_due" => $advance_amount_due,
                "foreclosure_date" => $foreclosure_date,
                "waived_off_data" => $waived_off_data ?? [],
                "can_waive_off" => $can_waive_off,
                "foreclosure_breakup" => $foreclosure_breakup,
                "payment_logs" => $_payment_logs,
                "foreclosed_info" => $foreclosed_info,
                "isForeclosed" => $isForeclosed,
                "isSettled" => $isSettled,
                "settlement_amount" => $settlement_amount,
                "settled_info" => $settled_info ?? [],
                "reference" => AvanseCreateFinance::where('application_id', $app_id)->first(),
                "lender_name" => $application->lender->name ?? ''
            ];
        } catch (\Exception $e) {
            $cwFactory = new CloudWatchLoggerFactory();
            $_data = array(
                'exception' => 'Error while calling Payment Page API',
                'message' => $e->getMessage(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString()
            );
            $cwFactory->logger(json_encode($_data));
        }
        return false;
    }

    public function updateForeclosure($application, $update = []){
        $application_id = $application->id ?? $application;
        if (!isset($application->id)){
            $application = ConsumerApplication::with(['application_element' => function ($query) {
                $query->select('id','application_id', 'product_name', 'total_amount_due', 'amount_over_due', 'emi_paid', 'emi_pending', 'foreclosure_date');
            }])->where('id', $application_id)->first(['id']);
        }
        $foreclosure_amount = PaymentTransaction::where('application_id', $application_id)->where('payment_for', 'Foreclosure')->whereNull('is_deleted_at')->whereNull('deleted_by')->first(['amount']);
        $writeOff_amount = PaymentTransaction::where('application_id', $application_id)->where('payment_for', 'Write-off')->whereNull('is_deleted_at')->whereNull('deleted_by')->first(['id']);

        if ((isset($application->application_element->foreclosure_date) && !empty($application->application_element->foreclosure_date) && $application->application_element->foreclosure_date != "1970-01-01")) {
            if (isset($application->application_element) && $application->application_element) {
                $application_element = ConsumerApplicationElement::find($application->application_element->id);
            } else {
                $application_element = new ConsumerApplicationElement();
                $application_element->application_id = $application->id;
            }

            if (($application->application_element->foreclosure_date != '' && isset($foreclosure_amount->amount)) || isset($writeOff_amount->id)) {
                $total_principal_due = $total_over_due = $outstanding_principal_due = $outstanding_over_due = 0;

                $application_element->principal_due = $total_principal_due;
                $application_element->amount_over_due = $total_over_due;
                $application_element->total_principal_due = $outstanding_principal_due;
                $application_element->total_amount_due = $outstanding_over_due;
                if (isset($update['emi_pending'])){
                    $application_element->emi_pending = $update['emi_pending'];
                }
                if (isset($update['emi_paid'])) {
                    $application_element->emi_paid = $update['emi_paid'];
                }
                $application_element->save();
            }
        }else if($update){
            ConsumerApplicationElement::where('application_id', $application_id)->update($update);
        }
    }

    //Public function to get updated payment details
    public function getPaymentCalculations($app_id){
        try {
            $pre_paid_ids = explode(',', _env('PRE_PAID_CASE_IDS', '0,0'));
            return !in_array($app_id, $pre_paid_ids) ? $this->getRepaymentUpdates($app_id) : false;
        } catch (\Exception $e) {
            $cwFactory = new CloudWatchLoggerFactory();
            $_data = array(
                'exception' => 'Error while calling Payment Calculation API',
                'message' => $e->getMessage(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString()
            );
            $cwFactory->logger(json_encode($_data));
        }
        return false;
    }

    //Private function to get updated foreclosure breakup details
    private function getNewForeclosureBreakup($id, $response, $processing_fee_due, $isForeclosed, $advance_amount_due){
        try{
            $breakupLogs = ForeclosureBreakup::where('application_id', $id)->orderBy('created_at', 'desc')->first();
            if(isset($breakupLogs->id) && $isForeclosed){
                return [
                    'is_foreclosed' => 1,
                    'principal_due' => round($breakupLogs->principal_due, 2),
                    'interest_due' => round($breakupLogs->interest_due),
                    'moratorium_due' => round($breakupLogs->moratorium_due, 2),
                    'bounce_charges' => $breakupLogs->bounce_due,
                    'penal_charges' => $breakupLogs->penal_due,
                    'emi_due' => $breakupLogs->emi_due,
                    'pf_due' => $breakupLogs->pf_due,
                    'advance_due' => $breakupLogs->advance_due,
                    'total_foreclosure_amount' => $breakupLogs->foreclosure_amount,
                ];
            } else{

                if ($foreclosure_details = $this->getForeclosureThroughAPI($id)){
                    return $foreclosure_details;
                }

                $pf_due = $processing_fee_due ?? 0;
                $emi_due = 0;
                $advance_due = $advance_amount_due ?? 0;

                $_principalDue = 0;
                $_interestDue = 0;
                $_waivedAmount = 0;
                $_moratInterestDue = 0;
                $_bounceDue = 0;
                $_penalDue = 0;
                $_bpi_interest = 0;
                foreach($response['payment_allocation_json'] as $resp){
                    if($resp['payment_status'] != 'success'){
                        $_principalDue += ($resp['principal_comp'] - $resp['principal_comp_paid']);
                        $_waivedAmount += $resp['charges_waived'];
                        if(strtotime($resp['emi_date']) <= strtotime(Carbon::now()->addMonth()->toDateTimeString())){
                            $_interestDue += ($resp['interest_comp'] - $resp['interest_comp_paid']);
                        }
                        $_moratInterestDue += $resp['morat_interest'];
                        $_bounceDue += $resp['bounce_charges'];
                        $_penalDue += $resp['delay_penalty'];
                        $_bpi_interest += $resp['bpi_interest'];
                    }
                    $emi_due += ($resp['total_payable'] - $resp['amount_due']);
                }
                $foreclosure_amount =
                    round($_principalDue - $_waivedAmount) +
                    round($_moratInterestDue) + round($_interestDue) +
                    round($_bounceDue) +
                    round($_penalDue) +
                    $pf_due +
                    $advance_due+
                    $_bpi_interest;

                return [
                    'is_foreclosed' => 0,
                    'pre_emi_due' => $_bpi_interest,
                    'principal_due' => round($_principalDue - $_waivedAmount, 2),
                    'moratorium_due' => round($_moratInterestDue, 2),
                    'interest_due' => round($_interestDue),
                    'bounce_charges' => $_bounceDue,
                    'penal_charges' => $_penalDue,
                    'emi_due' => $emi_due,
                    'pf_due' => $pf_due,
                    'advance_due' => $advance_amount_due,
                    'total_foreclosure_amount' => round($foreclosure_amount),
                ];
            }
        } catch (\Exception $e) {
            $cwFactory = new CloudWatchLoggerFactory();
            $_data = array(
                'exception' => 'Error while calling Foreclosure Breakup Function',
                'message' => $e->getMessage(),
                'line' => $e->getLine(),
                'trace' => $e->getTraceAsString()
            );
            $cwFactory->logger(json_encode($_data));
        }
        return [
            'is_foreclosed' => 0,
            'principal_due' => 0,
            'moratorium_due' => 0,
            'interest_due' => 0,
            'bounce_charges' => 0,
            'penal_charges' => 0,
            'emi_due' => 0,
            'pf_due' => 0,
            'advance_due' => 0,
            'total_foreclosure_amount' => 0,
        ];
    }

    public function getForeclosureThroughAPI($id){

        $response =  (new AccountingController())->getLoanScheduleUsingPythonService($id);


        $total_foreclosure_amount = $response['message']['Pre-EMI due'] + $response['message']['Principal due'] + $response['message']['Moratorium due'] + $response['message']['Interest due'] + $response['message']['Bounce charges due'] + $response['message']['Penal charges due'] + $response['message']['PF due'] + $response['message']['Advance due'];

        return [
            'is_foreclosed' => 0,
            'pre_emi_due' => round($response['message']['Pre-EMI due']),
            'principal_due' => round($response['message']['Principal due']),
            'moratorium_due' => round($response['message']['Moratorium due']),
            'interest_due' => round($response['message']['Interest due']),
            'bounce_charges' => round($response['message']['Bounce charges due']),
            'penal_charges' => round($response['message']['Penal charges due']),
            'emi_due' => round($response['message']['Principal due'] + $response['message']['Interest due']),
            'pf_due' => round($response['message']['PF due']),
            'advance_due' => round($response['message']['Advance due']),
            'total_foreclosure_amount' => round($total_foreclosure_amount),
        ];
    }

    public static function isNEWRPSApplicable($id){
        return true;
        $statusLog = StatusLogs::where('application_id', $id)->where('status', 'approved')->first(['id', 'created_at']);
        if (isset($statusLog->id)){
            return $statusLog->created_at > _env('PYTHON_SUBVENTION_CASE_APPLY_DATE');
        }
        return false;
    }

    public function checkIfRPSExists($id){
        $is_update = RPS_Logs::where('application_id', $id)->exists();
        if(!$is_update) {
            $application = ConsumerApplication::with('activeOffer')->where('id', $id)->first(['id', 'offer_id']);
            $isHybrid = $application->activeOffer->subvention_type_id > 1;
            $this->is_pre_part_payment = true;
            $this->is_bpi_applicable = false; //OLD cases where RPS is not exists remove BPI from API
            $this->getRPSDetails($id, true, '', false, $isHybrid);
            $this->is_pre_part_payment = false;
            $this->is_bpi_applicable = true;
        }
    }

    public function update_bounce_penal($id){
        $this->application_id = $id;
        $this->payload = json_encode(['app_id_list' => [(int)$this->application_id]]);
        return $this->apiCall('bounce_penal_update');
    }

    public function update_over_due($id){
        $this->application_id = $id;
        $this->payload = json_encode(['app_id_list' => [(int)$this->application_id]]);
        return $this->apiCall('overdue_update');
    }
}
