<?php
/**
 * Created by PhpStorm.
 * User: sunil
 * Date: 9/29/18
 * Time: 4:30 PM
 */

namespace App\Console\Commands;


use App\CallLogs;
use App\ConsumerApplication;
use App\Exotel\ExotelServices;
use App\Http\Controllers\Admin\ConsumerApplicationController;
use App\Http\Controllers\Admin\ConsumerDocument;
use App\Http\Controllers\Admin\MerchantController;
use App\Http\Controllers\Admin\UserController;
use App\Leads;
use App\Merchant;
use App\MerchantLocation;
use App\Services;
use App\Slack;
use App\Templates;
use App\User;
use App\UserEmails;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Http\Request;

class EveryFiveMinutes extends Command
{

    protected $signature = 'basic:everyFiveMinutes';

    public function __construct(){

        parent::__construct();
    }

    public function handle(){
        if ($lists = $this->getListsOfCalls()){
            $this->updateCalls($lists);
            $this->missedCalls();
        }

        $this->saveToS3();

        //$this->validateEmails();
        $hour = date('H',time());
        if($hour == 8 || $hour == 14 || $hour == 20){
            $this->scanPort();
        }

    }

    public function missedCalls(){

        $calls = CallLogs::where(function ($query) {
            $query->whereNull('status')->orWhereIn('status', ['failed','completed']);
        })->where('created_at','>=',Carbon::now()->subMinute(40)->toDateTimeString())->where('direction','inbound')->get(['id','sid','status','recording','direction','from','to','purpose']);


        foreach ($calls as $call) {
            if (isset($call->recordingUrl) && $call->direction == 'inbound' && strlen($call->recordingUrl) == 0) {
                $this->sendOnSlack($call);
            }
        }
    }

    public function missedOutboundCalls(){

        $calls = CallLogs::whereIn('status',['no-answer','busy'])->where('missed_call_alert', 0)->where('created_at','>=',Carbon::now()->subMinute(10)->toDateTimeString())->where('direction','outbound-api')->get(['id','_id','sid','status','recording','direction','from','to','purpose','id_type','user_id']);
        //$calls = CallLogs::where('id',789)->get();

        if($calls) {
            foreach ($calls as $call) {
                $user = User::where('id', $call->user_id)->where('user_type', '>=', 5)->first(['id']);
                if (isset($user->id) && !isset($call->recording) && (strlen($call->recording) == 0 || !$call->recording)) {
                    $this->sendMissedCallAlert($call);
                }
            }
        }
    }

    public function sendMissedCallAlert($call){
        try {


            $name = '';
            switch ($call->id_type) {
                case 'application_id':
                    $application = new ConsumerApplicationController();
                    $applicationData = ConsumerApplication::find($call->_id);
                    $lists = $application->getCallerLists($applicationData, '', false, true);
                    foreach ($lists as $list){
                        if($list['phone'] == $call->to){
                            $name = $list['name'];
                            break;
                        }
                    }
                    break;
                case 'lead_id':
                    $nameData = Leads::where('id', $call->_id)->where('contacts', 'like', '%' . $call->to . '%')->first(['contacts']);
                    if (isset($nameData->contacts) && $nameData->contacts) {
                        $contacts = json_decode($nameData->contacts);
                        foreach ($contacts as $contact) {
                            if (isset($contact->phone_of_contact) && $contact->phone_of_contact) {
                                if ($contact->phone_of_contact == $call->to) {
                                    $name = $contact->name_of_contact;
                                }
                            }
                        }
                    }
                    break;
                case 'merchant_id':
                    $application = new MerchantController();
                    $lists = $application->getCallerLists($call);
                    foreach ($lists as $list){
                        if($list['phone'] == $call->to){
                            $name = $list['name'];
                        }
                    }
                    break;
                case 'merchant_location_id':
                    $name = MerchantLocation::where('phone', $call->to)->first(['name']);
                    $name = isset($name->name) ? $name->name : '';
                    break;
                case 'user_id':
                    $name = User::where('mobile_number', $call->to)->first(['name']);
                    $name = isset($name->name) ? $name->name : '';
                    break;
            }

            $message = '';
            $args = [];
            if ($name) {
                $message = "Dear $name,<br/>";
                $args = [$name];
                $message .= "Greetings from Credit Fair! We tried calling you today but couldn't get through. Please reach out to us when you can.<br/> Thank you. <br/> - Credit Fair";
                $entity = ['templateid' => '1307166902829903575', 'entityid' => Templates::$entityid];
                send_sms($call->to, ['message'=>$message, 'templateId' => Templates::$missed_call_c2, 'args' => $args, 'templateDetails' => $entity]);
            }
            CallLogs::where('id', $call->id)->update(['missed_call_alert' => 1]);
        }catch (\Exception $e){

        }
    }

