<?php

namespace App\Http\Controllers\Admin;

use App\APIWrapper\Wrapper;
use App\ConsumerApplication;
use App\ConsumerApplicationFiles;
use App\Http\Controllers\Controller;
use App\Method\Lendbox\LendboxMethods;
use Illuminate\Http\Request;
use App\Events\V1\EventLendboxDocumentUpload;
use Illuminate\Support\Facades\Auth;
use App\LendboxBorrowerReg;
use App\LendboxCreateLoan;
use App\LendboxDocument;
use App\Slack;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

class LendboxController extends Controller{

    private $request;

    public function __construct(Request $request){

        $this->request = $request;
    }

    public function checkWorthiness(){
        $user_id = Auth::check() ? Auth::user()->id : 107;
        $wrapper = new Wrapper();
        $wrapperMethods = $wrapper->register(LendboxMethods::class);
        $wrapper->payload->addPayload(new Request(['id' => $this->request->get('id'), 'user_id' => $user_id, 'isLbLsp' => $this->request->get('isLbLsp')]));

        $application = ConsumerApplication::where('id',$this->request->get('id'))->first(['id', 'lender_id']);
        $borrower_reg = LendboxBorrowerReg::where('application_id', $this->request->get('id'))->where('result','success')->first(['id','lbUserId']);
        if(isset($application->id) && empty($borrower_reg)){
            $wrapperRes = $wrapperMethods->borrowerRegistration($wrapper);
            if (isset($wrapperRes->errorBag)) {
                return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
            }
            if(isset($wrapperRes->error->description)){
                return response()->json(['status' => 'FAIL', 'data' => $wrapperRes->error->description]);
            }
            $lbUserId = $wrapperRes->data->lbUserId;
        }else{
            $lbUserId = $borrower_reg->lbUserId;
        }
        
        \request()->merge(['lbUserId' => $lbUserId]);
        $wrapper->payload->addPayload(new Request(['id' => $this->request->get('id'), 'user_id' => $user_id,'lbUserId' => $lbUserId, 'isLbLsp' => $this->request->get('isLbLsp')]));
        $create_loan = LendboxCreateLoan::where('application_id', $this->request->get('id'))->where('result','success')->first(['id','lbLoanId']);
        if(empty($create_loan)){
            $wrapperRes = $wrapperMethods->createLoan($wrapper);
            if (isset($wrapperRes->errorBag)) {
                return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
            }
            if(isset($wrapperRes->error->description)){
                return response()->json(['status' => 'FAIL', 'data' => $wrapperRes->error->description]);
            }
            $lbLoanId = $wrapperRes->data->lbLoanId;
        }else{
            $lbLoanId = $create_loan->lbLoanId;
        }

        if($application->lender_id == 7) {
            \request()->merge(['lbLoanId' => $lbLoanId]);
            // Save EMI Call
            $lbEdi = LendboxCreateLoan::where('application_id', $this->request->get('id'))->where('result','success')->first(['lbEdiStatus', 'lbOrderStatus']);
            if((!empty($lbEdi) && $lbEdi->lbEdiStatus != 'success') || !empty($lbLoanId)){
                $wrapper->payload->addPayload(new Request(['id' => $this->request->get('id'), 'user_id' => $user_id, 'lbLoanId' => $lbLoanId, 'isLbLsp' => $this->request->get('isLbLsp')]));

                $wrapperRes = $wrapperMethods->saveEMI($wrapper);
                if (isset($wrapperRes->errorBag)) {
                    if ($wrapperRes->errorBag['Error'] != "EDI Already Exist.") {
                        return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
                    }
                }
                if (isset($wrapperRes->error->description)) {
                    return response()->json(['status' => 'FAIL', 'data' => $wrapperRes->error->description]);
                }
            }

            if((!empty($lbEdi) && $lbEdi->lbOrderStatus != 'success') || !empty($lbLoanId)){
                // Walllet Order First Call
                \request()->merge(['txnType' => "DEBIT"]);
                $wrapper->payload->addPayload(new Request(['id' => $this->request->get('id'), 'user_id' => $user_id, 'lbLoanId' => $lbLoanId, 'lbUserId' => $lbUserId, 'txnType' => "DEBIT", 'isLbLsp' => $this->request->get('isLbLsp')]));

                $wrapperRes = $wrapperMethods->walletOrder($wrapper);
                if (isset($wrapperRes->errorBag)) {
                    if (!(isset($wrapperRes->response->errorCode) && $wrapperRes->response->errorCode == 40 && $wrapperRes->response->msg == "Some txIds are already exists in our records, Please remove them.")) {
                        return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
                    }
                }
                if (isset($wrapperRes->error->description)) {
                    return response()->json(['status' => 'FAIL', 'data' => $wrapperRes->error->description]);
                }
            }
        }

        $application_files = ConsumerApplicationFiles::select(['consumer_application_id','file_type', 'file_path'])->where('consumer_application_id', $this->request->get('id'))->orderBy('created_at','desc')->get();
        //$doc_array = array('POI'=>['pan_card'],'POA'=>array('votar_id_front','votar_id_back','passport_front','passport_back','aadhar_card','aadhar_card_back','driving_license'),'agreement'=>['loan_agreement_esign'],'proforma'=>['pro_forma_invoice'],'nach'=>['nach'],'bank_proof'=>array('bank_statement_1','bank_statement_2','bank_statement_3','bank_statement_6' ,'security_cheques'));
        $doc_array = array('POI'=>['pan_card'],'POA'=>array('votar_id_front','votar_id_back','passport_front','passport_back','aadhar_card','aadhar_card_back','driving_license'),'agreement'=>['loan_agreement_esign'],'proforma'=>['pro_forma_invoice'],'nach'=>['nach']);
        foreach($application_files as $val){
            foreach($doc_array as $key => $values){
                if (in_array($val->file_type, array_values($values))){
                    unset($doc_array[$key]);
                }
            }
        }
        if(!empty($doc_array)){
           return response()->json(['status' => 'FAIL','data' => array_keys($doc_array)]);
        }else{
            event(new EventLendboxDocumentUpload(['id'=>$this->request->get('id'), 'uid'=>$user_id, 'isLbLsp' => $this->request->get('isLbLsp')]));
            return response()->json(['status' => 'OK', 'data' => ['Message' => 'Loan application sent to LENDBOX']]);
        }
    }

