<?php

namespace App\Avanse\Processes;

use App\Avanse\DataModels\AvanseAddDocument;
use App\Avanse\DataModels\AvanseApproveMandate;
use App\Avanse\DataModels\AvanseDeleteDocument;
use App\Avanse\DataModels\AvanseDisbursementInstruction;
use App\Avanse\DataModels\AvanseFinance;
use App\Avanse\DataModels\AvanseFinCustomStatus;
use App\Avanse\DataModels\AvanseFinOverDueDetails;
use App\Avanse\DataModels\AvanseSearchCustomer;
use App\Avanse\DataModels\AvanseStatement;
use App\Avanse\Services\AvanseServices;
use App\Avanse\Services\SubService\CreateCustomer;
use App\Avanse\Services\SubService\CreateFinance;
use App\AvanseCreateCustomer;
use App\AvanseCreateDocument;
use App\AvanseCreateFinance;
use App\Bureau;
use App\CampaignsJobProvider;
use App\CibilBureau;
use App\ConsumerApplication;
use App\ConsumerApplicationElement;
use App\ConsumerApplicationFiles;
use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\LiabilityLog;
use App\MerchantOffers;
use App\MerchantWhitelistLender;
use App\Slack;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Carbon\Carbon;
use App\OnlinePayment;
use App\Events\V1\EventPostDisbursementInstruction;
use Illuminate\Support\Facades\DB;
use MathPHP\Finance;

class AvanseProcesses
{
    private $request;
    public static $educationCategories = [4, 33, 34, 35, 36, 37, 38];
    public $documentMapped = [
        'VVCIP1' => ['vkyc_video_{id}_{applicant_type}'],
        'LOANAGG' => ['loan_agreement_esign'],
        'SANLTR' => ['sanction_letter'],
        'CAM' => ['credit_appraisal_memo'],
        'UBILLS'  => ['gas_bill', 'electricity_bill'],
        'BANKSTMTM1' => ['bank_statement_1','bank_statement_1 1', 'bank_statement_1 2', 'bank_statement_1 3', 'bank_statement_1 4', 'bank_statement_1 5', 'bank_statement_1 6'],
        'BANKSTMTM2' => ['bank_statement_2', 'bank_statement_2 1', 'bank_statement_2 2', 'bank_statement_2 3', 'bank_statement_2 4', 'bank_statement_2 5', 'bank_statement_2 6'],
        //'BANKSTMT4' => ['bank_statement_4', 'bank_statement_4 1', 'bank_statement_4 2', 'bank_statement_4 3', 'bank_statement_4 4', 'bank_statement_4 5', 'bank_statement_4 6'],
        //'BANKSTMT5' => ['bank_statement_5', 'bank_statement_5 1', 'bank_statement_5 2', 'bank_statement_5 3', 'bank_statement_5 4', 'bank_statement_5 5', 'bank_statement_5 6'],
        'BANKSTMT6' => ['bank_statement_6', 'bank_statement_6 1', 'bank_statement_6 2', 'bank_statement_6 3', 'bank_statement_6 4', 'bank_statement_6 5', 'bank_statement_6 6'],
        'SALSLIP' => ['salary_slip'],
        'ADHRCRD' => ['aadhar_card','co_applicant_aadhar_card'],
        'ADHRCRDB' => ['aadhar_card_back','co_applicant_aadhar_card_back'],
        'PAN' => ['pan_card','co_applicant_pan_card'],
        'BANKSTMTM3' => ['BANKSTMTM3','bank_statement_3', 'bank_statement_3 1', 'bank_statement_3 2', 'bank_statement_3 3', 'bank_statement_3 4', 'bank_statement_3 5', 'bank_statement_3 6'],
        'INRTN' => ['itr'],
        'CUSTPHOTO' => ['customer_photo'],
        'COAPPPH' => ['co_applicant_customer_photo'],
        'EMAN' => ['e mandate','emandate'],
        'FINBIT' => ['finbit_analysis']
    ];

    public $kycDocuments = [
        'VVCIP1', 'VVCIP2'
    ];

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

    public function populateDocumentMapping(){
        $documents = DB::connection('avanse')->table('BMTDocumentTypes')->get(['DocTypeCode']);
        foreach ($documents as $document){
            if (!isset($this->documentMapped[$document->DocTypeCode])) {
                $this->documentMapped[$document->DocTypeCode] = [$document->DocTypeCode];
            }
        }
    }

