<?php

namespace App\Method\JM\Response;

use App\ABFL\Services\Services;
use App\Comments;
use App\ConsumerApplication;
use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\JMDisburse;
use App\JMDocuments;
use App\JMLoanBooking;
use App\JMMandate;
use App\JMOnboarding;
use App\JMRepayment;
use App\JMRepaymentSchedule;
use App\JMService\JMServices;
use App\Method\JM\Helpers\JMHelper;
use App\LendboxBorrowerReg;
use App\LendboxCreateLoan;
use App\LendboxDocument;
use Illuminate\Support\Carbon;
use App\Slack;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Input;

class Response implements JMHelper
{
    public $errorBag;
    public $response;
    public $request;
    public function resolveResponse($func, $res, $request = null){
        if(isset($res->error->description)){
            $this->errorBag['Error'] = $res->error->description;
            $this->response = $res;
            return $this;
        }
        if ($request)
            $this->request = $request;
        if(method_exists($this, $func)){
            return $this->$func($res);
        }
        return array();
    }

    public function uploadDocument($res){
        if(isset($res->is_success) && !$res->is_success){
            $this->errorBag['Error'] = $this->getError($res);
            $this->response = $res;
            return $this;
        }

        $JMDocuments = new JMDocuments();
        $fileId = Input::get('file_id') ? Input::get('file_id') : $this->request->get('file_id');
        $documents = JMDocuments::where('consumer_application_file_id',$fileId)->count();
        /*if($documents == 0 && isset($res->data->processed) && isset($res->data->processed[0]) && $res->data->processed[0] == $fileId){*/
            $JMDocuments->fill([
                'application_id' => Input::get('id'),
                'consumer_application_file_id' => $fileId,
                'response' => json_encode($res),
                'user_id' => Input::get('user_id'),
                'created_at' =>Carbon::now()->toDateTimeString(),
            ]);
            $JMDocuments->save();
        /*}*/
       
        $this->response = $res;
        return $this;
    }


    public function createLoan($res){
        if(isset($res->is_success) && !$res->is_success){
            if (isset($res->error->details) && isset($res->error->details->loan_account_number)){
                $this->updateLoanAccountNumber($res);
                $this->errorBag['Error'] = $res->error->message;
                $this->response = $res;
                return $this;
            }else {
                $this->errorBag['Error'] = $this->getError($res);
                $this->response = $res;
                return $this;
            }
        }

        if(isset($res->error->description)){
            $this->errorBag['Error'] = $res->error->description;
            $this->response = $res;
            return $this;
        }
        
        $this->updateLoanAccountNumber($res);
        $this->response = $res;
        return $this;
    }

    public function updateLoanAccountNumber($res){
        $JMLoanBooking = JMLoanBooking::where('application_id', Input::get('id'))->first(['id']);
        if (!isset($JMLoanBooking->id)){
            $JMLoanBooking = new JMLoanBooking();
            $loan_ac_no = isset($res->data->loan_account_number) && $res->data->loan_account_number ? $res->data->loan_account_number : (isset($res->error->details->loan_account_number) && $res->error->details->loan_account_number ? $res->error->details->loan_account_number : (isset($res->data->loan_ac_no) && $res->data->loan_ac_no ? $res->data->loan_ac_no : ''));
            $lead_id = isset($res->data->lead_id) && $res->data->lead_id ? $res->data->lead_id : (isset($res->error->details->lead_id) && $res->error->details->lead_id ? $res->error->details->lead_id : '');
            $JMLoanBooking->fill([
                'application_id' => Input::get('id'),
                'loan_ac_no' => $loan_ac_no,
                'lead_id' => $lead_id,
                'status' => $res->data->status ?? 'pending'
            ]);
            $JMLoanBooking->save();
        }
    }

