<?php

namespace App;

use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\Http\Controllers\Admin\ConsumerDocument;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Storage;
use App\Slack;
use App\Events\V1\EventVkycApproved;

class HypervergeVideo
{
    private $HYPERVERGE_DOMAIN = null;
    private $endPointDevelopment;
    private $payload;
    private $request;
    private $APP_ID;
    private $APP_KEY;
    private $webhookURL;
    private $videoURL;
    private $agentVideoURL;
    private $error = null;
//    private $videoURL = 'https://india-vcip-prequal-demo.hyperverge.co/';
//    private $videoURL;// = 'https://vcip-prequal.hyperverge.co/';
//    private $agentVideoURL = 'https://india-vcip-admin-demo.hyperverge.co/';
//    private $agentVideoURL;// = 'https://vcip-admin.hyperverge.co/';
//    private $webhookURL;// = 'https://creditfair.in/api/hyperverge/response';
    private $GET_URL = 'getPrequalificationURL';
    private $EVENT_SUBSCRIBE = 'events/subscribe';
    private $Get_Agent_URL = 'getAgentURL';
    private $HYPERVERGE_DOMAIN_A = null;

    public function __construct(Request $request){

        $this->request = $request;
        $this->HYPERVERGE_DOMAIN = (_env('HYPERVERGE_DOMAIN'));
        $this->HYPERVERGE_DOMAIN_A = (_env('HYPERVERGE_DOMAIN_A'));
        $this->APP_ID = (_env('HYPERVERGE_APP_ID'));
        $this->APP_KEY = (_env('HYPERVERGE_APP_KEY'));
        $this->webhookURL = (_env('HYPERVERGE_WEBHOOK_URL'));
        if(!empty($this->request->get('application')->lender_id ) && $this->request->get('application')->lender_id === 3) {
            $this->videoURL = (_env('HYPERVERGE_VIDEO_URL_AV'));
        } else {
            $this->videoURL = (_env('HYPERVERGE_VIDEO_URL_CF'));
        }
        $this->agentVideoURL = (_env('HYPERVERGE_ADMIN_VIDEO_URL'));

        $this->registerWebhook();
    }

    public function getVideoKYCURL($applicant_type = null){

        $userId = $this->request->get('application')->id;
        $co_applicant_link = '';
        $applicant_link = '';
        if($this->request->get('application')->co_applicant_name && $applicant_type == 2){
            $applicant_type = 2;
            $userId .= $applicant_type;
            $panNumber = $this->request->get('application')->co_applicant_pan_card;
            $panDOB = date('d/m/Y',strtotime($this->request->get('application')->co_applicant_dob));
            $panName = $this->request->get('application')->co_applicant_name;

            $this->payload = "{\"userId\":\"$userId\",\"panNumber\":\"$panNumber\",\"panDOB\":\"$panDOB\",\"panName\":\"$panName\"}";

            $this->endPointDevelopment = $this->HYPERVERGE_DOMAIN.$this->GET_URL;
            $resp = $this->getResponse();
            if(false !== $resp) {
                $videoURL = $this->setHypervergeVideoAttribute($resp, 'url_data', $applicant_type);
                $co_applicant_link = $this->videoURL.$videoURL.'/aadhaar';
            }
        }elseif($this->request->get('application')->name && !$applicant_type){
            $applicant_type = 1;
            $userId .= $applicant_type;
            $panNumber = $this->request->get('application')->pan_card;
            $panDOB = date('d/m/Y',strtotime($this->request->get('application')->dob));
            $panName = $this->request->get('application')->name;

            $this->payload = "{\"userId\":\"$userId\",\"panNumber\":\"$panNumber\",\"panDOB\":\"$panDOB\",\"panName\":\"$panName\"}";

            $this->endPointDevelopment = $this->HYPERVERGE_DOMAIN.$this->GET_URL;
            $resp = $this->getResponse();
            if(false !== $resp) {
                $videoURL = $this->setHypervergeVideoAttribute($resp, 'url_data', $applicant_type);
                $applicant_link = $this->videoURL.$videoURL.'/aadhaar';
            }
        }

        if (!$co_applicant_link){
            $hypervergeVideoAttribute = HypervergeVideoAttribute::with('webhook')->where('application_id', $this->request->get('application')->id)->where('applicant_type',2)->first(['id','url_data','agent_url_data','webhook']);
            if (isset($hypervergeVideoAttribute->id) && !$hypervergeVideoAttribute->webhook){
                $url_data = json_decode($hypervergeVideoAttribute->url_data);
                $videoURL = isset($url_data->status) && $url_data->status == 'success' ? $url_data->url : '';
                if($videoURL) {
                    $co_applicant_link = $this->videoURL . $videoURL.'/aadhaar';
                }
            }
        }

        //$agent_link = $this->generateAgentURL();
        return [
            'customer_link' => Shortio::getUrl($applicant_link),//$applicant_link
            'co_customer_link' => Shortio::getUrl($co_applicant_link),//$co_applicant_link,
            'agent_link' => $this->agentVideoURL,
        ];
    }

