<?php

namespace App\Method\Vivriti\Payload;

use App\ApplicationEMICalculation;
use App\ApplicationEMIDetails;
use App\Avanse\Processes\AvanseProcesses;
use App\ConsumerApplication;
use App\ConsumerApplicationFiles;
use App\CreditReport;
use App\EMICalculation;
use App\FinBit;
use App\FinBitData;
use App\FOIR;
use App\Http\Controllers\Admin\AccountingController;
use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\Http\Controllers\Admin\ConsumerDocument;
use App\JWTAccess;
use App\LoanManagement;
use App\MerchantOffers;
use App\Method\Vivriti\Helpers\VivritiHelper;
use App\PaymentTransaction;
use App\PWAApplicationForm;
use App\Slack;
use Carbon\Carbon;
use Hashids\Hashids;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Symfony\Component\HttpFoundation\StreamedResponse;

class Payload implements VivritiHelper
{

    public $request;
    public $error = null;
    public $temp_files = [];
    public $additional_data = [];

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

    public function getPayload($func){
        if(method_exists($this, $func)){
            return ['payload' => $this->$func(), 'additional_data' => $this->additional_data];
        }
        return ['payload' => []];
    }

    public function createLoan($wrapper = null)
    {

        $application = ConsumerApplication::with('company','merchant','proFormaInvoice', 'emi', 'creditReport', 'merchant_bank_details', 'application_element')->where('id', $this->request->get('id'))->first(['id', 'approved_amount','merchant_id' ,'offer_id', 'name', 'dob', 'mobile_number', 'permanent_address_line_1', 'permanent_address_city', 'permanent_address_state', 'permanent_address_pincode',  'current_address_line_1', 'current_address_city', 'current_address_state', 'current_address_pincode', 'monthly_income', 'pan_card', 'co_applicant_pan_card', 'co_applicant_name', 'co_applicant_mobile_number', 'co_applicant_email', 'co_applicant_address_city', 'co_applicant_address_pincode', 'co_applicant_address_state', 'co_applicant_address_line_1', 'co_applicant_monthly_income', 'gender', 'applicant_id', 'co_applicant_aadhaar_card', 'co_applicant_dob', 'co_applicant_relationship', 'email', 'aadhaar_card', 'company_name', 'employee_status', 'marital_status','work_address_line_1', 'work_address_state', 'work_address_city', 'work_address_pincode', 'work_address_landmark']);
        $merchant = MerchantOffers::where('id', $application->emi->offer_id)->first(['advance_type']);
        $finbit = FinBitData::where('application_id', $application->id)->first(['id', 'average_balance']);

        if (empty($application->emi->tenure)){
            $error = new \stdClass();
            $error->description = 'tenure is required';
            $this->error = $error;
            return $this;
        }

        if (!isset($application->merchant_bank_details)){
            $error = new \stdClass();
            $error->description = 'Merchant bank details required';
            $this->error = $error;
            return $this;
        }

        if (!isset($application->creditReport[0]->Score)){
            $error = new \stdClass();
            $error->description = 'Generate the Bureau';
            $this->error = $error;
            return $this;
        }

        // if (!isset($finbit->average_balance)){
        //     $error = new \stdClass();
        //     $error->description = 'Finbit report is required';
        //     $this->error = $error;
        //     return $this;
        // }

        $name = explode(' ', $application->name);
        $gender = '';
        if(strtolower($application->gender) == 'male'){
            $gender = "M";
        }else if(strtolower($application->gender) == 'female'){
            $gender = "F";
        }

        $applicationController = new ConsumerApplicationController();
        $merchantBank = $applicationController->getBankAccountDetails($application);


        $net_loan_amount = $application->approved_amount;

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

        if (!$merchant_collected_advance_amount){
            $net_loan_amount -= $application->emi->upfront_from_customer;
            if ($merchant->advance_type == 'emi'){
                $net_tenure = $application->emi->tenure - $application->emi->advance_emi;
            }
        }

        $subvention = (new ConsumerApplicationController())->getSubventionDetails($application, false);
        $net_loan_amount -= $subvention['WithGST'];

        $total_existing_obligations = FOIR::where('application_id', $application->id)->where('AccountType', '!=', 'Credit Fair EMI')->where('isOpened', 1)->sum('InstallmentAmount');

        $referenceName = explode(' ', $application->application_element->reference_name_1, 2);
        $referenceName = $referenceName[0] ?? '';
        $referenceLame = $referenceName[1] ?? '';

        $aadhaar_card = str_replace(" ", "", $application->aadhaar_card);
        //$aadhaar_card = substr_replace($aadhaar_card, 'XXXX', -1, 4);

        $current_address_status = 'owned';
        if(strtolower($application->current_address_status) == 'rented'){
            $current_address_status = 'rented';
        }

        $permanent_address_status = 'owned';
        if(strtolower($application->permanent_address_status) == 'rented'){
            $permanent_address_status = 'rented';
        }

        $customer_category = 'others';
        if (strtolower($application->employee_status) == 'salaried'){
            $customer_category = 'salaried';
        }else if (strtolower($application->employee_status) == 'self employed - business'){
            $customer_category = 'self_employed';
        }else if (strtolower($application->employee_status) == 'self employed - professional'){
            $customer_category = 'self_employed_professional';
        }else if (strtolower($application->employee_status) == 'business'){
            $customer_category = 'self_employed';
        }


        $merchant_processing_collected =  (isset($application->proFormaInvoice) && $application->proFormaInvoice->processing_fee_by_merchant == 1 ? $application->proFormaInvoice->processing_fee_by_merchant : (isset($application->merchant->is_collected) && $application->merchant->is_collected == 1 ? $application->merchant->is_collected : 0));


        $emiSchedule = (new ConsumerDocument(new Request()))->generateEMI($application);

        $amountAB = 0;
        if (isset($application->proFormaInvoice->insurance_premium_applicable) && $application->proFormaInvoice->insurance_premium_applicable == 1) {
            //$amountAB += $application->proFormaInvoice->insurance_premium_amount;
        }

        $amountAmtV = $emiSchedule->processing_fee + $emiSchedule->upfront_from_customer + $amountAB;

        if($merchant_processing_collected){
            //$amountAmtV -= $emiSchedule->processing_fee;
            //$net_loan_amount -= $emiSchedule->processing_fee;
        }


        $is_gst_applicable = isset($application->merchant->is_gst) ? $application->merchant->is_gst : 0;
        if ($is_gst_applicable == 0) {
            $amountAmtV += $subvention;
        }

        $amtV = ($application->approved_amount - $amountAmtV);

        $aprrate = round(\MathPHP\Finance::rate($emiSchedule->remaining_emi, $emiSchedule->emi, -$amtV, 0) * 100 * 12, 2);
        if ($aprrate < 0) {
            $aprrate = 0;
        }
        // below condition is for NAN return by finance function
        if(is_nan($aprrate)){
            $aprrate = 0;
        }

        //$aprrate = 16;

        $process = (new AvanseProcesses($this->request));
        $eligibilityChecks = $this->eligibityMethodCheck($application->id);

        $data = [
            "annual_business_turnover"  => 0,
            "number_of_repayments"  => $application->emi->tenure,
            "language_pref"  => "english",
            "foir" => $eligibilityChecks['eligibilityMethod'] == 'income' ? ($application->creditReport[0]->applicant_type == 1 ? round($application->creditReport[0]->foirIncludingCFEMI) : ($application->creditReport[1]->applicant_type == 1 ? (round($application->creditReport[1]->foirIncludingCFEMI)) : '')) : 50,
            "pan_number_link"  => $this->getDocumentLink('pan_card'),
            "aadhar_number_link"  => $this->getDocumentLink(['aadhar_card_back', 'aadhar_card']),
            "apr"  => $aprrate,
            "identity_type"  => "",
            "aadhar_number"  => $aadhaar_card,
            "customer_type"  => "individual",
            "customer_category"  => $customer_category,
            "client_customer_id"  => $application->applicant_id,
            "client_loan_id"  => $application->proFormaInvoice->loan_application_no,
            "application_id"  => $application->id,
            "first_name"  => $name[0],
            "last_name"  => end($name),
            "gender"  => $gender,
            "date_of_birth"  => $application->dob,
            "name_of_bureau"  => $application->creditReport[0]->applicant_type == 1 && $application->creditReport[0]->bureau ? ($application->creditReport[0]->bureau) : ($application->creditReport[1]->applicant_type == 1 && $application->creditReport[1]->bureau ? ($application->creditReport[1]->bureau) : ''),
            "bureau_score"  => $application->creditReport[0]->applicant_type == 1 && $application->creditReport[0]->Score ? ($application->creditReport[0]->Score) : ($application->creditReport[1]->applicant_type == 1 && $application->creditReport[1]->Score ? ($application->creditReport[1]->Score) : ''),
            "bureau_report_link"  => $this->getDocumentLink(['credit_report', 'equifax_report']),
            "commercial_bureau_score"  => 0,
            "commercial_bureau_score_link"  => $this->getDocumentLink('commercial_bureau_score_link'),
            "current_address"  => $application->current_address_line_1.' '. $application->current_address_city.' '.$application->current_address_state.', '.$application->current_address_pincode,
            "income_assessment_method" => strtolower($application->employee_status) == 'salaried'? 'Salary Slip' : 'Bank Statement',
            "current_village"  => "",
            "current_city_tier"  => "",
            "current_city"  => $application->current_address_city,
            "current_district"  => $application->current_address_city,
            "current_state"  => $this->getState($application->current_address_state),
            "current_country"  => "India",
            "current_pincode"  => $application->current_address_pincode,
            "resi_status"  => "RESIDENT",
            "residence_type_current_address"  => $current_address_status,
            "years_of_stay_in_current_address"  => 0,
            "permanent_address"  => $application->permanent_address_line_1.' '. $application->permanent_address_city.' '.$application->permanent_address_state.', '.$application->permanent_address_pincode,
            "permanent_city"  => $application->current_address_city,
            "permanent_state"  => $this->getState($application->current_address_state),
            "permanent_country"  => "India",
            "employment_pincode"  => $application->work_address_pincode ?? '',
            "bounces_in_last_6m"  => 0,
            "permanent_pincode"  => $application->current_address_pincode,
            "residence_type_permanent_address"  => $permanent_address_status,
            "mobile_number"  => $application->mobile_number,
            "email"  => $application->email,
            "bank_statement_link"  => $this->getDocumentLink(['bank_statement','bank_statement_1', 'bank_statement_2', 'bank_statement_3', 'bank_statement_4', 'bank_statement_5', 'bank_statement_6']),
            "employment_vintage_current_organisation"  => '',
            "net_monthly_income"  => $application->monthly_income,
            "partner_score_on_the_customer"  => '',
            "pan_number"  => $application->pan_card,
            "marital_status"  => strtolower($application->marital_status),
            "voter_id_number"  => "",
            "voting_id_link"  => $this->getDocumentLink('voting_id_link'),
            "driving_license_number"  => "",
            "driving_license_number_link"  => $this->getDocumentLink('driving_license'),
            "video_image_link"  => $this->getDocumentLink(['vkyc_video_'.$application->id.'_1']),
            "video_kyc_detail"  => [
                "auditor"  => "",
                "profile_id"  => "",
                "officer"  => ""
            ],
            'valuer_report' =>  $this->getDocumentLink('valuer_report'),
            'proforma_invoice_quotation_link' => $this->getDocumentLink('solar_quotation'),
            'gst_return_link_year_1' => $this->getDocumentLink('gst_return_year_one'),
            'gst_return_link_year_2' => $this->getDocumentLink('gst_return_year_two'),
            'gst_return_link_year_3' => $this->getDocumentLink('gst_return_year_three'),
            'virtual_account' => '',
            'business_place_photo_link' => $this->getDocumentLink(['house_verification_photo', 'business_verification_photo']),
            "number_of_enquiries_3months"  => $application->creditReport[0]->TotalEnquiry ?? 0,
            "utility_bills_link"  => $this->getDocumentLink('utility_bills_link'),
            "bank_statement"  => [
                "bank_statement_savings_account_12_months_link"  => $eligibilityChecks['eligibilityMethod'] == 'income' ? 'NA' : '',//$this->getDocumentLink('bank_statement_savings_account_12_months_link') : '',
                "credit_summation"  => 0,
                "abb"  => $eligibilityChecks['eligibilityMethod'] == 'income' ? $finbit->average_balance ?? 0 : 0
            ],
            "total_existing_obligations"  => $total_existing_obligations,
            "employment_type"  => $customer_category,
            "employment_details_name"  => $application->company->company ?? $application->company_name,
            "total_work_experience"  => $application->experience,
            "payslip_link"  => $this->getDocumentLink(['payslip_link', 'salary_slip']),
            "kyc_xml_link"  => $this->getDocumentLink('kyc_xml_link'),
            "financial_data"  => [
                "gst_return_year_3_link"  => $this->getDocumentLink('gst_return_year_3_link'),
                "gst_return_year_2_link"  => $this->getDocumentLink('gst_return_year_2_link'),
                "it_return_year_2_link"  => $this->getDocumentLink('it_return_year_2_link'),
                "it_return_year_3_link"  => $this->getDocumentLink('it_return_year_3_link'),
                "gst_return_year_1_link"  => $this->getDocumentLink('gst_return_year_1_link'),
                "annual_business_turnover"  => 0,
                "gst_annual_turnover"  => 0,
                "it_return_year_1_link"  => $this->getDocumentLink('it_return_year_1_link'),
                "other_income_assesment_proof_link"  => $this->getDocumentLink('other_income_assesment_proof_link'),
                "cam_link"  => $this->getDocumentLink(['cam', 'credit_appraisal_memo'])
            ],
            "abb_emi_ratio"  => isset($finbit->average_balance) ? ($finbit->average_balance / $application->emi->emi) : 0,
            "emi_obligations"  => $application->emi->emi ?? 0,
            "category"  => "unsecured",
            "sub_category"  => "fresh",
            "purpose"  => "Personal Loan",
            "disbursement_type"  => "single",
            "number_of_tranches"  => 1,
            "end_borrower_amount"  => 0,
            "principal_amount"  => !$merchant_collected_advance_amount ? $application->approved_amount - $application->emi->upfront_from_customer : $application->approved_amount,
            "interest_rate"  =>  $process->flatBalanceToReducingById($application->id),
            "interest_type"  => "reducing",
            "tenure"  => $application->emi->tenure,
            "advance_emi"  => $merchant_collected_advance_amount ? $application->emi->advance_emi : 0,
            "processing_fee"  => $merchant_processing_collected ? $application->emi->processing_fee : 0,
            "references"  => [
                [
                    "phone"  => $application->application_element->reference_contact_1,
                    "name"  => $application->application_element->reference_name_1,
                    "first_name"  => $referenceName,
                    "last_name"  => $referenceLame
                ]
            ],
            "no_of_co_applicants"  => $application->co_applicant_name ? 1 : 0,
            "no_of_guarantors"  => 0,
            "tenure_frequency"  => "monthly",
            "repayment_frequency"  => "monthly",
            "other_documents_link" => $eligibilityChecks['eligibilityMethod'] == 'income' ? 'NA' : '',//$this->getDocumentLink(['personal_discussion', 'personal discussion call', 'personal discussion', 'personal_discussion_applicant']) : '',
            "other_kyc_link" => $eligibilityChecks['eligibilityMethod'] == 'income' ? 'NA' : '',//$this->getDocumentLink('salary_slip') : '',
        ];

        if(isset($data['business']['partnership_detail'])){
            $data['business']['partnership_detail']  = [
                "partnership_firm_pan"  =>"",
                "beneficiary_owner_details_link"  => $this->getDocumentLink('beneficiary_owner_details_link'),
                "partnership_pan_link"  => $this->getDocumentLink('partnership_pan_link')
            ];
        }

        if(isset($data['business'])){
            $data['business'] = [
                "name_of_business"  => "Credavenue",
                "industry_type"  => "trading",
                "sector_type"  => "Financial services",
                "business_registered_office_address"  => "221B, Baker Street, Chennai",
                "business_registered_office_state"  => "tamil_nadu",
                "business_registered_office_pincode"  => 342228,
                "private_entity_detail"  => [
                    "cin_link"  => $this->getDocumentLink('cin_link'),
                    "board_resoultion_link"  => $this->getDocumentLink('board_resoultion_link'),
                    "aoa_link"  => $this->getDocumentLink('aoa_link'),
                    "moa_link"  => $this->getDocumentLink('moa_link'),
                    "cin_number"  =>"L21091KA2019OPC141331",
                    "share_holding_pattern_link"  => $this->getDocumentLink('share_holding_pattern_link')
                ],
                "type_of_constitution"  => "", //partnership
                "business_udyog_aadhar_link"  => $this->getDocumentLink('business_udyog_aadhar_link'),
                "business_udhyam_link"  => $this->getDocumentLink('business_udhyam_link'),
                "nature_of_business"  => "wholesaler",
                "business_phone_number"  => [

                ],
                "business_type"  => "", //owned
                "business_gst_number"  => "",
                "business_email_id"  => [
                    "",
                    ""
                ],
                "business_electricity_bill_link"  => $this->getDocumentLink('business_electricity_bill_link'),
                "business_vintage"  => 4,
                "business_udyog_aadhar_number"  => "794065346725",
                "business_pan_number"  => "BMMPG9018G"
            ];
        }

        if (isset($data['deviation_details'])){
            $data['deviation_details'] =
                [
                    "mitigant"  => "mitigant_50",
                    "summary"  => "summary_31",
                    "desc"  => "desc_56"
                ];
        }

        if (!isset($data['disbursement_accounts'])){
            $data["disbursement_accounts"]  = $this->get_disbursement_details($net_loan_amount, $merchantBank);
        }

        if (!isset($data['repayment_information'])){
            $data["repayment_information"]  = $this->get_repayment_details($application);
        }

        $transaction = PaymentTransaction::where('application_id', $this->request->get('id'))->where('payment_for', 'insurance_fee')->first(['id','payment_date', 'trasanction_id']);
        if (isset($transaction->id)){
            $data["insurance_details"]  = $this->get_insurance_details($transaction);
        }

        if (isset($data['tranches'])){
            $data["tranches"]  = $this->get_tranch_details();
        }

        if (!isset($data['is_loan_detail'])){
            $data["loan_detail"]  = $this->get_loan_details($application, $eligibilityChecks);
        }

        if (isset($application->co_applicant_name) && $application->co_applicant_name) {
            $data['co_applicants'] = $this->get_co_applicant($application);
        }

        if (isset($data['is_guarantor'])){ // is_guarantor is not exists, pass true if you have
            $data['guarantors']  =
                [
                    "language_pref"  => "",
                    "bank_statement_link"  => $this->getDocumentLink('bank_statement_link'),
                    "date_of_birth"  => "1995-12-05",
                    "relationship_with_applicant"  => "",
                    "relationship_proof"  => "",
                    "first_name"  => "",
                    "gender"  => "M",
                    "current_address"  => "",
                    "current_district"  => "",
                    "current_city"  => "",
                    "current_state"  => "",
                    "current_pincode"  => '',
                    "permanent_address"  => "",
                    "permanent_city"  => "",
                    "permanent_state"  => "",
                    "permanent_pincode"  => '',
                    "mobile_number"  => '',
                    "email"  => "",
                    "pan_number"  => "",
                    "pan_number_link"  => $this->getDocumentLink('pan_card'),
                    "aadhar_number"  => "",
                    "aadhar_number_link"  => $this->getDocumentLink('aadhar_number_link'),
                    "photo_link"  => $this->getDocumentLink('photo_link'),
                    "bureau_score"  => 0,
                    "bureau_report_link"  => $this->getDocumentLink('bureau_report_link')
                ];
        }

        $this->additional_data['temp_files'] = $this->temp_files;
        $this->request->merge(['additional_data' => $this->additional_data]);
        return $data;
    }