    public function SendDocumentToLendbox(){
        $application_id = $this->request->get('id');
        $uid = $this->request->get('uid');
        $application_files = ConsumerApplicationFiles::select(['id', 'consumer_application_id','file_type', 'file_path'])->where('consumer_application_id', $application_id)->orderBy('created_at','desc')->get();
        $doc_array = [
            'POI'=>['pan_card'],
            'agreement'=> ['loan_agreement_esign'],
            'proforma'=> ['pro_forma_invoice'],
            'nach'=> ['nach'],
            'bank_proof'=> ['bank_statement_1', 'bank_statement_2', 'bank_statement_3', 'bank_statement_6','security_cheques']
        ];
        $poi_array = [
            'voter_id' => ['votar_id_front','votar_id_back'],
            'passport'=> ['passport_front','passport_back'],
            'aadhar_card'=> ['aadhar_card','aadhar_card_back'],
            'driving_license'=> ['driving_license']
        ];
        $doc_final_array = [];
        $bs_check = "";
        foreach($application_files as $val){
            foreach($doc_array as $key => $values){
                if(!in_array($values, $doc_final_array) /*|| strpos($val->file_type, 'bank_statement') !== false*/){
                    if (in_array($val->file_type, array_values($values)) /*|| strpos($val->file_type, 'bank_statement') !== false*/){
                        $doc_final_array[$val->file_type]['path'] = $val->file_path;
                        $doc_final_array[$val->file_type]['file_id'] = $val->id;
                        if($key == 'bank_proof' && strpos($val->file_type, 'bank_statement') !== false){
                            $bs_check = 'bank_statement';
                        }
                        unset($doc_array[$key]);

                    }
                }

            }
            if(!empty($bs_check) && strpos($val->file_type, 'bank_statement') !== false){
                $doc_final_array[$val->file_type]['path'] = $val->file_path;
                $doc_final_array[$val->file_type]['file_id'] = $val->id;
            }
        }

        $var = "";
        foreach($application_files as $val){
            foreach($poi_array as $key => $values){
                if(/*in_array($values, $doc_final_array) &&*/ ($var == "" || $var == $key)){
                    if (in_array($val->file_type, array_values($values))){
                        $doc_final_array[$val->file_type]['path'] = $val->file_path;
                        $doc_final_array[$val->file_type]['file_id'] = $val->id;
                        $var = $key;
                    }
                }
            }
        }

        //echo "<pre>";print_r($doc_final_array);die;
        $lbUser = LendboxBorrowerReg::where('application_id', $application_id)->first(['lbUserId']);
        $lbUserId = $lbUser->lbUserId;
        $wrapper = new Wrapper();
        $wrapperMethods = $wrapper->register(LendboxMethods::class);
        (new Slack(new Request(['title' => 'Lendbox doc check array', 'fields' => ['Status' => 'Error','Array' => json_encode($doc_final_array)], 'group' => Slack::$STAGE_TESTING])))->send();
        foreach($doc_final_array as $key => $val){
            if ($key == 'pan_card'){
                $param = "PAN";
            }
            if ($key == 'votar_id_front' || $key == 'votar_id_back'){
                $param = "VOTER_ID";
            }
            if ($key == 'passport_front' || $key == 'passport_back'){
                $param = "PASSPORT";
            }
            if ($key == 'aadhar_card' || $key == 'aadhar_card_back'){
                $param = "AADHAR";
            }
            if ($key == 'driving_license'){
                $param = "OTHER";
            }
            if ($key == 'loan_agreement_esign'){
                $param = "LOAN_AGREEMENT";
            }
            if ($key == 'pro_forma_invoice'){
                $param = "OTHER";
            }
            if ($key == 'nach'){
                $param = "OTHER";
            }
            if (strpos($key, 'bank_statement') !== false){
                $param = "BANK_STATEMENT";
            }
            if ($key == 'security_cheques'){
                $param = "CHEQUE";
            }
            request()->merge(['id' => $application_id,'file_path' => $val['path'], 'param' =>$param, 'file_id'=>$val['file_id'], 'lbUserId' =>$lbUserId, 'user_id'=>$uid, 'isLbLsp' => $this->request->get('isLbLsp')]);
            $wrapper->payload->addPayload(new Request(['id' => $application_id,'file_path' => $val['path'], 'param' =>$param, 'file_id'=>$val['file_id'], 'lbUserId' =>$lbUserId, 'user_id'=>$uid, 'isLbLsp' => $this->request->get('isLbLsp')]));
            $wrapperRes = $wrapperMethods->uploadDocument($wrapper);
            if (isset($wrapperRes->success) && $wrapperRes->success == true) {
                $fileArray = explode("/", $val['path']);
                $file_name = $fileArray[1];
                //$file_name = end($fileArray);
                $file_tmp_path = storage_path().'/'.$file_name;
                unlink($file_tmp_path);
            }
            if(isset($wrapperRes->errorBag['Error'])){
                break;
            }
        }
        return response()->json(['status' => 'FAIL', 'message' => $wrapperRes->errorBag['Error']]);
    }

