<?php

namespace App\Method\Lendbox\Payload;

use App\ConsumerApplication;
use App\EmiPayment;
use App\Http\Controllers\Admin\AccountingController;
use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\Http\Controllers\Admin\DisbursementController;
use App\LendboxCreateLoan;
use App\MerchantOffers;
use App\Method\Lendbox\Helpers\LendboxHelper;
use App\PaymentTransaction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;


class Payload implements LendboxHelper
{
    public $request;
    public $error = null;

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

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

    public function borrowerRegistration($wrapper = null){
        $application = ConsumerApplication::with('bank_details','application_element','digital_sign')->where('id', $this->request->get('id'))->first(['id', 'name', 'dob', 'gender', 'email', 'merchant_id', 'mobile_number','pan_card','current_address_line_1','current_address_state','current_address_city','current_address_pincode','created_at']);

        $name = explode(' ', $application->name);
        if (empty($application->name)){
            $error = new \stdClass();
            $error->description = 'Name is required';
            $this->error = $error;
            return $this;
        }

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

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

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

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

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

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

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

        if (empty($application->application_element->father_name)){
            $error = new \stdClass();
            $error->description = 'Father name is required';
            $this->error = $error;
            return $this;
        }

        if (empty($application->bank_details->name)){
            $error = new \stdClass();
            $error->description = 'Account Holder Name is required';
            $this->error = $error;
            return $this;
        }

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

        if (empty($application->bank_details->account_type)){
            $error = new \stdClass();
            $error->description = 'Account Type is required';
            $this->error = $error;
            return $this;
        }

        if (empty($application->bank_details->account_number)){
            $error = new \stdClass();
            $error->description = 'Account Number is required';
            $this->error = $error;
            return $this;
        }

        if (empty($application->digital_sign) || (isset($application->digital_sign[0]) && !$application->digital_sign[0]['isaddress'])){
            $error = new \stdClass();
            $error->description = 'Ip is required';
            $this->error = $error;
            return $this;
        }
        // if (empty($application->digital_sign) || (isset($application->digital_sign[0]) && !$application->digital_sign[0]['client'])){
        //     $error = new \stdClass();
        //     $error->description = 'User agent is required';
        //     $this->error = $error;
        //     return $this;
        // }
        if($application->gender == 'MALE'){
            $title = "Mr.";
        }else if($application->gender == 'FEMALE'){
            $title = "Ms.";
        }else{
            $title = '';
        }
        $user_agent = isset($application->digital_sign[0]) ? json_decode($application->digital_sign[0]['client'], TRUE) : NULL;
        $userAgent  = isset($user_agent) ? $user_agent['userAgent'] : "";

        return [
            "email" => $application->email,
            "title" => $title,
            "firstName" =>$name[0],
            "lastName" =>end($name),
            "fathersName" =>$application->application_element->father_name,
            "mobile" =>$application->mobile_number,
            "pan" =>$application->pan_card,
            "dob" =>strtotime($application->dob)*1000,
            "street1" =>$application->current_address_line_1,
            "street2" =>$application->current_address_state,
            "city" =>$application->current_address_city,
            "pin" =>$application->current_address_pincode,
            "holderName" =>$application->bank_details->name,
            "ifsc" =>$application->bank_details->ifsc_code,
            "accountType" =>strtoupper($application->bank_details->account_type),
            "accountNumber" =>$application->bank_details->account_number,
            "ip" => isset($application->digital_sign[0]) ? $application->digital_sign[0]['isaddress'] : "",
            "ua" =>$userAgent,
            "timestamp" => strtotime($application->created_at)*1000,
            "isLbLsp" => $this->request->has('isLbLsp') ? $this->request->get('isLbLsp') : false,
            "appId" => $this->request->has('id') ? $this->request->get('id') : "",
        ];
    }