    private function get_disbursement_details($net_loan_amount, $merchantBank){

        return [
            [
                "ifsc_code"  => $merchantBank['beneficiaryIFSC'],
                "bank_branch_name"  => $merchantBank['beneficiaryBranchName'],
                "amount"  => $net_loan_amount,
                "account_name"  => $merchantBank['beneficiaryName'],
                "account_no"  => $merchantBank['beneficiaryAccount'],
                "bank_name"  => $merchantBank['beneficiaryBankName']
            ]
        ];
    }

    private function get_repayment_details($application){
        return [
            [
                "repayment_bank_account_name"  => $application->bank_details->name ?? '',
                "repayment_bank_ifsc"  => $application->bank_details->ifsc_code ?? '',
                "repayment_bank_account_number"  => $application->bank_details->account_number ?? '',
                "repayment_bank_name"  => $application->bank_details->bank_name ?? '',
                "repayment_account_type"  => ucfirst($application->bank_details->account_type ?? '')
            ]
        ];
    }

    private function get_insurance_details($transaction){

        return [
            [
                "insurance_form_link"  => $this->getDocumentLink('insurance_form_link'),
                "insurance_type"  => "credit",
                "insurance_amount"  => $transaction->amount,
                "insurer_name"  => "",
                "premium"  => $transaction->amount,
                "nominee_details"  => "",
                "policy_number"  => ""
            ]
        ];
    }