    public function createCustomer(){
        if (!$this->checkEligibility())
            return false;
        $createCustomer = new CreateCustomer($this->request);
        return $createCustomer->createCustomer();
    }

    public function callBRE(){
        $avanseFinance = new AvanseFinance($this->request);
        $response = (new AvanseServices($this->request))->callBRE($avanseFinance);

        if ($response){
            if (is_bool($response)){
                return true;
            }else{
                return $response;
            }
        }

        return $avanseFinance->error;
    }

    public function createFinance(){
        $avanseCreditPolicy = new AvanseCreditPolicy(new PolicyAttributes($this->request));
        if($avanseCreditPolicy->isWorthy()){
            $createFinance = new CreateFinance($this->request);
            return $createFinance->createFinance($avanseCreditPolicy);
        }

        return $avanseCreditPolicy->errorBag;
    }

    public function updateFinancials(){
        $avanseFinance = new AvanseFinance($this->request);
        $response = (new AvanseServices($this->request))->updateFinancials($avanseFinance);
        if ($response){
            if (isset($response->returnStatus)){
                return $response->returnStatus->returnText;
            }
            if ($this->request->get('avanse_finance_id')){
                return $this->request->get('avanse_finance_id');
            }
        }

        return $avanseFinance->error;
    }

    public function searchCustomer(){
        $avanseServices = new AvanseServices($this->request);
        $avanseSearchCustomer = new AvanseSearchCustomer($this->request);
        $avanseSearchCustomerResponse = $avanseServices->searchCustomer($avanseSearchCustomer);
        if ($avanseSearchCustomerResponse){
            return $avanseSearchCustomerResponse;
        }

        return $avanseSearchCustomer->error;
    }

    public function getDisbursementInstructions(){
        $avanseServices = new AvanseServices($this->request);
        $avanseDisbursementInstruction = new AvanseDisbursementInstruction($this->request);
        $avanseDisbursementInstructionResponse = $avanseServices->getDisbursementInstructions($avanseDisbursementInstruction);
        if ($avanseDisbursementInstructionResponse){
            return $avanseDisbursementInstructionResponse;
        }

        return $avanseDisbursementInstruction->error;
    }

    public function addDisbursementInstructionsTranches(){
        $avanseServices = new AvanseServices($this->request);
        $avanseDisbursementInstruction = new AvanseDisbursementInstruction($this->request);
        $avanseDisbursementInstructionResponse = $avanseServices->addDisbursementInstructionsTranches($avanseDisbursementInstruction);
        if ($avanseDisbursementInstructionResponse){
            return $avanseDisbursementInstructionResponse;
        }

        return $avanseDisbursementInstruction->error;
    }

    public function getFinCustomStatus(){
        $avanseServices = new AvanseServices($this->request);
        $avanseFinCustomStatus = new AvanseFinCustomStatus($this->request);
        $avanseFinCustomStatusResponse = $avanseServices->getFinCustomStatus($avanseFinCustomStatus);
        if ($avanseFinCustomStatusResponse){
            return $avanseFinCustomStatusResponse;
        }

        return $avanseFinCustomStatus->error;
    }

    public function getFinOverDueDetails(){
        $avanseServices = new AvanseServices($this->request);
        $avanseFinOverDueDetails = new AvanseFinOverDueDetails($this->request);
        $avanseFinOverDueDetailsResponse = $avanseServices->getFinOverDueDetails($avanseFinOverDueDetails);
        if ($avanseFinOverDueDetailsResponse){
            return $avanseFinOverDueDetailsResponse;
        }

        return $avanseFinOverDueDetails->error;
    }

    public function deleteDocument(){
        if (in_array($this->request->get('doc'), array_values($this->kycDocuments))){
            return $this->deleteCustomerServiceDocument();
        }else{
            return $this->deleteFinDocument();
        }

    }

    private function deleteFinDocument(){
        $avanseServices = new AvanseServices($this->request);
        $avanseDeleteDocument = new AvanseDeleteDocument($this->request);
        $avanseDeleteDocumentResponse = $avanseServices->deleteFinDocument($avanseDeleteDocument);
        if ($avanseDeleteDocumentResponse){
            return $avanseDeleteDocumentResponse;
        }

        return $avanseDeleteDocument->error;
    }