    public function uploadDocument($wrapper = null){
        $file_path = $this->request->get('file_path');
        $param = $this->request->get('param');
        $s3 = Storage::disk('s3');
        if ($s3->exists($file_path)){
            $file = $s3->get($file_path);
        }elseif($param == "AADHAR" || $param == "VOTER_ID" || $param == "OTHER"){
            $error = new \stdClass();
            $error->description = 'Aadhar Card or Voter ID or Driving License not masked';
            $this->error = $error;
            return $this;
        }else{
            $error = new \stdClass();
            $error->description = 'File is missing';
            $this->error = $error;
            return $this;
        }
        $fileArray = explode("/", $file_path);
        $file_name = $fileArray[1];
        $file_name_arr = explode(".", $file_name);
        $file_extension = $file_name_arr[1] ?? '';
        if($file_extension == ""){
            $file_name_1 = $fileArray[2];
            $file_name_arr_1 = explode(".", $file_name_1);
            $file_extension = isset($file_name_arr_1[1]) ? $file_name_arr_1[1] : '';
            $file_name = $file_name.$file_extension;
            $file_tmp_path = storage_path().'/'.$file_name;
        }else{
            $file_tmp_path = storage_path().'/'.$file_name;
        }
        file_put_contents($file_tmp_path,$file);
        $mime = "";
        if($file_extension == "jpg" || $file_extension == "jpeg"){
            $mime = "image/jpeg";
        }
        if($file_extension == "png"){
            $mime = "image/png";
        }
        if($file_extension == "pdf"){
            $mime = "application/pdf";
        }

        if($mime == ""){
            $error = new \stdClass();
            $error->description = 'Incorrect File Type';
            $this->error = $error;
            return $this;
        }
        return [
            $param => new \CurlFile($file_tmp_path,$mime,$file_name),
            "lbUserId"  => $this->request->get('lbUserId'),
            "isLbLsp"   => $this->request->has('isLbLsp') ? $this->request->get('isLbLsp') : false,
            "appId"     => $this->request->has('id') ? $this->request->get('id') : "",
        ];
    }

    public function createLoan($wrapper = null){
        $application = ConsumerApplication::with('emi','category')->where('id', $this->request->get('id'))->first(['id','merchant_id','purpose','approved_amount']);

        $merchant = MerchantOffers::where('id', $application->emi->offer_id)->first(['advance_type']);

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

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

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

        $net_loan_amount = $application->approved_amount - $application->emi->upfront_from_customer;
        return [
            "roi" =>$application->emi->interest_rate ?? 0,
            "loanAmount"=>$net_loan_amount,
            "loanTenure" =>$net_tenure,
            "durationInDays" => 0,
            "lbUserId"  => $this->request->get('lbUserId'),
            "isLbLsp"   => $this->request->has('isLbLsp') ? $this->request->get('isLbLsp') : false,
            "appId"     => $this->request->has('id') ? $this->request->get('id') : "",
        ];
    }

    public function saveEMI($wrapper = null) {
        $account = new AccountingController();
        $repayments = $account->viewloanschedule($this->request->get('id'),1);
        // $application = ConsumerApplication::with('emi','category')->where('id', $this->request->get('id'))->first(['id','merchant_id','purpose','approved_amount']);
        if($repayments["schedule"]){
            for($i = 0; $i < count($repayments["schedule"]); $i++){

                $interest = isset($repayments["schedule"][$i]['irr']) ? round($repayments["schedule"][$i]['irr'],2) : 0;
                $balance = isset($repayments["schedule"][$i]['principal_outstanding']) ? round($repayments["schedule"][$i]['principal_outstanding'],2) : 0;
                $emi_amount = isset($repayments["schedule"][$i]['amount']) ? round($repayments["schedule"][$i]['amount'],2) : 0;
                $principal = $emi_amount - $interest;
                $emi_date = isset($repayments["schedule"][$i]['emi_date']) ? $repayments["schedule"][$i]['emi_date'] : "";

                $edis[$i]['edi'] = array(
                    "counter"=> $i+1,
                    "interest"=> $interest,
                    "principal"=> round($principal),
                    "balance"=> $balance,
                    "amount"=> $emi_amount,
                    "dueDate"=> $emi_date
                );
            }

        }else{
            $error = new \stdClass();
            $error->description = 'Repayment Schedule not found';
            $this->error = $error;
            return $this;
        }

        $emi['loanId'] = $this->request->has('lbLoanId') ? strval($this->request->get('lbLoanId')) : "";
        $emi['appId']  = $this->request->has('id') ? $this->request->get('id') : "";
        $emi["isLbLsp"] = $this->request->has('isLbLsp') ? $this->request->get('isLbLsp') : false;


        foreach($edis as $edi){
            $emi['edi'][] = $edi['edi'];
        }

        return $emi;
    }