    private function generateAgentURL(){
        $userId = $this->request->get('application')->id;
        $this->payload = $this->payload = "{\"userId\":\"$userId\"}";
        $this->endPointDevelopment = $this->HYPERVERGE_DOMAIN_A.$this->Get_Agent_URL;
        $resp = $this->getResponse();
        $videoURL = '';
        if (false !== $resp) {
            $videoURL = $this->setHypervergeVideoAttribute($resp, 'agent_url_data');
        }
        return $this->agentVideoURL.'/'.$videoURL;
    }

    public function setHypervergeVideoAttribute($response, $type, $applicant_type = null){
        //(new Slack(new Request(['title'=>'HyperV Response1', 'fields'=>['data' => json_encode($response) ,'type' => json_encode($type)]])))->send();
        if($this->request->has('application') && isset($this->request->get('application')->id)) {

            $HypervergeVideoAttribute = HypervergeVideoAttribute::where('application_id', $this->request->get('application')->id)->where('applicant_type', $applicant_type)->first(['id']);

            if (!isset($HypervergeVideoAttribute->id)) {
                HypervergeVideoAttribute::insert(
                    [
                        'application_id' => $this->request->get('application')->id,
                        $type => json_encode($response),
                        'applicant_type' => $applicant_type,
                        'created_at' => Carbon::now()->toDateTimeString()
                    ]
                );
            } else {
                HypervergeVideoAttribute::where('id', $HypervergeVideoAttribute->id)->where('applicant_type', $applicant_type)->update(
                    [
                        $type => json_encode($response),
                    ]
                );
            }
            return (!empty($response['status']) && $response['status'] == 'success') ? $response['url'] : '';
        } elseif($type == 'webhook') {
            //\Log::info($response);
            //(new Slack(new Request(['title'=>'HyperV Response2', 'fields'=>['data' => json_encode($response)]])))->send();
            if(1 == _env("HYPERVERGE_LOG_WEBHOOK_RESPONSE")) {
                $this->writeLogs($response);
            }
            $application_id = !empty($response['user_id']) ? $response['user_id'] : '';
            $data = $application_id;
            $application_id = substr($data, 0, -1);
            $applicant_type = substr($data, -1);

            if($application_id) {
                $HypervergeVideoAttribute = HypervergeVideoAttribute::where('application_id', $application_id)->where('applicant_type', $applicant_type)->first(['id']);
                if (isset($HypervergeVideoAttribute->id)) {
                    // for summary event only
                    $logs['user_id'] = $application_id;
                    if (!empty($response['event_type']) && $response['event_type'] === 'vcip_summary') {
                        $approved = false;
                        foreach($response['event_details']['summary'] as $event => $ed) {
                            $hvhObj = new HypervergeWebhook();
                            $hvhObj->hyper_id = $HypervergeVideoAttribute->id;
                            $hvhObj->applicant_type = $applicant_type;
                            $hvhObj->created_at = Carbon::now()->toDateTimeString();
                            $hvhObj->data = (!empty($ed['event_details'])) ? json_encode($ed['event_details']) : '';
                            $hvhObj->timestamp = !empty($ed['timestamp']) ? $ed['timestamp'] : '';
                            $hvhObj->event_type = $event;
                            $hvhObj->application_id = $application_id;
                            $logs[$event]['timestamp'] = date('d M Y h:i A', floor($ed['timestamp'] / 1000));
                            $logs[$event]['event_details'] = $ed['event_details'];
                            switch($event) {
                                //Sequence of cases is as per events happen in reality. So don't change the sequence of cases
                                case 'prequalification_aadhaar_xml':
                                    $dt = $ed['event_details'];
                                    if (!empty($dt['result']['details']['photo']['value'])) {
                                        // upload to S3 bucket
                                        (new ConsumerDocument(new Request()))->uploadToS3('vkyc_aadhaar_image'.$application_id.'_'.$applicant_type, $application_id, base64_decode($dt['result']['details']['photo']['value']),'.jpeg');
                                        unset($dt['result']['details']['photo']['value']);
                                    }
                                    $hvhObj->data = json_encode($dt);
                                    break;
                                case 'vcip_sms_agent_fetch':
                                case 'vcip_location_captured':
                                case 'vcip_agent_connected':
                                case 'vcip_send_sms':
                                case 'vcip_user_connected':
                                case 'vcip_otp_verification':
                                    break;
                                case 'vcip_pan_captured':
                                    $dt = $ed['event_details'];
                                    if (!empty($dt['image'])) {
                                        // upload to S3 bucket
                                        (new ConsumerDocument(new Request()))->uploadToS3('vkyc_pancard_image_'.$application_id.'_'.$applicant_type, $application_id, base64_decode($dt['image']),'.jpeg');
                                        unset($dt['image']);
                                    }
                                    $hvhObj->data = json_encode($dt);
                                    break;
                                case 'vcip_panocr_result':
                                    $dt = $ed['event_details'];
                                    if (!empty($dt['panOcrResult']['result'][0]['details']['base64Image'])) {
                                        // upload to S3 bucket
                                        (new ConsumerDocument(new Request()))->uploadToS3('vkyc_panocr_image'.$application_id.'_'.$applicant_type, $application_id, base64_decode($dt['panOcrResult']['result'][0]['details']['base64Image']),'.jpeg');
                                        unset($dt['panOcrResult']['result'][0]['details']['base64Image']);
                                    }
                                    $hvhObj->data = json_encode($dt);
                                    break;
                                case 'vcip_namematch_result':
                                case 'vcip_pan_ocr_verification':
                                    break;
                                case 'vcip_image_captured':
                                    $hvhObj->data = '';
                                    // check if image is available or not
                                    if (!empty($ed['event_details']['image'])) {
                                        // upload to S3 bucket
                                        //(new ConsumerDocument(new Request()))->uploadToS3('vkyc_user_image_'.$application_id.'_'.$applicant_type, $application_id, base64_decode($ed['event_details']['image'], '.jpeg'));
                                        (new ConsumerDocument(new Request()))->uploadToS3('CUSTPHOTO', $application_id, base64_decode($ed['event_details']['image'], '.jpeg'));
                                    }
                                    break;
                                case 'vcip_liveness_result':
                                    $dt = $ed['event_details'];
                                    if (!empty($dt['image'])) {
                                        // upload to S3 bucket
                                        (new ConsumerDocument(new Request()))->uploadToS3('vkyc_liveness_result_'.$application_id.'_'.$applicant_type, $application_id, base64_decode($dt['image']),'.jpeg');
                                        unset($dt['image']);
                                    }
                                    $hvhObj->data = json_encode($dt);
                                    break;
                                case 'vcip_facematch_result':
                                  break;
                                case 'vcip_pan_facematch_result':
                                    $dt = $ed['event_details'];
                                    if (!empty($dt['image'])) {
                                        // upload to S3 bucket
                                        (new ConsumerDocument(new Request()))->uploadToS3('vkyc_pan_facematch_result_'.$application_id.'_'.$applicant_type, $application_id, base64_decode($dt['image']),'.jpeg');
                                        unset($dt['image']);
                                    }
                                    $hvhObj->data = json_encode($dt);
                                    break;
                                case 'vcip_aadhaar_facematch_result':
                                    $dt = $ed['event_details'];
                                    if (!empty($dt['image'])) {
                                        // upload to S3 bucket
                                        (new ConsumerDocument(new Request()))->uploadToS3('vkyc_aadhaar_facematch_result_'.$application_id.'_'.$applicant_type, $application_id, base64_decode($dt['image']),'.jpeg');
                                        unset($dt['image']);
                                    }
                                    $hvhObj->data = json_encode($dt);
                                    break;
                                case 'vcip_name_match_result':
                                case 'vcip_face_verification':
                                    break;
                                case 'vcip_video_recording':
                                    //$hvhObj->data = '';

                                    if (isset($ed['event_details']['url']) && $ed['event_details']['url']){
                                        (new ConsumerDocument(new Request()))->uploadToS3('vkyc_video_'.$application_id.'_'.$applicant_type, $application_id, file_get_contents($ed['event_details']['url']),'.webm');
                                    }else if(isset($ed['event_details']) && isset($ed['event_details']->url)){
                                        (new ConsumerDocument(new Request()))->uploadToS3('vkyc_video_'.$application_id.'_'.$applicant_type, $application_id, file_get_contents($ed['event_details']->url),'.webm');
                                    }else if (isset($ed->event_details->url) && $ed->event_details->url){
                                        (new ConsumerDocument(new Request()))->uploadToS3('vkyc_video_'.$application_id.'_'.$applicant_type, $application_id, file_get_contents($ed->event_details->url),'.webm');
                                    }

                                    if (!empty($ed['event_details']['url'])) {
                                        /*$handle = @fopen($ed['event_details']['url'], 'r+');
                                        if($handle) {
                                            $destinationPath = storage_path('app') . '/vkyc_'.time().'.webm';
                                            while (!feof($handle)) {
                                              file_put_contents(
                                                  $destinationPath,
                                                  fread($handle, 1024),
                                                  FILE_APPEND
                                              );
                                            }
                                            fclose($handle);
                                            if(file_exists($destinationPath)) {
                                              $targetFile = '/'.$application_id.'/vkyc_video_'.$application_id.'_'.$applicant_type.'.webm';
                                              $disk = Storage::disk('s3');
                                              $disk->put($targetFile, $destinationPath);
                                              $data1['file_type'] = 'vkyc_video';
                                              $data1['id'] = $application_id;
                                              $data1['applicant_type'] = $applicant_type;
                                              (new ConsumerApplicationController())->getUploadedFileNameMultiple($disk, $targetFile, $data, false);
                                              unlink($destinationPath);
                                            }

                                        }*/

                                    }
                                    break;
                                case 'vcip_kyc_status':
                                    if (!empty($ed['event_details']['status']) && strtolower($ed['event_details']['status']) === 'approved') {
                                        $approved = true;
                                    }
                                    break;
                                case 'vcip_user_disconnected':
                                    break;
                                default:
                            }
                            $hvhObj->save();

                        }
                        $applicant_type = ($applicant_type == 1) ? 'applicant' : 'co_applicant';
                        //return $logs;
                        $view = view('front.hyperV-report', ['data' => $logs]);
                        //return $view;
                        $pdf = App::make('snappy.pdf.wrapper');
                        $report = $pdf->loadHTML($view)->setOption('encoding', 'UTF-8')->setPaper('a4')->setOrientation('portrait');
                        (new ConsumerDocument(new Request()))->uploadToS3('hyperV_report_'.$applicant_type, $application_id, $report->output());
                        $appObj = ConsumerApplication::find($application_id);
                        if (!empty($appObj->lender_id) && $appObj->lender_id == ConsumerApplication::AVANSE_LENDER_ID) {
                          event(new EventVkycApproved($application_id));
                            //(new ConsumerApplicationController())->rabbitMQQueue();
                        }
                        unset($appObj);
                    }
                }
            }
        }

    }

