<?php namespace App;
use App\APIWrapper\Wrapper;
use App\Method\ABFL\ABFLMethods;
use App\Method\OneFin\Payload\Payload;
use App\Method\OneFin\OneFinMethods;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use App\CSV;


/**
 * Created by PhpStorm.
 * User: sunil khorwal
 * Date: 6/6/16
 * Time: 1:52 PM
 */
class OneFinService extends CFOneFinConfig
{
    private $request;
    /**
     * @var Wrapper
     */
    private $wrapper;
    /**
     * @var mixed
     */
    private $wrapperMethods;

    public $apis = [
        'onBoardChannelEntity' => false,
        'createLoan' => false,
        'postLoanRepayment' => false,
        'createMandate' => false,
        'loanDisbursal' => false,
        'getRepaymentSchedule' => false
    ];


    /**
     * Slack constructor.
     * @param Request $request
     */
    public function __construct(Request $request){
        $this->request = $request;
        $this->getWrapper();
    }

    private function getWrapper(){
        $this->wrapper = new Wrapper();
        $this->wrapperMethods = $this->wrapper->register(OneFinMethods::class);
    }

    public function createLoan()
    {

        $this->wrapper->payload->addPayload($this->request);
        $wrapperRes = $this->wrapperMethods->createLoan($this->wrapper);
        if (!$wrapperRes->errorBag)
            return response()->json(['status' => 'OK', 'data' => ['Message' => 'Loan application sent to OneFin']]);

        return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
    }

    public function postLoanRepayment()
    {
        $this->request->merge(['lead_id' => $this->getLeadId()]);
        $this->wrapper->payload->addPayload($this->request);
        $wrapperRes = $this->wrapperMethods->postLoanRepayment($this->wrapper);
        if (!$wrapperRes->errorBag)
            return response()->json(['status' => 'OK', 'data' => ['Message' => 'Loan application sent to OneFin']]);

        return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
    }

    public function createMandate()
    {
        $this->wrapper->payload->addPayload($this->request);
        $wrapperRes = $this->wrapperMethods->createMandate($this->wrapper);
        if (!$wrapperRes->errorBag)
            return response()->json(['status' => 'OK', 'data' => ['Message' => 'Loan application sent to OneFin']]);

        return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
    }

    public function loanDisbursal()
    {
        $this->request->merge(['lead_id' => $this->getLeadId()]);
        $this->wrapper->payload->addPayload($this->request);
        $wrapperRes = $this->wrapperMethods->loanDisbursal($this->wrapper);
        if (!$wrapperRes->errorBag)
            return response()->json(['status' => 'OK', 'data' => ['Message' => 'Loan application sent to OneFin']]);

        return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
    }

    public function getRepaymentSchedule()
    {
        $this->request->merge(['lead_id' => $this->getLeadId()]);
        $this->wrapper->payload->addPayload($this->request);
        $wrapperRes = $this->wrapperMethods->getRepaymentSchedule($this->wrapper);
        if (!$wrapperRes->errorBag)
            return response()->json(['status' => 'OK', 'data' => ['Message' => 'Loan application sent to OneFin']]);

        return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
    }

    public function onBoardChannelEntity()
    {
        $application = ConsumerApplication::where('id', $this->request->get('id'))->first(['id', 'merchant_id']);
        if(isset($application->merchant_id)) {
            $merchants = Merchant::whereHas('bank_details');
            if ($this->request->get('id')) {
                $merchants = $merchants->where('id', $application->merchant_id);
            }
            $merchants = $merchants->where('status', 'active')->get(['email', 'address', 'merchant_name', 'id', 'gst_number', 'pan_card', 'official_merchant_name', 'contact_number']);

            foreach ($merchants as $merchant) {
                try {
                    //$payload = new Payload();
                    $emails = explode(',', $merchant->email);
                    $this->request->merge([
                        "email" => $emails[0],
                        "address" => $merchant->address,
                        "merchant_name" => $merchant->merchant_name,
                        "channel_id" => $merchant->id,
                        "gst_number" => strlen($merchant->gst_number) ? $merchant->gst_number : "",
                        "pan_number" => strlen($merchant->pan_card) && $merchant->pan_card ? $merchant->pan_card : "",
                        "official_merchant_name" => $merchant->official_merchant_name,
                        "channel_type" => 9,
                        "mobile_number" => $merchant->contact_number,
                        "master_channel_id" => 0,
                        "ac_number" => $merchant->bank_details->account_number ?? '',
                        "ac_name" => $merchant->bank_details->account_holder ?? '',
                        "account_type" => 1,// PRIMARY = 1 SECONDARY = 2 CLOSED = 3 COLLECTION_ACCOUNT = 4 DISBURSEMENT_ACCOUNT = 5 OTHER_ACCOUNT = 6 CURRENT_ACCOUNT = 7 SAVINGS_ACCOUNT = 8
                        "ifsc_code" => $merchant->bank_details->ifsc_code ?? ''
                    ]);
                    //$payload->addPayload($this->request);
                    //return $payload->onBoardChannelEntity();
                    $this->wrapper->payload->addPayload($this->request);
                    $wrapperRes = $this->wrapperMethods->onBoardChannelEntity($this->wrapper);
                    if (!$wrapperRes->errorBag)
                        return response()->json(['status' => 'OK', 'data' => ['Message' => 'Channel entity onboarded']]);

                    return response()->json(['status' => 'FAIL', 'data' => array_filter($wrapperRes->errorBag)]);
                } catch (\Exception $e) {
                    return response()->json(['status' => 'FAIL', 'data' => ['Message' => 'Exception occured']]);
                }
            }
        }

        return response()->json(['status' => 'FAIL', 'data' => ['Message' => 'Merchant is not active or assigned']]);
    }