    public function SingleSendDocumentToLendbox(){
        $application_id = $this->request->get('id');
        $file_id = $this->request->get('file_id');
        $uid = Auth::check() ? Auth::user()->id : 107;
        $application_files = ConsumerApplicationFiles::where('id', $file_id)->first(['file_type', 'file_path']);
        $lbUser = LendboxBorrowerReg::where('application_id', $application_id)->first(['lbUserId']);
        $lbUserId = $lbUser['lbUserId'];
        $wrapper = new Wrapper();
        $wrapperMethods = $wrapper->register(LendboxMethods::class);
        $key = $application_files->file_type;
        if ($key == 'pan_card'){
            $param = "PAN";
        }
        if ($key == 'votar_id_front_masked' || $key == 'votar_id_back_masked' || $key == 'votar_id_front' || $key == 'votar_id_back'){
            $param = "VOTER_ID";
        }
        if ($key == 'passport_front_masked' || $key == 'passport_back_masked' || $key == 'passport_front' || $key == 'passport_back'){
            $param = "PASSPORT";
        }
        if ($key == 'aadhar_card_masked' || $key == 'aadhar_card_back_masked' || $key == 'aadhar_card' || $key == 'aadhar_card_back'){
            $param = "AADHAR";
        }
        if ($key == 'driving_license_masked' || $key == 'driving_license'){
            $param = "OTHER";
        }
        if ($key == 'loan_agreement_esign'){
            $param = "LOAN_AGREEMENT";
        }
        if ($key == 'pro_forma_invoice'){
            $param = "OTHER";
        }
        if ($key == 'nach'){
            $param = "OTHER";
        }
        if (strpos($key, 'bank_statement') !== false){
            $param = "BANK_STATEMENT";
        }
        if ($key == 'security_cheques'){
            $param = "CHEQUE";
        }
        request()->merge(['id' => $application_id,'file_path' => $application_files->file_path, 'param' =>$param, 'file_id'=>$file_id, 'lbUserId' =>$lbUserId, 'user_id'=>$uid, 'isLbLsp' => $this->request->get('isLbLsp')]);
        $wrapper->payload->addPayload(new Request(['id' => $application_id,'file_path' => $application_files->file_path, 'param' =>$param, 'file_id'=>$file_id, 'lbUserId' =>$lbUserId, 'user_id'=>$uid, 'isLbLsp' => $this->request->get('isLbLsp')]));
        $wrapperRes = $wrapperMethods->uploadDocument($wrapper);
        if (isset($wrapperRes->success) && $wrapperRes->success == true) {
            $fileArray = explode("/", $application_files->file_path);
            $file_name = end($fileArray);
            $file_tmp_path = storage_path().'/'.$file_name;
            return response()->json(['status' => 'OK', 'message' => 'Upload Document Triggered.']);
        }
        return response()->json(['status' => 'FAIL', 'message' => $wrapperRes->errorBag]);

    }