    private function get_tranch_details(){
        return [
            [
                "processing_fee"  => 0,
                "principal_amount"  => 0,
                "tranche_number"  => 1
            ]
        ];
    }

    private function get_loan_details($application, $eligibilityChecks){

        try{
            $eligibilityMethod = "";
            $applicationController = new ConsumerApplicationController();
            $merchantBank = $applicationController->getBankAccountDetails($application);

            $consumer_application = ConsumerApplication::with('telecom_data')->where('id', $application->id)->first(['co_applicant_name','mobile_number','created_at','user_id','id']);
            if(!isset($consumer_application->id)){
                \Session::flash('error','Application does not exist');
                return redirect()->to('/admin/consumer-applications');
            }
            $request = new Request();
            $request->attributes->add(['application_id' => $application->id]);
            $response = $applicationController->getScoreCard($request);
            $i = 0;
            $consumer_application = ConsumerApplication::with('telecom_data')->where('id', $application->id)->first(['co_applicant_name','mobile_number','created_at','user_id']);

            $appMaxSixMonthDPDs = 0;
            $appMaxTwelveMonthDPDs = 0;
            $appMaxThreeMonthDPDs = 0;
            $appTotalAccountsInStatus = 0;
            $appTotalActiveRestructuredLoans = 0;

            // In case if co-app details are needed for future
            $CoappMaxSixMonthDPDs = 0;
            $CoappMaxTwelveMonthDPDs = 0;
            $CoappMaxThreeMonthDPDs = 0;
            $CoappTotalAccountsInStatus = 0;
            $CoappTotalActiveRestructuredLoans = 0;

            $response['auto_creditscore'] = CreditReport::where('application_id',$application->id)->where('applicant_type',2)->orderBy('created_at','desc')->first(['Score']);
            $response['auto_co_applicant_name'] = $consumer_application->co_applicant_name;
            $response['bureau'] = CreditReport::where('application_id',$application->id)->where('applicant_type', 1)->orderBy('created_at','desc')->first(['bureau']);

            if (isset($response['bureau']->bureau)) {
                $latestdpd = $applicationController->getDPD($application->id);
                $appMaxSixMonthDPDs = $latestdpd['six_mon_max_30_plus'] ?? 0;//$latestdpd['six_mon_max'];
                $appMaxTwelveMonthDPDs = $latestdpd['twelve_mon_max_90_plus'] ?? 0;//$latestdpd['twelve_mon_max'];
                $appMaxThreeMonthDPDs = $latestdpd['three_mon_max_0_plus'] ?? 0;//$latestdpd['three_mon_max'];
                $appTotalAccountsInStatus = $latestdpd['total_accounts_in_status'] ?? 0;
                $appTotalActiveRestructuredLoans = $latestdpd['totalActiveRestructuredLoans'] ?? 0;
            }

            /*// In case if co-app details are needed for future

            $i = 0;
            if (isset($response['bureauInputCoApplicant'][0])) {
                $latestdpd = $applicationController->getDPD($application->id, 2);
                foreach ($response['bureauInputCoApplicant'] as $bureauInputCo) {

                    $CoappMaxSixMonthDPDs = $latestdpd['six_mon_max_30_plus'];//$latestdpd['six_mon_max'];
                    $CoappMaxTwelveMonthDPDs = $latestdpd['twelve_mon_max_90_plus'];//$latestdpd['twelve_mon_max'];
                    $CoappMaxThreeMonthDPDs = $latestdpd['three_mon_max_0_plus'];//$latestdpd['three_mon_max'];
                    $CoappTotalAccountsInStatus = $latestdpd['total_accounts_in_status'];
                    $CoappTotalActiveRestructuredLoans = $latestdpd['totalActiveRestructuredLoans'];

                    $i++;
                }
            }*/


            $merchant_collected_advance_amount = $application->proFormaInvoice && $application->proFormaInvoice->merchant_collected_advance_amount ? $application->proFormaInvoice->merchant_collected_advance_amount : 0;
            $transaction = PaymentTransaction::where('application_id', $application->id)->where('payment_for', 'processing_fee')->first(['id','payment_date', 'trasanction_id', 'mode']);

            $merchant_processing_collected =  (isset($application->proFormaInvoice) && $application->proFormaInvoice->processing_fee_by_merchant == 1 ? $application->proFormaInvoice->processing_fee_by_merchant : (isset($application->merchant->is_collected) && $application->merchant->is_collected == 1 ? $application->merchant->is_collected : 0));


            $plus_30 = 0;
            $plus_60 = 0;
            $plus_90 = 0;
            $pastOverDue = 0;
            $foirData = FOIR::where('application_id', $application->id)->where('applicant_type', 1)->where('isOpened', 1)->get(['dpd']);
            foreach ($foirData as $item){
                if (isset($item->dpd)){
                    $dpd = json_decode($item->dpd, 1);
                    foreach($dpd as $key => $dpdItem){
                        if ($key == "30+"){
                            $plus_30 = $dpdItem;
                        }else if ($key == "60+"){
                            $plus_60 = $dpdItem;
                        }else if ($key == "90+"){
                            $plus_90 = $dpdItem;
                        }
                    }

                    if ($item->PastDueAmount) {
                        $pastOverDue += $item->PastDueAmount;
                    }

                }
            }
        }catch(\Exception $e){
            (new Slack(new Request(['title'=>'Payload Error for Vivriti Create Loan','fields'=>['application_id'=>$application->id, 'error'=>$e->getMessage(),'line'=>$e->getLine(),'trace'=>$e->getTraceAsString()], 'group' => \App\Slack::$STAGE_TESTING])))->send();
            return [];
        }

        return [
            "Max_DPD_days_in_last_3M" => $appMaxThreeMonthDPDs,
            "Max_DPD_days_in_last_6M" => $appMaxSixMonthDPDs,
            "Max_DPD_days_in_last_12M" => $appMaxTwelveMonthDPDs,
            "Number_of_loans_in_Sub_or_DBT_or_Loss_or_Settled_or_Writeoffs_or_Suitfiled_or_wilful_default_in_last_36M" => $appTotalAccountsInStatus,
            "Number_of_Active_Restructured_loans_excluding_Covid_Restructuring" => $appTotalActiveRestructuredLoans,
            "Name_of_Merchant"  => $application->merchant->merchant_name,
            "Date_of_PF_receipt"  => isset($transaction->payment_date) ? date('Y-m-d', strtotime($transaction->payment_date)) : '',
            "Name_of_Inverter"  => $application->application_element->inverter,
            "Panel_Brand"  => $application->application_element->panel,
            "Monthly_Power_Bill"  => $application->application_element->inverter_monthly_power_bill,
            "Subsidy_Amount"  => $application->application_element->inverter_subsidy_amount,
            "Power_Savings_Estimated"  => $application->application_element->inverter_power_savings,
            "Own_Contribution_by_Customer"  => !$merchant_collected_advance_amount ? $application->emi->upfront_from_customer : 0,
            "Solar_LTV"  => (($application->approved_amount - $application->emi->upfront_from_customer) / $application->approved_amount) * 100,
            "Address_where_solar_panel_installed"  => $application->current_address_line_1.' '. $application->current_address_city.' '.$application->current_address_state.', '.$application->current_address_pincode,
            "UTR_Number_of_PF"  => $transaction->trasanction_id ?? '',
            'upfront_processing_fee' => !$merchant_processing_collected ? $application->emi->processing_fee : 0,
            "Place_of_Installation_Owned_Rented"  => "Owned",
            "Place_of_instalment_owned_by"  => isset($application->co_applicant_name) && $application->co_applicant_name ? "Co-applicant" : "Applicant",
            "Lease_Period_Years_of_Lease_Period"  => 0,
            "Business_Lease_Period"  => 0,
            "Solar_Savings"  => 0,
            "EBIDTA"  => $application->monthly_income ?? 0,
            "GST_Turnover"  => 0,
            "GST_Multiplier"  => 0,
            "EMI_bounces_in_last_6M"  => 0,
            "Percentage_of_Inward_Bounces_in_Last_12M"  => 0,
            "Proposed_EMI"  => $application->emi->emi,
            "Number_of_30_plus_DPD_in_Last_1M"  => 0,
            "Number_of_60_plus_DPD_in_last_2M"  => 0,
            "Number_of_90_plus_DPD_in_last_4M"  => 0,
            "Number_of_30_plus_DPD_in_last_6M"  => 0,
            "Overdue_Amount_as_on_date"  => $pastOverDue,
            "Overdue_amount_for_CC_KCC_Guarantor_Loans"  => 0,
            "EMI_To_Energy_Saving"  => 0,
            "Number_of_30_plus_DPD_in_Last_12M"  => 0,
            "Number_of_90_plus_DPD_ever"  => 0,
            "Model_Description"  => $application->application_element->inverter_model_description,
            "KW_Installation"  => $application->application_element->inverter_KW_installation,
            "Gross_Project_Amount"  => $application->application_element->inverter_gross_project_amount,
            "Amount_of_Write_off_Settled_Sub_DBT_Loss_Suitfiled_Wilful_default_in_last_5Yr"  => 0,
            "Eligibility_Method" => $eligibilityChecks['eligibilityMethod'],
            "max_emi_serviced_in_last_36_months" => $eligibilityChecks['max_emi_serviced'],
            "Current_EMI_amount_as_per_bureau" => $eligibilityChecks['current_emi_sum'],
            "Power_Savings_based_on_120_units_per_kw" => $application->application_element->inverter_power_savings,
            "aadhar_number_xml_link" => '',
            "video_image_link." => '',
        ];
    }