    private function deleteCustomerServiceDocument(){
        $avanseServices = new AvanseServices($this->request);
        $avanseDeleteDocument = new AvanseDeleteDocument($this->request);
        $avanseDeleteDocumentResponse = $avanseServices->customerService($avanseDeleteDocument);
        if ($avanseDeleteDocumentResponse){
            return $avanseDeleteDocumentResponse;
        }

        return $avanseDeleteDocument->error;
    }

    public function getStatement(){
        $avanseServices = new AvanseServices($this->request);
        $avanseStatement = new AvanseStatement($this->request);
        $avanseStatementResponse = $avanseServices->getStatement($avanseStatement);

        if ($avanseStatementResponse){
            return $avanseStatementResponse;
        }
        if($this->request->get('type') == "NOC"){
            return 0;
        }
        return $avanseStatement->error;

    }

    public function addDocuments(){
        $addService = new AvanseServices($this->request);
        $addDocument = new AvanseAddDocument($this->request);

        if(in_array($this->request->get('file_type'), $this->kycDocuments)){
            $response = $addService->addCustomerDocument($addDocument);
        }else {
            $response = $addService->addFinDocument($addDocument);
        }
        if ($response){
            if (is_string($response)){
                return $response;
            }
        }

        return $addDocument->error;
    }

    public function mandateApproval(){
        $avanseServices = new AvanseServices($this->request);
        $avanseApproveMandate = new AvanseApproveMandate($this->request);
        $approveMandate = $avanseServices->approveMandate($avanseApproveMandate);
        if ($approveMandate){
            return $approveMandate;
        }

        return $avanseApproveMandate->error;
    }

    public function addDisbursementInstructions(){
        $avanseServices = new AvanseServices($this->request);
        $avanseDisbursementInstruction = new AvanseDisbursementInstruction($this->request);
        $avanseDisbursementInstructionResponse = $avanseServices->addDisbursementInstructions($avanseDisbursementInstruction);
        if ($avanseDisbursementInstructionResponse){
            event(new EventPostDisbursementInstruction($this->request->get('id')));
            (new ConsumerApplicationController())->rabbitMQQueue();
            return $avanseDisbursementInstructionResponse;
        }

        return $avanseDisbursementInstruction->error;
    }

    private function isMerchantEligible($application){
        return (in_array($application->merchant_id, static::activatedMerchants())) ? $application->id : false;
    }

    public static function activatedMerchants(){
        $merchantWhitelist = MerchantWhitelistLender::where('lender_id','3')->whereNull('deleted_at')->get(['merchant_id']);
        $merchantWhitelisted =[];
        foreach($merchantWhitelist as $white){
            $merchantWhitelisted[] = $white->merchant_id;
        }
        // return env('APP_CONNECTION') == 0 ? [0,1] : [6657, 6485, 4696, 1338, 4646, 4882, 4829, 4774, 4687, 4693, 6034, 5162, 6543, 6440, 73, 6616, 6623, 6816,6451, 6873, 6944, 5668, 6859, 6661, 6686];
        return $merchantWhitelisted;
    }

    public function checkEligibility(){
        $application = ConsumerApplication::where('id', $this->request->get('id'))->whereIn('purpose', static::$educationCategories)->first(['id','merchant_id']);
        return isset($application->id) ? $this->isMerchantEligible($application) :  false;
    }

    public static function getLANNumber($id){
        $avanseFinance = AvanseCreateFinance::where('application_id', $id)->first(['finReference']);
        return isset($avanseFinance->finReference) ? $avanseFinance->finReference : null;
    }

    public static function getCIFNumber($id, $applicant_id){
        $avanseCustomer = AvanseCreateCustomer::where('application_id', $id)->where('applicant_id', $applicant_id)->first(['cif']);
        return isset($avanseCustomer->cif) ? $avanseCustomer->cif : null;
    }

    public function flatBalanceToReducingById($id){

        $application = ConsumerApplication::with('proFormaInvoice','emi','activeOffer','merchant')->where('id', $id)->first(['id','merchant_id','offer_id', 'approved_amount']);

        if(isset($application->activeOffer)){
            $interest_rate = $application->activeOffer->interest_rate;
            if($application->activeOffer->interest_type_id != 2){
                $avanseProcesses = new AvanseProcesses(new Request(['id' => $application->id]));
                $interest_rate = $avanseProcesses->flatBalanceToReducing($application->emi->remaining_emi, $application, ($application->approved_amount - $application->emi->upfront_from_customer));
            }
            return $interest_rate;
        }
        return 0;
    }