    public function getError($res){
        $error = [];
        if (isset($res->error->description)){
            $error[] = $res->error->description;
        }else if(isset($res->error->details)){
            foreach ($res->error->details as $key => $detail) {
                $detail = is_array($detail) ? $detail : (array) $detail;
                if (is_array($detail)) {
                    foreach ($detail as $item) {
                        $item = (array)$item;
                        $string = implode(": ", array_map(
                            function ($key, $value) {
                                return "$key: $value";
                            },
                            array_keys($item),
                            $item
                        ));
                        $error[] = $key . ':' . $string;
                    }
                }
            }
        }
        $message = ($res->error->message ?? '')."\n".implode(', ', $error);
        return $message;
    }

    public function getLoanStatus($res)
    {
        if(isset($res->is_success) && !$res->is_success){
            $this->errorBag['Error'] = $this->getError($res);
            $this->response = $res;
            return $this;
        }

        $JMLoanBooking = JMLoanBooking::where('application_id', Input::get('id'))->first(['id', 'loan_ac_no', 'status']);
        if (!$JMLoanBooking->loan_ac_no && $res->data->loan_ac_no){
            JMLoanBooking::where('application_id', Input::get('id'))->update(['loan_ac_no' => $res->data->loan_ac_no]);
        }
        if(isset($JMLoanBooking->id) && $JMLoanBooking->status == 'pending' && $res->data->status == 'Approved'){
            $this->onboardingCompleted($res);
        }

        $this->response = $res;
        return $this;
    }

    public function updateLoan($res)
    {
        if(isset($res->is_success) && !$res->is_success){
            $this->errorBag['Error'] = $this->getError($res);
            $this->response = $res;
            return $this;
        }

        $this->response = $res;
        return $this;
    }

    public function onboardingCompleted($res)
    {
        if(isset($res->is_success) && !$res->is_success){
            $this->errorBag['Error'] = $this->getError($res);
            if(isset($res->error->code) && $res->error->code == "request_validation_error"){
                $this->updateStatus('waiting for decision', JMServices::$lender_id);
            }
            $this->response = $res;
            return $this;
        }

        $JMBooking = JMOnboarding::where('application_id', Input::get('id'))->first(['id', 'status']);
        if (!isset($JMBooking->id) || $JMBooking->status != 'Approved'){
            $JMOnboarding = (isset($JMBooking->id)) ? JMOnboarding::find($JMBooking->id) : new JMOnboarding();

            $JMOnboarding->fill([
                'application_id' => Input::get('id'),
                'status' => $res->data->status,
                'response' => json_encode($res)
            ]);

            $JMOnboarding->save();

            if($res->data->status == 'Approved') {
                $this->updateStatus('approved', JMServices::$lender_id);
            }else if(in_array($res->data->status, ['Rejected', 'Rejected By Loan Officer'])){
                $this->sendComment(Input::get('id'), 'JM BRE Reject');
                $this->updateStatus('waiting for decision');
            }

            JMLoanBooking::where('application_id', Input::get('id'))->update(['status' => $res->data->status]);
        }

        $this->response = $res;
        return $this;
    }

    public function updateStatus($status, $lender_id = 2){
        $application = ConsumerApplication::where('id', Input::get('id'))->where('lender_id',JMServices::$lender_id)->first(['id']);
        if (isset($application->id)) {
            $this->changeStatus(Input::get('id'), $lender_id, $status, $this->errorBag['Error']);
        }
    }

    public function disburseLoan($res)
    {
        if(isset($res->is_success) && !$res->is_success){
            $this->errorBag['Error'] = $this->getError($res);
            $this->response = $res;
            return $this;
        }

        $id = Input::get('id') ? Input::get('id') : $this->request->get('id');

        $JMDisburse = JMDisburse::where('application_id', $id)->first(['id']);
        if (!isset($JMDisburse->id)){
            $JMDisburse = new JMDisburse();
            $JMDisburse->fill([
                'application_id' => $id,
                'status' => $res->data->status,
                'amount' => $res->data->amount,
                'transaction_time' => $res->data->transaction_time,
                'transaction_id' => $res->data->transaction_id,
                'closure_reason' => $res->data->closure_reason ?? '',
                'nach_umrn' => $res->data->nach_umrn ?? '',
                'created_at' => Carbon::now()->toDateTimeString()
            ]);

            $JMDisburse->save();
        }

        $this->response = $res;
        return $this;
    }