    public function eligibityMethodCheck($application_id){
        $max_emi_serviced = 0;
        $emiSpan = Carbon::now()->subMonth(36)->format('Y-m');

        $includeAccountTypes = ['Auto Loan',
            'Business Loan',
            'Business Loan - Priority Sector- Small Business',
            'Business Loan - Secured',
            'Business Loan - Unsecured',
            'Business Loan – General',
            'Commercial Vehicle Loan',
            'Construction Equipment Loan',
            'Consumer Loan',
            'Education Loan',
            'Educational Loan',
            'GECL Loan Secured',
            'GECL Loan Unsecured',
            'Gecl Secured',
            'Gecl Unsecured',
            'Home Loan',
            'Housing Loan',
            'Loan on Credit Card',
            'Loan to Professional',
            'Microfinance – Business Loan',
            'Microfinance – Housing Loan',
            'Microfinance – Others',
            'Microfinance – Personal Loan',
            'MicroFinance Business Loan',
            'MicroFinance Housing Loan',
            'MicroFinance Others',
            'MicroFinance Personal Loan',
            'Mortgages Loan',
            'Mudra Loans - Shishu / Kishor / Tarun',
            'Mudra Loans – Shishu / Kishor / Tarun',
            'P2p Auto Loan',
            'P2P Personal Loan',
            'Personal Loan',
            'Pradhan Mantri Awas Yojana - Credit Link Subsidy Scheme MAY CLSS',
            'Prime Minister Jaan Dhan Yojana - Overdraft',
            'Property Loan',
            'Short Term Personal Loan [Unsecured]',
            'Tractor Loan',
            'Two-wheeler Loan',
            'Used Car Loan'];

        $tradelines = FOIR::where('application_id',$application_id)->whereIn('AccountType', $includeAccountTypes)->where('applicant_type', 1)->where('OwnershipType', 'Individual')->whereNotIn('AccountType', ['Credit Fair EMI'])->get();
        $emiCalculation = ApplicationEMICalculation::where('application_id',$application_id)->first(['emi']);

        $data = [];

        foreach($tradelines as $tradeline){
            $open_date = Carbon::parse($tradeline->DateOpened)->format('Y-m');
            $closed_date = Carbon::parse($tradeline->DateClosed)->format('Y-m');
            if($tradeline->isOpened){
                $closed_date = $tradeline->LastPaymentDate != null ? Carbon::parse($tradeline->LastPaymentDate)->format('Y-m') : Carbon::now()->format('Y-m');
            }
            $date = $open_date;

            if($closed_date > $emiSpan) {
                while ($date <= $closed_date) {
                    $data[$date] = isset($data[$date]) ? $data[$date] + (int)$tradeline->InstallmentAmountNEW : (int)$tradeline->InstallmentAmountNEW;
                    $date = Carbon::parse($date)->addMonths(1)->format('Y-m');
                }
            }
        }
        $max_emi_serviced = max($data);
        $current_emi = end($data);
        $eligibleAmount = ($max_emi_serviced - end($data)) * 50 / 100;

        $eligibleMethod = 'income';
        if($eligibleAmount >= $emiCalculation->emi){
            $eligibleMethod = 'bureau';
        }

        CreditReport::where('application_id', $application_id)->where('applicant_type', 1)->update([
           'max_emi_serviced' => $max_emi_serviced,
            'current_emi_sum' => $current_emi

        ]);

        return [
            'eligibilityMethod' => $eligibleMethod,
            'max_emi_serviced' => $max_emi_serviced,
            'current_emi_sum' => $current_emi
        ];
    }