    public function getDocumentMapping(){

        $mappedDocumentExists = [];

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

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

        $mappedDocumentAvExists = [];

        if (isset($filesExistIds) && $filesExistIds) {
            foreach ($filesExistIds as $mainKey => $filesExistId) {
                $avansePushed = LendboxDocument::where('application_id', $this->request->get('id'))->whereIn('consumer_application_file_id', $filesExistId)->first();
                if (isset($avansePushed->id)) {
                    $mappedDocumentAvExists[$mainKey] = $mainKey;
                }
            }
        }

        return [$mappedDocumentExists, $mappedDocumentAvExists];
    }

    public function lendboxRepayments(){
        $from   = Carbon::parse('yesterday 9pm');
        $to     = Carbon::parse('today 9pm');
        $startDate = Carbon::now()->startOfMonth()->toDateString();
        $endDate = Carbon::now()->endOfMonth()->toDateString();

        // $transactions = ConsumerApplication::select('id')->with('emi','emi_payment','payment_transaction')
        //     ->where('lender_id',"7")
        //     ->whereNull('deleted_at')
        //     ->whereIn('state',['disbursed','nach registered'])
        //     ->whereHas('emi_payment', function ($q) { $q->where('payment_status','success');})
        //     ->whereHas('payment_transaction', function ($q) use($from, $to){
        //         $q->where('status','success')->whereNull('is_deleted_at')->whereBetween('created_at', [$from, $to]);
        //     })->get();
        
        $transactions = DB::table('consumer_application as ca')
            ->select('ca.id', 'pt.emi_payment_id', 'ep.bounce_charges', 'ep.delay_penalty', 'ep.emi_amount')
            ->join('emi_payments as ep', 'ep.application_id', '=', 'ca.id')
            ->join('payment_transactions as pt', 'pt.emi_payment_id', '=', 'ep.id')
            ->where('ca.lender_id', "7")
            ->whereNull('ca.deleted_at')
            ->whereIn('ca.state', ['disbursed', 'nach registered'])
            ->whereBetween('pt.created_at', [$from, $to])
            ->where('pt.status', 'success')
            ->whereNull('pt.is_deleted_at')
            ->where('pt.emi_payment_id', '<>', 0)
            ->whereBetween('ep.emi_date', [$startDate, $endDate])
            ->where('ep.payment_status', 'success')
            ->distinct()
            ->get();

        if(count($transactions) > 0){
            foreach($transactions->chunk(10) as $transactionsChunk){
                $wrapper = new Wrapper();
                $wrapperMethods = $wrapper->register(LendboxMethods::class);
                \request()->merge(['txnType' => "CREDIT"]);
                $wrapper->payload->addPayload(new Request(['txnType' => "CREDIT", 'isLbLsp' => 'true', 'transactions' => $transactionsChunk]));
                $wrapperRes = $wrapperMethods->walletOrder($wrapper);
                if (isset($wrapperRes->errorBag)) {
                    if (!(isset($wrapperRes->response->errorCode) && $wrapperRes->response->errorCode == 40 && $wrapperRes->response->msg == "Some txIds are already exists in our records, Please remove them.")) {
                        return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
                    }
                }
                if (isset($wrapperRes->error->description)) {
                    return response()->json(['status' => 'FAIL', 'data' => $wrapperRes->error->description]);
                }
            }
        }else {
            return response()->json(['status' => 'FAIL', 'data' => 'No transactions found']);
        }
    }