    public function registerWebhook(){
        //this->payload = '{\"webhookUrl\":\"'.$this->webhookURL.'\",\"emailId\":\"devteam@creditfair.in.in\",\"events\":{\"vcip_sms_customer_scheduled\":true,\"vcip_send_sms\":true,\"vcip_kyc_status\":true,\"vcip_review_kyc_status\":true,\"vcip_summary\":true,\"vcip_sms_agent_scheduled\":true,\"vcip_sms_agent_cancel\":true,\"vcip_agent_connected\":true,\"vcip_user_connected\":true,\"vcip_location_captured\":true,\"vcip_image_captured\":true,\"vcip_pan_captured\":true,\"vcip_panocr_result\":true,\"vcip_liveness_result\":true,\"vcip_agent_disconnected\":true,\"vcip_user_disconnected\":true,\"vcip_otp_verification\": true,\"vcip_pan_ocr_verification\": true,\"vcip_video_recording\": true}}';

        $this->payload = json_encode([
          "webhookUrl" => $this->webhookURL,
          "emailId" => "devteam@creditfair.in",
          "events" => [
            "vcip_summary" => true
          ]
        ]);
        $this->endPointDevelopment = $this->HYPERVERGE_DOMAIN_A.$this->EVENT_SUBSCRIBE;
        return $this->getResponse();
    }