    public function flatBalanceToReducing($tenure, $application, $amount){

        $merchant_collected_advance_amount = $application->proFormaInvoice && $application->proFormaInvoice->merchant_collected_advance_amount ? $application->proFormaInvoice->merchant_collected_advance_amount : 0;

        $upfront_from_customer = $application->activeOffer->advance_type == 'emi' && $merchant_collected_advance_amount && $application->emi ? $application->emi->upfront_from_customer : 0;

        return round(Finance::rate($tenure, $application->emi->emi,(-$amount + $upfront_from_customer), 0)*12 * 100, 2);
    }

    public function getFoirByAvanse($id){

        $EMIPercentage = [
            'Auto Loan' => '2.20',
            'Commercial Vehicle Loan' => '2.40',
            'Consumer Durable' => '9.00',
            'Consumer Loan' => '9.00',
            'Credit Card' => '5.00',
            'Education Loan' => '1.80',
            'Gold Loan' => '1.50',
            'Home Loan' => '1.00',
            'Housing Loan' => '1.00',
            'Other' => '3.50',
            'Personal Loan' => '2.80',
            'Two-wheeler Loan' => '4.30',
            'Two Wheeler Loan' => '4.30'
        ];

        $accounts = [];

        $application = ConsumerApplication::with('emi','foir')->where('id', $id)->first(['id','name','monthly_income']);

        $totalEMI = 0;
        $creditFairEMI = $application->emi->emi;
        $income = $application->monthly_income;


        if ($application->foir) {
            foreach ($application->foir as $foir) {
                if ($foir->isOpened == 1) {
                    if ($foir->AccountType == 'Credit Fair EMI')
                        continue;

                    $percentage = isset($EMIPercentage[$foir->AccountType]) ? $EMIPercentage[$foir->AccountType] : 0;
                    $account = ['type' => $foir->AccountType, 'percentage' => $percentage, 'approved_amount' => trim($foir->ApprovedAmount), 'balance' => trim($foir->Balance), 'InstallmentAmount' => trim($foir->InstallmentAmount), 'emi_per_ratio' => 0, 'emi' => 0];

                    if ($percentage) {
                        $amount = $account['type'] == 'Credit Card' ? $account['balance'] : $account['approved_amount'];
                        $account['emi_per_ratio'] = ($amount * ($percentage / 100));
                        $minEMI = $account['InstallmentAmount'] == null ? $account['emi_per_ratio'] : $account['InstallmentAmount'];
                        $account['emi'] = round(min([$account['balance'], $minEMI]));
                    }

                    $totalEMI += $account['emi'];

                    $accounts[] = $account;
                }
            }
        }

        return round((($totalEMI + $creditFairEMI) / $income) * 100, 2);

    }

    public function getNetAmountAsPerAvanse($subventionWithGST = 0, $minusHoldAmount = 1){
        $application = ConsumerApplication::with('emi','proFormaInvoice','activeOffer')->where('id', $this->request->get('id'))->first(['id','approved_amount','merchant_id','offer_id']);
        $merchant_collected_advance_amount = $application->proFormaInvoice && $application->proFormaInvoice->merchant_collected_advance_amount ? $application->proFormaInvoice->merchant_collected_advance_amount : 0;
        $processing_fee = $application->proFormaInvoice && $application->proFormaInvoice->processing_fee_by_merchant && $application->emi && $application->emi->processing_fee ? $application->proFormaInvoice->processing_fee_by_merchant : 0;
        $advanceAmount = $application->activeOffer->advance_type != 'emi' && !$merchant_collected_advance_amount && $application->emi ? $application->emi->upfront_from_customer : 0;

        $caeObj = ConsumerApplicationElement::where('application_id', $this->request->get('id'))->first(['application_id','hold_amount']);

        if($application->activeOffer->advance_type == 'emi' && !$merchant_collected_advance_amount && $application->emi){
            $advanceAmount = $application->emi->upfront_from_customer;
        }

        $approved_amount = $application->approved_amount;
        if ($approved_amount && $advanceAmount){
            $approved_amount -= $advanceAmount;
        }

        if ($approved_amount && $processing_fee){
            // $approved_amount -= $application->emi->processing_fee;
        }

//        if(isset($caeObj->hold_amount) && $caeObj->hold_amount){
//            $approved_amount -= $caeObj->hold_amount;
//        }

        if($minusHoldAmount) {
            $liabilityLog = LiabilityLog::where('application_id', $this->request->get('id'))->first(['id', 'liability_percent']);
            if (isset($liabilityLog->liability_percent)) {
                //$approved_amount -= ((isset($liabilityLog->liability_percent) ? $liabilityLog->liability_percent : 0) * $approved_amount) / 100;
            }
        }

        if($subventionWithGST){
            $approved_amount -= $subventionWithGST;
        }
        return $approved_amount;
    }