    private function get_co_applicant($application){
        $co_applicant_name = explode(' ', $application->co_applicant_name);
        $gender = '';
        if(strtolower($application->co_applicant_gender) == 'male'){
            $gender = "M";
        }else if(strtolower($application->co_applicant_gender) == 'female'){
            $gender = "F";
        }

        $co_applicant_current_address_status = 'owned';
        if(strtolower($application->co_applicant_employee_status) == 'rented'){
            $co_applicant_current_address_status = 'rented';
        }

        $applicationController = new ConsumerApplicationController();
        $creditReport = CreditReport::where('application_id', $application->id)->where('applicant_type', 2)->first(['Score']);

        if (isset($creditReport->score)) {
            $latestdpd = $applicationController->getDPD($application->id, 2);
            $CoappMaxSixMonthDPDs = $latestdpd['six_mon_max_30_plus'] ?? 0;//$latestdpd['six_mon_max'];
            $CoappMaxTwelveMonthDPDs = $latestdpd['twelve_mon_max_90_plus'] ?? 0;//$latestdpd['twelve_mon_max'];
            $CoappMaxThreeMonthDPDs = $latestdpd['three_mon_max_0_plus'] ?? 0;//$latestdpd['three_mon_max'];
            $CoappTotalAccountsInStatus = $latestdpd['total_accounts_in_status'] ?? 0;
            $CoappTotalActiveRestructuredLoans = $latestdpd['totalActiveRestructuredLoans'] ?? 0;
        }


        $pastOverDue = 0;
        $foirData = FOIR::where('application_id', $application->id)->where('applicant_type', 2)->where('isOpened', 1)->get(['dpd']);
        foreach ($foirData as $item){
            if (isset($item->dpd)){
//                $dpd = json_decode($item->dpd, 1);
//                foreach($dpd as $key => $dpdItem){
//                    if ($key == "30+"){
//                        $plus_30 = $dpdItem;
//                    }else if ($key == "60+"){
//                        $plus_60 = $dpdItem;
//                    }else if ($key == "90+"){
//                        $plus_90 = $dpdItem;
//                    }
//                }
                if ($item->PastDueAmount) {
                    $pastOverDue += $item->PastDueAmount;
                }

            }
        }

        return
            [[
                "Max_DPD_days_in_last_3M" => $CoappMaxThreeMonthDPDs ?? 0,
                "Max_DPD_days_in_last_6M" => $CoappMaxSixMonthDPDs ?? 0,
                "Max_DPD_days_in_last_12M" => $CoappMaxTwelveMonthDPDs ?? 0,
                "Number_of_loans_in_Sub_or_DBT_or_Loss_or_Settled_or_Writeoffs_or_Suitfiled_or_wilful_default_in_last_36M" => $CoappTotalAccountsInStatus ?? 0,
                "Number_of_Active_Restructured_loans_excluding_Covid_Restructuring" => $CoappTotalActiveRestructuredLoans ?? 0,
                "bureau_score"  => $creditReport->Score ?? 0,
                "employment_details"  => "BE",
                "income_proof_link"  => $this->getDocumentLink('income_proof_link'),
                "aadhar_number"  => $application->co_applicant_aadhaar_card,
                "current_address"  => $application->co_applicant_address_line_1,
                "net_monthly_income"  => $application->co_applicant_monthly_income,
                "middle_name"  => end($co_applicant_name),
                "annual_income"  => $application->co_applicant_monthly_income * 12,
                "age"  => PWAApplicationForm::calculateAge($application->co_applicant_dob),
                "permanent_address"  => "",
                "gender"  => $gender,
                "pan_number_link"  => $this->getDocumentLink('co_applicant_pan_card'),
                "bank_statement_link"  => $this->getDocumentLink('bank_statement_link'),
                "first_name"  => $co_applicant_name[0],
                "pan_number"  => $application->co_applicant_pan_card,
                "aadhar_number_link"  => $this->getDocumentLink(['co_applicant_aadhar_card', 'co_applicant_aadhar_card_back']),
                "relationship_with_applicant"  => $application->co_applicant_relationship,
                "relationship_proof"  => "",
                "last_name"  => "",
                "mobile_number"  => $application->co_applicant_mobile_number,
                "email"  => $application->co_applicant_email,
                "current_city"  => $application->co_applicant_address_city,
                "current_state"  => $this->getState($application->co_applicant_address_state),
                "current_pincode"  => $application->co_applicant_address_pincode,
                "residence_type_current_address"  => $co_applicant_current_address_status,
                "permanent_city"  => "",
                "permanent_state"  => "",
                "permanent_pincode"  => "",
                'co_applicant_aadhar_number_xml_link' => $this->getDocumentLink(['digio_report_coapplicant']),
                'co_applicant_video_image_link' => $this->getDocumentLink(['vkyc_video_'.$application->id.'_2', 'co_applicant_self_attested']),
                "bureau_report_link"  => $this->getDocumentLink('bureau_report_link'),
                "employment_details_link"  => $this->getDocumentLink('employment_details_link'),
                "co_applicant_bureau_report_link"  => $this->getDocumentLink('co_applicant_equifax_report'),
                "date_of_birth"  => $application->co_applicant_dob,
                "Amount_of_Write_off_Settled_Sub_DBT_Loss_Suitfiled_Wilful_default_in_last_5Yr"  => 0,
                "permanent_city_tier"  => "",
                "Overdue_Amount_as_on_date"  => $pastOverDue,
                "Overdue_amount_for_CC_KCC_Guarantor_Loans"  => 0,
            ]];
    }