    public function getRequestedAttributes(){
        if($this->request->has('application') && isset($this->request->get('application')->id)) {
            $data = [];
            $hypervergeVideoAttribute = HypervergeVideoAttribute::with('webhook')->where('application_id', $this->request->get('application')->id)->where('applicant_type',1)->first(['id','url_data','agent_url_data','webhook']);
            if (isset($hypervergeVideoAttribute->id) && !$hypervergeVideoAttribute->webhook){
                $url_data = json_decode($hypervergeVideoAttribute->url_data);
                $videoURL = isset($url_data->status) && $url_data->status == 'success' ? $url_data->url : '';
                if($videoURL) {
                    $data =  [
                        'customer_link' => Shortio::getUrl($this->videoURL . $videoURL.'/aadhaar'),
                        'agent_link' => $this->agentVideoURL,
                    ];
                }
            }

            if($this->request->has('application') && isset($this->request->get('application')->co_applicant_name)) {
                $hypervergeVideoAttribute = HypervergeVideoAttribute::with('webhook')->where('application_id', $this->request->get('application')->id)->where('applicant_type',2)->first(['id','url_data','agent_url_data','webhook']);
                if (!isset($hypervergeVideoAttribute->id)){
                    $this->getVideoKYCURL(2);
                }else{
                    if (isset($hypervergeVideoAttribute->id) && !$hypervergeVideoAttribute->webhook) {
                        $url_data = json_decode($hypervergeVideoAttribute->url_data);
                        $videoURL = isset($url_data->status) && $url_data->status == 'success' ? $url_data->url : '';
                        $data['co_customer_link'] = $this->videoURL . $videoURL.'/aadhaar';//Shortio::getUrl($this->videoURL . $videoURL.'/aadhaar');
                    }
                }
            }
            return !empty($data) ? $data : false;
        }

        return false;
    }

    private function getResponse(){

        $curl = curl_init();
        // return $this->endPointDevelopment;
        // return $this->payload;
        curl_setopt_array($curl, array(
            CURLOPT_URL => $this->endPointDevelopment,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => $this->payload,
            CURLOPT_HTTPHEADER => array(
                "Content-Type: application/json",
                "appId: ".$this->APP_ID,
                "appKey: ".$this->APP_KEY,
                "cache-control: no-cache"
            ),
        ));

        $response = curl_exec($curl);
        $err = curl_error($curl);
        curl_close($curl);
        if ($err) {
            (new Slack(new Request(['title'=>"Issue in hyperverge API", 'fields'=>['Message' => $err]])))->send();
            return false;
        } else {
            return json_decode($response, 1);
        }
    }

    private function writeLogs($log) {
        $fileName = 'hyperverge_'.time().'.json';
        Storage::disk('storage')->put($fileName, json_encode($log));
    }
}