    public function walletOrder($wrapper = null) {
        $order = [];
        $txType = $this->request->has('txnType') ? $this->request->get('txnType') : "";

        $order['appId']  = $this->request->has('id') ? $this->request->get('id') : "";
        $order["isLbLsp"] = $this->request->has('isLbLsp') ? $this->request->get('isLbLsp') : false;

        if($txType == 'DEBIT'){
            $application = ConsumerApplication::with('emi','proFormaInvoice','merchant','application_element.merchant_center')->where('id', $this->request->get('id'))->first();
            $disbursementData = (new DisbursementController($this->request))->getDisbursementAmountForLendboxLSP($application);
            $disb_amount = $disbursementData['disbursement'];
            $subvention_amount = $disbursementData['subvention_amount'];
            $subvention_gst_amount = $disbursementData['subvention_gst_amount'];
            $pf_amount = $disbursementData['processing_fee_by_merchant'];

            $app_id = $this->request->has('id') ? $this->request->get('id') : "";
            $merchant_holder = $merchant_ifsc = $merchant_account_no = "";
            $merchantBank = (new ConsumerApplicationController())->getBankAccountDetails($application);
            if($merchantBank) {
                $merchant_holder = isset($merchantBank['beneficiaryName']) ? $merchantBank['beneficiaryName'] : "";
                $merchant_ifsc = isset($merchantBank['beneficiaryIFSC']) ? $merchantBank['beneficiaryIFSC'] : "";
                $merchant_account_no = isset($merchantBank['beneficiaryAccount']) ? $merchantBank['beneficiaryAccount'] : "";
            }

            $deductions = [
                "gst" => $subvention_gst_amount,
                "subvention" => $subvention_amount
            ];

            $order['payload'][] = [
                "lbUserId"      => $this->request->has('lbUserId') ? $this->request->get('lbUserId') : 0,
                "loanId"        => $this->request->has('lbLoanId') ? $this->request->get('lbLoanId') : 0,
                "amount"        => $disb_amount,
                "txType"        => "DEBIT",
                "txId"          => "D".$app_id,
                "txTime"        => date('Y-m-d H:i:s'),
                "deductions"    => $deductions,
                "processingFee" => $pf_amount,
                "notes"         => "DIRECT_DISBURSAL",
                "holderName"    => $merchant_holder,
                "ifsc"          => $merchant_ifsc,
                "accountType"   => "0",
                "accountNumber" => $merchant_account_no,
                "appId"         => $app_id,
            ];

        }else if($txType == 'CREDIT'){
            $payload = [];
            $appId = 0;
            $transactions = $this->request->has('transactions') ? $this->request->get('transactions') : [];
            foreach($transactions as $appPay){
                $appId = isset($appPay->id) ? $appPay->id : 0;
                $lendboxData = LendboxCreateLoan::where('application_id',$appPay->id)->where('result','success')->first(['lbUserId','lbLoanId']);
                $payTrnxs = PaymentTransaction::select(['id','amount','cf_transaction_id','payment_reconciliation_date','trasanction_id','mode'])
                    ->where('application_id',$appPay->id)
                    ->where('emi_payment_id', $appPay->emi_payment_id)
                    ->get();
                
                if(!empty($payTrnxs) && count($payTrnxs) > 0){
                    foreach($payTrnxs as $paymentTrnx){
                        $chgAmount  = round($appPay->bounce_charges) + round($appPay->delay_penalty);
                        $emiAmount  = isset($appPay->emi_amount) ? round($appPay->emi_amount,2) : 0;
                        $lbAmnt     = isset($paymentTrnx) ? $paymentTrnx->amount : 0;

                        if($lbAmnt == $appPay->bounce_charges || $lbAmnt == $appPay->delay_penalty || $lbAmnt <= $chgAmount){
                            $emiCounter  = 0;
                            $emiPayments = EmiPayment::where('application_id',$appPay->id)->orderBy('emi_date','asc')->get();
                            foreach($emiPayments as $k => $v){
                                if($v->id == $appPay->emi_payment_id){
                                    $emiCounter = ($k+1);
                                }
                            }

                            $payload[] = [
                                "lbUserId"      => isset($lendboxData->lbUserId) ? $lendboxData->lbUserId : 0,
                                "loanId"        => isset($lendboxData->lbLoanId) ? $lendboxData->lbLoanId : 0,
                                "amount"        => $lbAmnt,
                                "txType"        => "CREDIT",
                                "txId"          => isset($paymentTrnx) ? $paymentTrnx->id.$paymentTrnx->cf_transaction_id : "",
                                "txTime"        => isset($paymentTrnx) ? $paymentTrnx->payment_reconciliation_date : "",
                                "utr"           => isset($paymentTrnx) ? $paymentTrnx->trasanction_id : "",
                                "paymentMethod" => isset($paymentTrnx) ? $paymentTrnx->mode : "",
                                "paymentSource" => isset($paymentTrnx) ? $paymentTrnx->mode : "",
                                "notes"         => "LATE_PAYMENT_CHARGES",
                                "emiCounter"    => $emiCounter,
                            ];
                        }else if($lbAmnt <= $emiAmount && $lbAmnt > $chgAmount){
                            $interestRate   = isset($appPay->emi) && isset($appPay->emi->interest_rate) ? ($appPay->emi->interest_rate/1200) : 0;
                            $interest       = round($interestRate * $lbAmnt, 2);
                            $principal      = round($lbAmnt - $interest, 2);
            
                            $payload[] = [
                                "lbUserId"      => isset($lendboxData->lbUserId) ? $lendboxData->lbUserId : 0,
                                "loanId"        => isset($lendboxData->lbLoanId) ? $lendboxData->lbLoanId : 0,
                                "amount"        => $lbAmnt,
                                "txType"        => "CREDIT",
                                "txId"          => isset($paymentTrnx) ? $paymentTrnx->id.$paymentTrnx->cf_transaction_id : "",
                                "txTime"        => isset($paymentTrnx) ? $paymentTrnx->payment_reconciliation_date : "",
                                "utr"           => isset($paymentTrnx) ? $paymentTrnx->trasanction_id : "",
                                "paymentMethod" => isset($paymentTrnx) ? $paymentTrnx->mode : "",
                                "paymentSource" => isset($paymentTrnx) ? $paymentTrnx->mode : "",
                                "notes"         => "BILL_REPAYMENT",
                                "principal"     => $principal,
                                "interest"      => $interest,
                            ];
                        }
                    }
                } 
            }
            $order['appId']   = $appId;
            $order['payload'] = $payload;
        }
        return $order;
    }

    public function transactionStatus($wrapper = null) {
        $order = $payload = [];
        $order["isLbLsp"] = $this->request->has('isLbLsp') ? $this->request->get('isLbLsp') : false;
        $transactions = $this->request->has('transactions') ? $this->request->get('transactions') : [];
        foreach($transactions as $key => $dbPay){
            if(isset($dbPay->id) && $dbPay->id != ""){
                $payload[] = "D".$dbPay->id;
            }
        }
        $order['txIds'] = $payload;
        return $order;
    }
}