    private function getState($state_name){

        $state = ['Andaman & Nicobar Islands' => 'andaman_nicobar_islands',
            'Andhra Pradesh' => 'andhra_pradesh',
            'Arunachal Pradesh' => 'arunachal_pradesh',
            'Assam' => 'assam',
            'Bihar' => 'bihar',
            'Chandigarh' => 'chandigarh',
            'Chhattisgarh' => 'chhattisgarh',
            'Dadra & Nagar Haveli' => 'dadra_nagar_haveli',
            'Daman & Diu' => 'daman_diu',
            'Delhi' => 'delhi',
            'Goa' => 'goa',
            'Gujarat' => 'gujarat',
            'Haryana' => 'haryana',
            'Himachal Pradesh' => 'himachal_pradesh',
            'Jammu & Kashmir' => 'jammu_kashmir',
            'Jharkhand' => 'jharkhand',
            'Karnataka' => 'karnataka',
            'Kerala' => 'kerala',
            'Lakshadweep' => 'lakshadweep',
            'Madhya Pradesh' => 'madhya_pradesh',
            'Maharashtra' => 'maharashtra',
            'Manipur' => 'manipur',
            'Meghalaya' => 'meghalaya',
            'Mizoram' => 'mizoram',
            'Nagaland' => 'nagaland',
            'Orissa' => 'orissa',
            'Pondicherry/Puducherry' => 'pondicherry',
            'Punjab' => 'punjab',
            'Rajasthan' => 'rajasthan',
            'Sikkim' => 'sikkim',
            'Tamil Nadu' => 'tamil_nadu',
            'Tripura' => 'tripura',
            'Uttar Pradesh' => 'uttar_pradesh',
            'Uttaranchal/Uttarakhand' => 'uttaranchal',
            'West Bengal' => 'west_bengal',
            'Telangana' => 'telangana'];

        return $state[$state_name] ?? 'others';
    }