    public function getAvanseSummary($id){

        $cibil = CibilBureau::where('application_id', $id)->first(['id']);
        return [
            'bureau' => isset($cibil->id) ? $cibil : false,
            'worthiness' => '',
            'mandate' => '',
            'finance' => '',
        ];
    }

    public function isAvanseEligible($statusData){
        if (!$this->checkEligibility() && isset($statusData['cf approved'])){
            unset($statusData['cf approved']);
            return array_values($statusData);
        }

        return $statusData;
    }

    public static function accessible($id, $statusreversearray){
        if (Auth::user()->lender_id == AvanseServices::$lender_id) {
            $application = ConsumerApplication::where('id', $id)->where('lender_id', AvanseServices::$lender_id);
            if ($statusreversearray) {
                $application->whereNotIn('state', $statusreversearray['waiting for decision']);
            }else{
                $application->whereIn('state', ['cf approved','approved']);
            }
            $application = $application->first(['id']);
            return isset($application->id) ? $application->id : false;
        }

        return $id;
    }

    public function getCibilReport($id){

        $applicant_type = $this->request->get('applicant_type') ? $this->request->get('applicant_type') : 1;

        $application = ConsumerApplication::find($id);
        $_name = $applicant_type == 1 ? $application->name : $application->co_applicant_name;
        $dob = $applicant_type == 1 ? $application->dob : $application->co_applicant_dob;
        $gender = $applicant_type == 1 ? $application->gender : $application->co_applicant_gender;
        $pan = $applicant_type == 1 ? $application->pan_card : $application->co_applicant_pan_card;
        $mobile = $applicant_type == 1 ? $application->mobile_number : $application->co_applicant_mobile_number;
        $address_line_1 = $applicant_type == 1 ? $application->current_address__line_1 : $application->co_applicant_address_line_1;
        $landmark = $applicant_type == 1 ? $application->current_address_landmark : $application->co_applicant_address_landmark;
        $city = $applicant_type == 1 ? $application->current_address_city : $application->co_applicant_address_city;
        $state = $applicant_type == 1 ? $application->current_address_state : $application->co_applicant_address_state;
        $pin = $applicant_type == 1 ? $application->current_address_pincode : $application->co_applicant_address_pincode;

        $name = explode(' ', $_name);

        $firstName = isset($name[0]) ? $name[0] : '';
        $middleName = isset($name[1]) && isset($name[2]) ? $name[1] : '';
        $lastName = !isset($name[2]) && isset($name[1]) ? $name[1] : (isset($name[1]) && isset($name[2]) ? $name[2].(isset($name[3]) ? $name[3] : '') : '');

        $this->request->merge([
            'id' => $id,
            'loan_amount' => $application->loan_amount,
            'name' => $firstName,
            'mName' => $middleName,
            'lName' => $lastName,
            'dob' => $dob,
            'gender' => $gender,
            'pan' => $pan,
            'mobile' => $mobile,
            'address_line_1' => $address_line_1,
            'landmark' => $landmark,
            'city' => $city,
            'state' => $state,
            'pincode' => $pin,
            'is_manually' => true
        ]);


        $bureau = new Bureau($this->request);

        $report = $bureau->getReport($this->request);

        if ($report->has('cibil_error') && !$report->get('cibil_error')){
            return response()->json(['status' => 'FAIL', 'message' => $report->get('message')]);
        }else{
            return response()->json(['status' => 'OK', 'message' => $report->get('message')]);
        }
    }