    public function repaymentSchedule($wrapper)
    {
        if(isset($wrapper->is_success) && !$wrapper->is_success){
            $this->errorBag['Error'] = $this->getError($wrapper);
            $this->response = $wrapper;
            return $this;
        }

        $id = $this->request->has('id') ? $this->request->get('id') : Input::get('id');
        $JMRepaymentSchedule = JMRepaymentSchedule::where('application_id', $id)->first(['id']);
        if (!isset($JMRepaymentSchedule->id) && isset($wrapper->data->status)){
            $JMRepaymentSchedule = new JMRepaymentSchedule();
            $JMRepaymentSchedule->fill([
                'application_id' => $id,
                'tentative_schedule' => isset($wrapper->data->tentative_schedule) && $wrapper->data->tentative_schedule ? 1 : 0,
                'status' => $wrapper->data->status,
                'principal' => $wrapper->data->collection->principal ?? 0,
                'interest' => $wrapper->data->collection->interest ?? 0,
                'bounce_charges' => $wrapper->data->collection->bounce_charges ?? 0,
                'late_interest' => $wrapper->data->collection->late_interest ?? 0,
                'total' => $wrapper->data->collection->total ?? 0,
                'excess' => $wrapper->data->collection->excess ?? 0,
                'dpd' => $wrapper->data->collection->dpd ?? 0,
                'response' => json_encode($wrapper)
            ]);

            $JMRepaymentSchedule->save();
        }

        $this->response = $wrapper;
        return $this;

    }

    public function repayment($res)
    {
        if(isset($res->is_success) && !$res->is_success){
            $this->errorBag['Error'] = $this->getError($res);
            $this->response = $res;
            return $this;
        }

        $JMRepayment = JMRepayment::where('application_id', Input::get('id'))->first(['id']);
        if (!isset($JMRepayment->id)){
            $JMRepayment = new JMRepayment();
            $JMRepayment->fill([
                'application_id' => Input::get('id'),
                'payment_id' => $this->request->get('payment_id'),
                'response' => json_encode($res)
            ]);

            $JMRepayment->save();
        }

        $this->response = $res;
        return $this;
    }

    public function charges($wrapper)
    {
        // TODO: Implement charges() method.
    }

    public function changeStatus($id, $lender_id, $status, $message = ''){
        request()->merge(['lender_id' => $lender_id, 'state' => $status, 'source' => 'jm_bre']);
        if ($message) {
            saveComment("JM Decision : " .$message, $id, 107);
        }
        $applicationController = new ConsumerApplicationController();
        $applicationController->updateStatus($id);
    }

    public function mandate($res)
    {
        if(isset($res->is_success) && !$res->is_success){
            $this->errorBag['Error'] = $this->getError($res);
            $this->response = $res;
            return $this;
        }

        $JMMandate = new JMMandate();
        $documents = JMMandate::where('application_id',Input::get('id'))->count();
        if($documents == 0 && isset($res->data->nach_mandate_id) && $res->data->nach_mandate_id){
            $JMMandate->fill([
                'application_id' => Input::get('id'),
                'mandate_id' => Input::get('mandate_id') ?? $this->request->get('mandate_id'),
                'nach_mandate_id' => $res->data->nach_mandate_id,
                'created_at' =>Carbon::now()->toDateTimeString(),
            ]);
            $JMMandate->save();

            $this->sendComment(Input::get('id'), 'JM review pending');
        }

        $this->response = $res;
        return $this;
    }

    public function sendComment($id, $message){
        Comments::insert([
            'application_id' => $id,
            'user_id' => 107,
            'comment' => $message,
            'show_consumer' => 0,
            'show_merchant' => 0,
            'created_at' => \Carbon\Carbon::now()->toDateTimeString(),
            'updated_at' => Carbon::now()->toDateTimeString(),
            'type' => 'consumer'
        ]);
    }
}