    public function updateLoan($wrapper = null)
    {
        $data = $this->createLoan($wrapper);

        $loan_detail = $data['loan_detail'];

        $updateData['loan_detail'] = [
            'Date_of_PF_receipt' => $loan_detail['Date_of_PF_receipt'],
            'UTR_Number_of_PF' => $loan_detail['UTR_Number_of_PF']
        ];

        if(isset($data['repayment_information'])) {
            $updateData['repayment_information'] = $data['repayment_information'];
        }

        if(isset($data['disbursement_accounts'])) {
            $updateData['disbursement_accounts'] = $data['disbursement_accounts'];
        }

        $updateData['client_loan_id'] = $data['client_loan_id'];
        $updateData['application_id'] = $data['application_id'];

        $updateData['aadhar_number_xml_link'] = $this->getDocumentLink(['digio_report_applicant']);
        $updateData['video_image_link'] = $this->getDocumentLink(['vkyc_video_'.$this->request->get('id').'_1', 'self_attested']);
        $updateData['valuation_report_link'] = $this->getDocumentLink('technical_feasibility_report');
        $updateData['other_kyc_link'] = $this->getDocumentLink('panel_installation_photo');
        $updateData['photo_link']  = $this->getDocumentLink('customer_photo');
        $updateData['psl_proof_link']  = $this->getDocumentLink('udyog_aadhaar_certificate');


        return $updateData;

    }