    public static function getPaymentLink($data) {
        $headers = [
            'Authorization: Basic '._env("AVANSE_PAYMENT_AUTH"),
            'Content-Type: application/json'
        ];
        $payload = [
            "id" => !empty($data['id']) ? $data['id'] : '', // for logging purpose only
            "laNumber" => !empty($data['laNumber']) ? $data['laNumber'] : '',
            "sourceId" => _env("AVANSE_SOURCEID",''),
            "loanType" => _env("AVANSE_LOAN_TYPE",''),
            "mode" => "Online",
            "requestPurpose" => "Payment",
            "paymentPurpose" => "FEES",
            "amount" => !empty($data['amount']) ? $data['amount'] : 0,
            "currency" => "INR",
            "paymentRequestDateTime" => Carbon::now()->toDateTimeString(),
            "receipents" => !empty($data['receipents']) ? $data['receipents'] : [],
            "feesList" => []
        ];
        if (!empty($data['purpose'])) {
            switch($data['purpose']) {
                case 'advance_amount':
                    $payload['feesList'][] = [
                        "feeCode" => "ADVEMI",
                        "feeAmount" => !empty($data['amount']) ? $data['amount'] : 0
                    ];
                    break;
                // case 'insurance_fee':
                //     $payload['feesList'][] = [
                //         "feeCode" => "PROCFEE",
                //         "feeAmount" => !empty($data['amount']) ? $data['amount'] : 0
                //     ];
                //     break;
                case 'processing_fee':
                    $payload['feesList'][] = [
                        "feeCode" => "PROCFEE",
                        "feeAmount" => !empty($data['amount']) ? $data['amount'] : 0
                    ];
                    break;
            }
        }
        //\Log::info($payload);
        $asObj = new AvanseServices(new Request($payload));
        unset($payload["id"]);
        //\Log::info(self::encrypt($payload));
        $ret = $asObj->getPaymentLink($headers, ['encryptedData' => self::encrypt($payload)]);
        //\Log::info($ret);
        if (!empty($ret['encryptedData'])) {
            // success
            /*
                Sample response Original
                {
                    "encryptedData": "ple6R4PXoNPHnGE48DyPWdF4T/YKna3pXP+G12UfC6Z5+p5dtGr0li2ApnZ3VfTR51jd2v0v6UcuVos6RJu34njudHKgMOIDB693gk0pLoyqGN2fsMzeWbR4nMOOjfZc"
                }
                Sample response after decryption
                {"shortURL":"https://uatpaymnt.avanse.com/ShortLinkApp/OEaxmz","paymentRequestId":25632}
            */
            $ret1 = self::decrypt($ret['encryptedData']);
            if (!empty($ret1)) {
                $output = json_decode($ret1, 1);
                if (!empty($output['shortURL']) && !empty($output['paymentRequestId'])) {
                    $payment = new OnlinePayment();
                    $payment->application_id = $data['id'];
                    $payment->payment_id = $output['paymentRequestId'];
                    $payment->payment_link = $output['shortURL'];
                    $payment->purpose = $data['purpose'];
                    $payment->emi_date = $payload['paymentRequestDateTime'];
                    $payment->amount = !empty($data['amount']) ? $data['amount'] : 0;
                    $payment->status = 'Pending';

                    $payment->save();
                    return $output['shortURL'];
                }
            }
            return '';
        } else {
            // failed
            return '';
        }
    }

    public static function getPaymentStatus($data) {
        $headers = [
            'Authorization: Basic '._env("AVANSE_PAYMENT_AUTH"),
            'Content-Type: application/json'
        ];
        $payload = [
            "id" => !empty($data['id']) ? $data['id'] : '', // for logging purpose only
            "paymentRequestId" => !empty($data['paymentRequestId']) ? $data['paymentRequestId'] : '',
        ];
        //\Log::info($payload);
        $asObj = new AvanseServices(new Request($payload));
        unset($payload["id"]);
        $ret = $asObj->getPaymentStatus($headers, ['encryptedData' => self::encrypt($payload)]);
        //\Log::info($ret);
        if (!empty($ret['encryptedData'])) {
            // success
            /*
                Sample response Original
                {
                    "encryptedData": "NNPCX7fnfQQqk4t+3im4jcLVTex5KOk41Xx+ElcWA4O5Ra0UagEIATaNRNiixe+qaoa1qnsdgY854QgXtxy1Bs+cPerSog3cpmF1E2JhIxeXP4i3h69rEy3J/qgFBz5ww13KYgWOl9OzMuFXuB4/qeAHfXFf21bRVrLHG3X4oy6JzbzQdzNK5J0UeOkmXD398HIE0rSrDKQzHAVjmUqwY+Zs+7S85yFzpEVt5UAd2pGm2PE+LJk/zK1LY81tGOPWKwlIsu3mBHs3LXcmrndFd/1psqtp/3t2nsGCn2YDlbyEn/pe1yBQmRrLm/MnWFkttSUZtV5zYXFnmCm8t7XSA9mX4zIfhmutGEIVuHChFF4ywN3C3Dde//jS7XSNiWZIYimh03rygIPISJpEbnl2nt/Z+EOfl0r92K6+s3zZ+sLEIBNNwJkGaXrN/g8KGuz+"
                }
                Sample response after decryption
                [{"currency":"INR","mode":"Online","fundingAccount":"14","requestDate":"2020-04-23","requestPurpose":"Payment","sourceApplicationName":"PaymentModule","paymentRequestID":"123","paymentPurpose":"Overdue","loanNumber":"DELSB00010104","loanType":"BLSME","merchantID":"FLx45AaqNXax8D","requestStatus":"NEW_REQUEST","amount":160542.0}]
            */
            $ret1 = self::decrypt($ret['encryptedData']);
            //\Log::info($ret1);
            return $ret1;
        } else {
            // failed
            return '';
        }
    }