    public function validateEmails(){
        $emails = UserEmails::get(['email'])->where('status',1)->toArray();
        $data = ConsumerApplication::whereNotIn('email',array_map(function ($item){return $item['email'];},$emails))->whereNull('is_deleted')->orderBy('created_at','desc')->limit(10)->get(['email','id']);

        foreach ($data as  $item){
            UserEmails::validates(['emails' => [$item->email],'type' => 'application_id', 'id' => $item->id]);
        }
    }

    public function updateCalls($calls){
        $serviceCount = 0;
        $start_time = time();
        foreach ($calls as $call){
            $exotelServices = new ExotelServices(new Request(['sid' => $call->sid, 'id' => $call->id]));
            $exotelServices->autoInitiateGetCall = true;
            $response = $exotelServices->getCall();
            if ($call->status != $response['Status']){
                $exotelServices->saveRecording($response['response']);
            }
            $serviceCount++;
        }

        (new Services())->log('exotel', ['status' => true, 'service_count' => $serviceCount, 'start_time' => $start_time]);
    }

    public function saveToS3(){
        $recordings = CallLogs::where('status','completed')->where('created_at','<=',Carbon::now()->subMinute(30)->toDateTimeString())->whereNull('s3')->get();

        foreach ($recordings as $recording){
            try{
                if(strlen($recording->recording) > 0) {
                    $location_type = ($recording->id_type == 'application_id' ? '' : ($recording->id_type == 'merchant_id' ? 'merchant' : ($recording->id_type == 'merchant_location_id' ? 'merchant_location' : ($recording->id_type == 'user_id' ? 'user' : 'Unknown'))));
                    $documents = (new ConsumerDocument(new Request()));
                    $documents->is_location_type = $location_type;
                    $documents->dontSaveLocal = 1;
                    $documents->uploadToS3('call_purpose_'.$recording->purpose .'_'. time(), $recording->_id, file_get_contents($recording->recording), '.mp3');
                    CallLogs::where('id',$recording->id)->update(['s3' => 1]);
                }
            }catch (\Exception $e){
                //(new Slack(new Request(['title'=>'Call Logs','fields'=>['error'=>$e->getMessage(),'line'=>$e->getLine(),'trace'=>$e->getTraceAsString(),'application_id'=>$recording->_id,'id_type'=>'application_id']])))->send();
            }
        }
    }

    public function getListsOfCalls(){
        $calls = CallLogs::where(function ($query) {
            $query->whereNull('status')->orWhereIn('status', ['in-progress','ringing','failed']);
        })->where('created_at','>=',Carbon::now()->subDay(1)->startOfDay()->toDateTimeString())->where('created_at','<=',Carbon::now()->subMinute(40)->toDateTimeString())->get(['id','sid','status','recording','direction','from','to','purpose']);

        return $calls;
    }

    public function sendOnSlack($call){
        $response = ['From' => $call->from, 'To' => $call->to, 'Purpose' => $call->purpose];
        (new Slack(new Request(['title'=>'Missed Call Alert','fields'=>$response,'group' => 'businessdevelopment'])))->send();
    }

    public function scanPort(){
        ini_set('max_execution_time', 0);
        ini_set('memory_limit', -1);
        $host = 'creditfair.in';
        $ports = array(21, 25, 80, 81, 110, 143, 443, 587, 2525, 3306);
        $info = [];
        foreach ($ports as $port)
        {
            $connection = @fsockopen($host, $port, $errno, $errstr, 2);
            if (is_resource($connection))
            {
                $info[getservbyport($port, 'tcp')] = 'Port: '.$port. ', Status: Open';
                fclose($connection);
            }
            else
            {
                $info[getservbyport($port, 'tcp')] = 'Port: '.$port. ', Status: Closed';
            }
        }

        if($info)
            (new Slack(new Request(['title'=>'Ports Info','fields'=>$info])))->send();
    }

}