    public function agreementSigned($wrapper = null)
    {
        $data = [];

        $files = ConsumerApplicationFiles::where('consumer_application_id', $this->request->get('id'))->whereIn('file_type',['sanction_letter', 'loan_agreement_esign', 'nach', 'e mandate', 'cpv'])->get(['id', 'file_path', 'file_type']);

        $lists = [];
        foreach ($files as $file){
            $lists[] = $file->file_type;
        }

        if (!in_array('sanction_letter', $lists)){
            $error = new \stdClass();
            $error->description = 'sanction_letter is required';
            $this->error = $error;
            return $this;
        }

        if (!in_array('loan_agreement_esign', $lists)){
            $error = new \stdClass();
            $error->description = 'Loan Agreement_signed is required';
            $this->error = $error;
            return $this;
        }

        if (!in_array('e mandate', $lists)){
            if (!in_array('nach', $lists)) {
                $error = new \stdClass();
                $error->description = 'E-Mandate is required';
                $this->error = $error;
                return $this;
            }
        }

        if (!in_array('cpv', $lists)){
            $application = new ConsumerApplicationController();
            $appData = ConsumerApplication::with('emi')->where('id', $this->request->get('id'))->first(['id', 'approved_amount']);
            if ($application->getCPVStatus($appData)){
                $error = new \stdClass();
                $error->description = 'Field Verification Report Link is required';
                $this->error = $error;
                return $this;
            }
        }

        foreach ($files as $file){
            /*if (isset($file->file_type) && $file->file_type == 'sanction_letter') {
                $data['sanction_letter_link'] = $this->getDocumentLink($file->file_path, true);
            }else */if (isset($file->file_type) && $file->file_type == 'loan_agreement_esign') {
                $data['entire_set_of_loan_agreements_link'] = $this->getDocumentLink($file->id, true);
            }else if (isset($file->file_type) && in_array($file->file_type, ['nach', 'e mandate'])) {
                $data['nach_enach_mandate_link'] = $this->getDocumentLink($file->id, true);
            }/*else if (isset($file->file_type) && $file->file_type == 'cpv') {
                $data['field_verification_report_link'] = $this->getDocumentLink($file->file_path, true);
            }*/
        }

        return $data;
    }

    public function createRepayment($wrapper = null)
    {
        $loanManagement = new LoanManagement();
        $loanManagement->paymentCalculate($this->request->get('id'));

        $accounting = new AccountingController();
        $accounting->raw = true;
        return [
            "repayment_schedules" => $this->getSchedule($accounting->getLoanScheduleDataV1($this->request->get('id')))
        ];
    }

    public function getSchedule($schedule){

        $data = [];
        foreach($schedule['schedule'] as $key => $item){
            $data[] = [
                "amount" => $item['amount'],
                "principal" => round($item['principal']),
                "due_date" => date('Y-m-d', strtotime($item['due_date'])),
                "interest" => round($item['interest']),
                "other_charges" => 0,
                "installment_no" => $key + 1,
                "pos" => round($item['principal_outstanding'])
            ];
        }
        return $data;
    }

    public function getDocumentLink($filesData = [], $isS3 = false){

        $filesData = is_array($filesData) ? $filesData : [$filesData];

        $files = [];
        $hash = new Hashids('Creditfair by CS', 20);
        if (!$isS3){
            $file_objs = ConsumerApplicationFiles::whereIn('file_type', $filesData)->where('consumer_application_id', $this->request->get('id'));
                if (in_array('aadhar_card', $filesData) || in_array('aadhar_card_back', $filesData)){
                    $file_objs = $file_objs->where('is_masked', 1);
                }
            $file_objs = $file_objs->get(['id', 'file_path', 'file_type']);
            foreach ($file_objs as $key => $file_obj) {
                if (isset($file_obj->id)) {
                    $hash_id = $hash->encode($file_obj->id);
                    if ($hash_id){
                        $files[] =  asset('content-service/bin?access_token='.$this->append_jwt_token($hash_id));
                    }

                }
            }
        }else{
            foreach ($filesData as $filesItem){
                $hash_id = $hash->encode($filesItem);
                if ($hash_id){
                    $files[] =  asset('content-service/bin?access_token='.$this->append_jwt_token($hash_id));
                }
            }
        }

        return $files;

        // return ["https://cdn.pixabay.com/photo/2017/06/22/20/22/green-2432374_1280.jpg"]; // Foer vivriti testing on stage to be removed on release
    }

    public function returnDocument($id){

        $file_obj = ConsumerApplicationFiles::where('id', $id)->first(['id', 'file_path', 'file_type']);

        $disk = Storage::disk('s3');
        if (!$disk->exists($file_obj->file_path)){
            $disk = Storage::disk('s3_temp');
        }
        if ($disk->exists($file_obj->file_path)){

            $fileName = $file_obj->file_path;

            $stream = $disk->readStream($fileName);

            if (!$stream) {
                (new Slack(new Request(['title' => 'Document Vivriti Stream Issue', 'fields' => ['fileName' => $fileName, 'id' => $id], 'group' => Slack::$STAGE_TESTING])))->send();
                abort(404);
            }

            $response = new StreamedResponse(function() use ($stream) {
                fpassthru($stream);
            }, 200, [
                'Content-Type' => $disk->mimeType($fileName),
                'Content-Length' => $disk->size($fileName),
                'Content-Disposition' => 'attachment; filename="' . basename($fileName) . '"',
            ]);

            $response->headers->set('Connection', 'close');

            return $response;

        }
        (new Slack(new Request(['title' => 'Document Vivriti File not exists', 'fields' => ['fileName' => $file_obj->file_path, 'id' => $id], 'group' => Slack::$STAGE_TESTING])))->send();
        abort(404);
    }

    public function getLoan($wrapper = null)
    {
        return [];
    }

    public function append_jwt_token($hash_id){
        $jwt = new JWTAccess();
        return $jwt->encodeJWT($this->request->merge(['data' => ['session_string' => $hash_id, 'jte_iv_eop' => 60*60]]), _env('CHAT_BOT_SECRET_KEY'));
    }

    public function decode_jwt_token($hash_id){
        $jwt = new JWTAccess();
        $request = new Request(['data' => $hash_id]);
        $jwt->secret = _env('CHAT_BOT_SECRET_KEY');
        return $jwt->decodeJWT($request, $jwt->secret);
    }
}