    public function updateAPIStatus($service, $success){
        if($success) {
            $status = 'success';
            $message = '';
            if ($success instanceof JsonResponse) {
                $data = $success->getData();
                if ($data->status == 'FAIL') {
                    $message = $data->data;
                    $status = 'error';
                }
            } else if (isset($success->is_success)) {
                $message = ['Message' => $success];
                if (!$success->is_success) {
                    $status = 'error';
                }
            }

            $oneFin = OneFinModel::where('application_id', $this->request->get('id'))->where('service', $service)->first(['id']);
            if (isset($oneFin->id)) {
                $oneFinModel = OneFinModel::find($oneFin->id);
            } else {
                $oneFinModel = new OneFinModel();
                $oneFinModel->application_id = $this->request->get('id');
                $oneFinModel->service = $service;
            }
            $oneFinModel->message = json_encode($message);
            $oneFinModel->status = $status;

            $oneFinModel->save();
        }
    }

    public function getStatus(){

        $this->get_single_config = true;
        if(!$this->getConfig($this->request->get('id'))){
            return false;
        }

        $data = OneFinModel::where('application_id', $this->request->get('id'))->get(['id', 'application_id', 'message', 'status', 'service']);
        if(count($data)) {
            foreach ($data as $item) {
                if (isset($item->service)) {
                    if (in_array($item->service, array_keys($this->apis))) {
                        $this->apis[$item->service] = $item;
                    }
                }
            }
        }

        return $this->apis;
    }

    public static function canSendToOnefin($lender_id, $type){
        if ($lender_id == 2){ //KMGC
            $l_name = 'kmgc';
            $l_type = 'unsec';
            if(in_array($type, [37, 36, 33, 34, 35, 4])){
                $c_type = 'el';
            }elseif(in_array($type, [23, 24, 16, 22, 20,19, 14, 21,25, 51])){
                $c_type = 'pl';
            }
        }else if($lender_id == 3){ //Avanse
            $l_name = 'avanse';
            $l_type = 'unsec';
            $c_type = 'pl';
        }else if($lender_id == 4){ // ABFL
            $l_name = 'abfl';
            $l_type = 'unsec';
            $c_type = 'pl';
        }else if($lender_id == 5){ //LP2P
            $l_name = 'lbp2p';
            $l_type = 'unsec';
            if(in_array($type, [37, 36, 33, 34, 35, 4])){
                $c_type = 'el';
            }elseif(in_array($type, [23, 24, 16, 22, 20,19, 14, 21, 25])){
                $c_type = 'pl';
            }
        }else if($lender_id == 6){ //UGRO

        }else if($lender_id == 7){ //LLSP
            $l_name = 'lblsp';
            $l_type = 'unsec';
            $c_type = 'pl';
        }else if($lender_id == 8){ //INDUSBank

        }else if($lender_id == 9){ //JMFL

        }else if($lender_id == 10){ //SINGUKARITY

        }else if($lender_id == 11){ //KMGCP2P

        }

        return isset($l_name, $l_type, $c_type) ? strtoupper($l_name.'_'.$l_type.'_'.$c_type) : false;
    }

    public function getLeadId(){
        $element = ConsumerApplicationElement::where('application_id', $this->request->get('id'))->first(['onefin_lead_id']);
        if (isset($element->onefin_lead_id)){
            return $element->onefin_lead_id;
        }
        return '';
    }

}