    public static function encrypt($data) {
        //\Log::info(json_encode($data));
        return openssl_encrypt(json_encode($data), _env("AVANSE_ENCRYPTION_CODE"), _env("AVANSE_ENCRYPTION_KEY"), $options=0, _env("AVANSE_ENCRYPTION_IV"));
    }

    public static function decrypt($data) {
        return openssl_decrypt($data, _env("AVANSE_ENCRYPTION_CODE"), _env("AVANSE_ENCRYPTION_KEY"), $options=0, _env("AVANSE_ENCRYPTION_IV"));
    }

    public function getAvanseDocumentMapping(){

        if(!$this->request->has('file_type')) {
            $files = ConsumerApplicationFiles::where('consumer_application_id', $this->request->get('id'))->get(['id', 'file_type']);

            $filesExist = [];
            foreach ($files as $file) {
                $filesExist[] = $file->file_type;
                $filesExistIds[$file->file_type][] = $file->id;
            }
        }else{
            $filesExist[] = $this->request->get('file_type');
            $filesExistIds[$this->request->get('file_type')][] = $this->request->get('file_id');
        }

        $variables = [
            '{id}' => $this->request->get('id'),
            '{applicant_type}' => $this->request->get('applicant_type') ?? 1
        ];

        $mappedDocumentExists = [];
        $mappedDocumentAvExists = [];

        foreach ($this->documentMapped as $mainKey => $mappedArray) {
            foreach ($mappedArray as $mapped) {
                foreach ($variables as $variable => $value) {
                    $mapped = str_replace($variable, $value, $mapped);
                }
                if (in_array($mapped, $filesExist)) {
                    $mappedDocumentExists[$mapped] = $mainKey;
                    if (isset($filesExistIds) && isset($filesExistIds[$mapped])) {
                        $avansePushed = AvanseCreateDocument::where('application_id', $this->request->get('id'))->whereIn('consumer_application_file_id', $filesExistIds[$mapped])->first();
                        if (isset($avansePushed->id)) {
                            $mappedDocumentAvExists[$mapped] = $mainKey;
                        }
                    }
                }
            }
        }

        return [$mappedDocumentExists, $mappedDocumentAvExists];
    }

    public function sendUploadedDocument(){
        $documents = DB::connection('avanse')->table('BMTDocumentTypes')->where('DocTypeCode', $this->request->get('file_name'))->first(['DocTypeCode']);
        //(new Slack(new Request(['title' => 'Avanse document test - 2', 'fields' => ['doc_code' => $documents->DocTypeCode], 'group' => Slack::$STAGE_TESTING])))->send();
        if (isset($documents->DocTypeCode)) {
            $avanseProcesses = new AvanseProcesses(new Request([
                'file_type' => $this->request->get('file_name'),
                'id' => $this->request->get('id'),
                'applicant_type' => 1,
                'consumer_application_file_id' => $this->request->get('file_id')
            ]));

            return $avanseProcesses->addDocuments();
        }
        return false;
    }

    public function getMappedKey($keyName){
        foreach ($this->documentMapped as $key => $values){
            if(in_array($keyName, $values)){
                return $key;
            }
        }
        return false;
    }
}