    public function lendboxTransactionStatus(){
        $transactions  = ConsumerApplication::select('id')->with('application_element')
            ->where('lender_id', 7)
            ->whereIn('state',['ready for disbursement'])
            ->whereNull('deleted_at')
            ->whereHas('application_element', function ($q) { $q->whereNull('reference_number')->orWhere('reference_number',''); })
            ->get();
        if(count($transactions) > 0){
            foreach($transactions->chunk(100) as $transactionsChunk){
                $wrapper = new Wrapper();
                $wrapperMethods = $wrapper->register(LendboxMethods::class);
                $wrapper->payload->addPayload(new Request(['txnType' => "DEBIT", 'isLbLsp' => 'true', 'transactions' => $transactionsChunk]));
                $wrapperRes = $wrapperMethods->transactionStatus($wrapper);
                if (isset($wrapperRes->errorBag)) {
                    if (!(isset($wrapperRes->response->errorCode) && $wrapperRes->response->errorCode == 40 && $wrapperRes->response->msg == "Some txIds are already exists in our records, Please remove them.")) {
                        return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
                    }
                }
                if (isset($wrapperRes->error->description)) {
                    return response()->json(['status' => 'FAIL', 'data' => $wrapperRes->error->description]);
                }

                return response()->json(['status' => 'SUCCESS', 'msg' => isset($wrapperRes->response->msg) ? $wrapperRes->response->msg : 'Lendbox LSP transactions status fetched successfully', 'data' => isset($wrapperRes->responseData) ? $wrapperRes->responseData : []]);
            }
        }else {
            return response()->json(['status' => 'FAIL', 'data' => 'No transactions found']);
        }
    }
}

