<?php /** @noinspection PhpPossiblePolymorphicInvocationInspection */

namespace App\Opt;


use App\CompanyTrialMode;
use App\SocialMediaCredit;
use App\SocialPaymentHistory;
use App\User;
use App\UserPost;
use App\UserSocial;
use Carbon\Carbon;
use Facebook\Facebook;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Abraham\TwitterOAuth\TwitterOAuth;
use Illuminate\Support\Str;
use function GuzzleHttp\Promise\all;


trait   Media
{

    public function index()
    {
        $user = auth()->user();

        if(!$user->SocialSubscriptionIsValid())  //if the user does have any package yet
        {
            //if the user is not a direct client
            if($user->under_reseller())
                return  redirect(url()->previous())
                    ->withErrors('Kindly contact your account administrator for social media package !!');
            else
                return  redirect()->route('social.subscription.index')
                    ->withErrors('Kindly subscribe to a package  !!');
        }


        $appId = '576850202828274';
        $appSecret = 'de165a551dde984fc98ebf16f0c2acf1';


        $fb = new Facebook([
            'app_id' => $appId,
            'app_secret' => $appSecret,
            'default_graph_version' => 'v3.2'
        ]);

        $helper = $fb->getRedirectLoginHelper();

        $permissions = ['email','manage_pages', 'publish_pages']; // Optional permissions
        $callback = route('social.facebook');
        $loginUrl = $helper->getLoginUrl($callback, $permissions);
        $route = $loginUrl;


        return view('social.account.index',['fb_route'=>$route]);
    }

    public function pages_fb(){
        $user = Auth::user();


        $facebook_accesstoken = UserSocial::query()->where('user_id','=', Auth()->user()->id)->select('fb_user_access')->first();

        return view('social.select_fb_pages',
            [
                'facebook_access_token' => $facebook_accesstoken
            ]
        );
    }

    public function dashboard_fb()
    {
        $user = Auth::user();

        if(empty($user->company->id))
            return redirect()->back()->withErrors('You have to be registered as a company before proceeding');

        $trial  = @$user->company->trial()->where('trial',1)->first();

        $linkedIn = $user->posts()->where('channel','linkedIn')->get();
        $twitter  = $user->posts()->where('channel','twitter')->get();
        $facebook = $user->posts()->where('channel','facebook')->get();


        $expiry = $user->social_subscription()->where('is_paid',1)->first();
        $daily  = $user->posts()->whereDate('created_at',now())->first();
        $can_post = $user->company->canPost();

        $facebook_accesstoken = UserSocial::query()->where('user_id','=', Auth()->user()->id)->select('fb_user_access')->first();

        return view('social.facebook',
            [
                'valsLK' => $linkedIn,
                'valsTW' => $twitter,
                'valsFB' => $facebook,
                'can_post'=>$can_post,
                'trial'  => $trial,
                'expiry' => $expiry,
                'daily'  => $daily,
                'facebook_access_token' => $facebook_accesstoken
            ]
        );
    }

    public function dashboard_ig()
    {
        $user = Auth::user();

        if(empty($user->company->id))
            return redirect()->back()->withErrors('You have to be registered as a company before proceeding');

        $trial  = @$user->company->trial()->where('trial',1)->first();

        $linkedIn = $user->posts()->where('channel','linkedIn')->get();
        $twitter  = $user->posts()->where('channel','twitter')->get();
        $facebook = $user->posts()->where('channel','facebook')->get();


        $expiry = $user->social_subscription()->where('is_paid',1)->first();
        $daily  = $user->posts()->whereDate('created_at',now())->first();
        $can_post = $user->company->canPost();



        return view('social.instagram',[
            'valsLK' => $linkedIn,
            'valsTW' => $twitter,
            'valsFB' => $facebook,
            'trial'  => $trial,
            'expiry' => $expiry,
            'daily'  => $daily,
            'can_post' => $can_post,

        ]);

    }

    public function dashboard_twitter()
    {
        $user = Auth::user();

        if(empty($user->company->id))
            return redirect()->back()->withErrors('You have to be registered as a company before proceeding');

        $trial  = @$user->company->trial()->where('trial',1)->first();

        $linkedIn = $user->posts()->where('channel','linkedIn')->get();
        $twitter  = $user->posts()->where('channel','twitter')->get();
        $facebook = $user->posts()->where('channel','facebook')->get();


        $expiry = $user->social_subscription()->where('is_paid',1)->first();
        $daily  = $user->posts()->whereDate('created_at',now())->first();
        $can_post = $user->company->canPost();

        $twitter_accesstoken = UserSocial::query()->where('user_id','=', Auth()->user()->id)->select('twitter_access_token')->first();
        $twitter_access_secret = UserSocial::query()->where('user_id','=', Auth()->user()->id)->select('twitter_token_secret')->first();

        return view('social.twitter',[
            'valsLK' => $linkedIn,
            'valsTW' => $twitter,
            'valsFB' => $facebook,
            'trial'  => $trial,
            'expiry' => $expiry,
            'daily'  => $daily,
            'can_post' => $can_post,
            'twitter_accesstoken' => $twitter_accesstoken,
            'twitter_access_secret' => $twitter_access_secret
        ]);

    }

    public function pages_lk(){
        $user = Auth::user();

        $linkedin_access_token = UserSocial::query()->where('user_id','=', Auth()->user()->id)->select('linkedin_access_token')->first();

        return view('social.select_lk_pages',
            [
                'linkedin_access_token'=> $linkedin_access_token
            ]
        );
    }

    public function dashboard_linked()
    {
        $user = Auth::user();

        if(empty($user->company->id))
            return redirect()->back()->withErrors('You have to be registered as a company before proceeding');

        $trial  = @$user->company->trial()->where('trial',1)->first();

        $linkedIn = $user->posts()->where('channel','linkedIn')->get();
        $twitter  = $user->posts()->where('channel','twitter')->get();
        $facebook = $user->posts()->where('channel','facebook')->get();


        $expiry = $user->social_subscription()->where('is_paid',1)->first();
        $daily  = $user->posts()->whereDate('created_at',now())->first();
        $can_post = $user->company->canPost();

        $linkedin_access_token = UserSocial::query()->where('user_id','=', Auth()->user()->id)->select('linkedin_access_token')->first();


        return view('social.linked_in',[
            'valsLK' => $linkedIn,
            'valsTW' => $twitter,
            'valsFB' => $facebook,
            'can_post' => $can_post,
            'trial'  => $trial,
            'expiry' => $expiry,
            'daily'  => $daily,
            'linkedin_access_token'=> $linkedin_access_token
        ]);
    }

     public function message(Request $request)
    {
        $user = Auth::user();
        if(empty($user->company->id))
            return redirect()->back()->withErrors('You have to be registered as a company before proceeding');

        $trial  = $user->company->trial()->where('trial',1)->first();

        /** if user is still on trial mode  then check if it hasn't expired. if.. then redirect **/
        if(!empty($trial)):
            $endDate = Carbon::parse($trial->created_at)->addDays(7);
            if(now() > $endDate)
                return redirect()->back()
                    ->withErrors('Your trial period has expired please make payment');
        endif;

        $permit = $this->permit(now(),$trial,$user);

//        if($permit)
//            return redirect()->route('social.index')
//                ->withErrors('Please make payment before posting');


        if(!$user->SocialSubscriptionIsValid())  //if the user does have any package yet
            if($user->under_reseller())   //if the user is not a direct client
                 return  redirect()->back()
                     ->withErrors('Kindly contact your account administrator for social media package !!');
            else
                return  redirect()->route('social.subscription.index')
                    ->withErrors('Kindly subscribe to a package  !!');



         /** if user has exhausted available post for the month  **/
        if($user->SocialSubscriptionLimits()->no_of_post <= $user->postBalance())
            if($user->under_reseller())   //if the user is not a direct client
                return  redirect()->back()
                    ->withErrors('You have exhausted your number of posts for this month Kindly contact your account administrator !!');
            else
                return  redirect()->route('social.subscription.index')
                    ->withErrors('You have exhausted your number of posts for this month Kindly subscribe to a package  !!');




        if($request->isMethod('post')):

            $this->validate($request,
                [
                    'channel'=>'required',
                    'media' => 'sometimes|nullable|mimes:jpg,jpeg,png|max:1000',
                    'message'=>'required|max:300'
                ]
            );



            $content = $request->all();

            if(!empty(Auth::user()->social()->first()->id)):  // ? has successfully setup one or more accounts

                if(in_array('linkedin',$content['channel'])):
                    $this->postToLinkedIn($request);
                endif;

                if(in_array('twitter',$content['channel'])):
                    $this->letsTweet($request);
                endif;

                if(in_array('facebook',$content['channel'])):
                    $this->letsFacebook($request);
                endif;


            endif;

            return redirect()->back()->with('success','Posting completed successfully');
        endif;

        $expiry = $user->social_subscription()->where('is_paid',1)->first();

        return view('social.message',[
            'expiry' => $expiry,
            'trial'  => $trial,
        ]);

    }

    private function postToLinkedIn(Request $request)
    {
//        $this->postToDb($request,'linkedin');
        $linked_id = Auth::user()->social()->first()->linkedin_person_id;
        $access_token = Auth::user()->social()->first()->linkedin_access_token;
        foreach ($request->input('l_acct') as $page_id):

            if($request->hasFile('media')):

                $this->processImageForLinkedIn($page_id,$access_token,$request);

            else:

                $jsonPost  = '{
                    "author" : "'.$page_id.'",
                    "lifecycleState" : "PUBLISHED",
                    "specificContent" : {
                        "com.linkedin.ugc.ShareContent" : {
                            "shareCommentary" : {
                                "text" : "'.$request->input('message').'"
                            },
                            "shareMediaCategory" : "NONE"
                        }
                    },
                    "visibility" : {
                        "com.linkedin.ugc.MemberNetworkVisibility" : "PUBLIC"
                    }
                }';

                $endpoint = 'https://api.linkedin.com/v2/ugcPosts';
                try {

                    $headers = array('Content-Type: application/json','X-Restli-Protocol-Version: 2.0.0','x-li-format: json','Authorization: Bearer '.$access_token);

                    $curl = curl_init();
                    curl_setopt($curl, CURLOPT_URL, $endpoint);
                    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
                    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
                    curl_setopt($curl, CURLOPT_POSTFIELDS, $jsonPost);
                    curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
                    $result = curl_exec($curl);


                } catch (\Exception $e) {
                    file_put_contents(public_path('Posts/linkedIn.log'),"{$e->getMessage()} \n",FILE_APPEND);
                }
            endif;
                endforeach;
    }

    private function processImageForLinkedIn($page_id,$access_token,$request)
    {
        $register = '{
                "registerUploadRequest": {
                    "recipes": [
                        "urn:li:digitalmediaRecipe:feedshare-image"
                    ],
                    "owner": "'.$page_id.'",
                    "serviceRelationships": [
                        {
                            "relationshipType": "OWNER",
                            "identifier": "urn:li:userGeneratedContent"
                        }
                    ]
                }
            }';

        $endpoint = 'https://api.linkedin.com/v2/assets?action=registerUpload';
        $headers = array('Content-Type: application/json','X-Restli-Protocol-Version: 2.0.0','x-li-format: json','Authorization: Bearer '.$access_token);
        try{

            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $endpoint);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST');
            curl_setopt($curl, CURLOPT_POSTFIELDS, $register);
            curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
            $output = curl_exec($curl);
            $output = str_replace('com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest','com_linkedin_digitalmedia_uploading_MediaUploadHttpRequest',$output);
            $result = json_decode($output);

            $uploadUrl = $result->value->uploadMechanism->com_linkedin_digitalmedia_uploading_MediaUploadHttpRequest->uploadUrl;
            $asset    = $result->value->asset;

            if(!empty($uploadUrl) && !empty($asset)):

                $res = shell_exec("curl -i --upload-file  $request->media --header 'Authorization: Bearer $access_token' '$uploadUrl'");
                file_put_contents(public_path('Posts/image-upload.log'),"{$res} \n",FILE_APPEND);

                $jsonPost = '{
                "author": "'.$page_id.'",
                "lifecycleState": "PUBLISHED",
                "specificContent": {
                    "com.linkedin.ugc.ShareContent": {
                        "shareCommentary": {
                            "text": "'.$request->input('message').'"
                        },
                        "shareMediaCategory": "IMAGE",
                        "media": [
                            {
                                "status": "READY",
                                "description": {
                                    "text": "'.$request->input('message').'"
                                },
                                "media": "'.$asset.'",
                                "title": {
                                     "text": "'.$request->input('message').'"
                                }
                            }
                        ]
                    }
                },
                "visibility": {
                    "com.linkedin.ugc.MemberNetworkVisibility": "PUBLIC"
                }
            }';


                $endpoint3 = 'https://api.linkedin.com/v2/ugcPosts';
                $curl3 = curl_init();
                curl_setopt($curl3, CURLOPT_URL, $endpoint3);
                curl_setopt($curl3, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($curl3, CURLOPT_CUSTOMREQUEST, 'POST');
                curl_setopt($curl3, CURLOPT_HTTPHEADER, $headers);
                curl_setopt($curl3, CURLOPT_POSTFIELDS, $jsonPost);
                $output2 = curl_exec($curl3);

            endif;


        }catch (\Exception $ex){
            file_put_contents(public_path('Posts/multiple-linkedIn.log'),"{$ex->getMessage()} \n",FILE_APPEND);
        }

    }

    private function letsTweet(Request $request)
    {

        $this->postToDb($request,'twitter');

        $oauth_token = Auth::user()->social()->first()->twitter_access_token;
        $oauth_token_secret = Auth::user()->social()->first()->twitter_token_secret;
        $tweet =  new TwitterOAuth($this->consumerKey, $this->consumer_secrete,$oauth_token,$oauth_token_secret);
        $tweet->setTimeouts(10, 15);
        /** @noinspection PhpUndefinedFieldInspection **/
        $tweet->ssl_verifypeer = true;
        try{
            if($request->hasFile('media')):

                $media = $tweet->upload('media/upload', ['media' => $request->media]);
                $parameters = [
                    'status' => $request->input('message'),
                    'media_ids' => $media->media_id_string
                ];

                $tweet->post('statuses/update', $parameters);

            else:
                $tweet->post('statuses/update', array('status' => $request->input('message')));
            endif;
        }catch (\Exception $ex){
            file_put_contents(storage_path('Posts/twitter.log'),"{$ex->getMessage()} \n",FILE_APPEND);
        }


    }

    private function letsFacebook(Request $request)
    {
        $posts = $request->all();


        $this->postToDb($request,'facebook');


        $appId = '576850202828274';
        $appSecret = 'de165a551dde984fc98ebf16f0c2acf1';



        $fb = new Facebook([
            'app_id' => $appId,
            'app_secret' => $appSecret,
            'default_graph_version' => 'v3.2',
        ]);

        foreach ($posts['f_acct'] as $accessoken):

            $fb->setDefaultAccessToken($accessoken);
            $statusUpdate =[
                'message'=> $request->input('message')
            ];

            $requestUserEvents = $fb->request('POST',"me/feed",$statusUpdate);

            if($request->hasFile('media')):

                $statusUpdate =[
                    'message' => $request->input('message'),
                    'source'  => $fb->fileToUpload($request->media),
                ];

                $requestUserEvents =  $fb->request('POST', '/me/photos', $statusUpdate);

            endif;

            $batch = [
                'user-feed' => $requestUserEvents,
            ];

            try {
                $responses = $fb->sendBatchRequest($batch);

                $post = Auth::user()->posts()->where('channel','facebook')->latest()->first();

                foreach ($responses as $key => $response) {
                    $statusCode =$response->gethttpStatusCode();

                    $statusCode == 200 ? $post->update(['status' => 'success']) :$post->update(['status' => 'failed']);

                }


            } catch(Facebook\Exceptions\FacebookResponseException $e) {
                file_put_contents(public_path('Posts/facebook.log'),"{$e->getMessage()} \n",FILE_APPEND);

            } catch(Facebook\Exceptions\FacebookSDKException $e) {
                file_put_contents(public_path('Posts/facebook.log'),"{$e->getMessage()} \n",FILE_APPEND);
            }

        endforeach;

    }

    private function postToDb(Request $request,$channel)
    {
        if($request->hasFile('media')):
            $file = $request->media;
            $name = date('h:i:s') . '' . $file->getClientOriginalName();
            $file->storePubliclyAs("public/social_media/{$channel}",$name);
        endif;

        $data['channel'] = $channel;
        $data['message'] = $request->input('message');
        $data['media'] = $name ?? null;
        $data['user_id'] = Auth::user()->id;
        $data['name'] = Auth::user()->social()->first()->handle_name($channel);

        UserPost::query()->create($data);

    }

    public function ajax_facebook(array $data)
    {

        $data['user_id'] = Auth::user()->id;

        try {
            $verify = UserSocial::query()->where('user_id',$data['user_id'])->get();
            count($verify) > 0 ?  $verify->each(function ($t) use (&$data){ $t->update($data); }) : UserSocial::query()->create($data);
        }catch (\Exception $spa)
        {
            file_put_contents(public_path('facebook.log'),"{$spa->getMessage()} \n",FILE_APPEND);
        }

    }

    public function ajax_linkedIn(array $data)
    {

        try {
            $verify = UserSocial::query()->where('user_id',$data['user_id'])->get();
            count($verify) > 0 ?  $verify->each(function ($t) use (&$data){ $t->update($data); }) : UserSocial::query()->create($data);
        }catch (\Exception $spa)
        {
            file_put_contents(public_path('linkedIn.log'),"{$spa->getMessage()} \n",FILE_APPEND);
        }

    }

    public function ajax_twitter(array $extra_info)
    {

        $data['user_id'] = Auth::user()->id;
        $data['twitter_access_token'] = $extra_info['oauth_token'];
        $data['twitter_token_secret'] = $extra_info['oauth_token_secret'];
        $data['twitter_name']         = $extra_info['screen_name'];

        try {

            $verify = UserSocial::query()->where('user_id',$data['user_id'])->get();
            count($verify) > 0 ?  $verify->each(function ($t) use (&$data){ $t->update($data); }) : UserSocial::query()->create($data);

        }catch (\Exception $spa){
            file_put_contents(public_path('twitter.log'),"{$spa->getMessage()} \n",FILE_APPEND);
        }
    }

    private function permit($now,$trial,$user)
    {
        if(empty($trial)):  //skip the check if user is  on trial mode
            if($now > @$user->social_subscription->expires_on)
                return true;
        endif;
        return false;

    }

    public function payment(Request $request)
    {
        $data = $request->all();
        $data['user_id']          =  $data['uid'];
        $data['username']         =  $data['uname'];
        $data['mm_number']        =  $data['msisdn'];
        $data['callback']         =  route('media.payment.callback');
        $data['p_status']         = 'pending';
        $data['res_mes']          = 'pending';
        $data['expiry_date']      = Carbon::parse(now())->addDays(30);
        $data['trans_id']         = $data['user_id'].'_'.Str::random('20');

        $data = (object)$data;
       return $this->SocialPaymentCurl($data);
    }

    public function SocialPaymentCurl($params)
    {

      $credit =  SocialMediaCredit::query()->updateOrCreate(
            ['user_id'=>$params->user_id],
            (array)$params
        );

        $history = SocialPaymentHistory::query()->create((array)$params);

        $paymentEndpoint = "https://pay.npontu.com/api/pay";

        $request = array(
            'number' => $params->msisdn,
            'vendor' => $params->network,
            'uid' => 'npdeywuro',
            'pass' => 'hdgt2314',
            'tp' => $params->trans_id,
            'cbk' => $params->callback,
            'amt' => $params->amount,
            'msg' => 'DEYWURO SM-SA PAYMENT',
            'vou' => $params->voucher_number,
            'trans_type' => 'Debit'
        );
        $ch = curl_init($paymentEndpoint);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        return curl_exec($ch);
    }

    public function paymentCallback(Request $request, SocialPaymentHistory $socialPaymentHistory)
    {
        $data = json_encode($request->all());
        file_put_contents(public_path('socialPayment.log'),"{$data} \n",FILE_APPEND);

        $api_update = $socialPaymentHistory::query()->where('trans_id', $request->transaction_id)->first();
        $api_update->res_mes = $request->responseMessage;
        $api_update->p_status = $request->status;
        $api_update->save();


        try{
            $find = SocialMediaCredit::query()->where('trans_id',$request->transaction_id)->first();

            if(!empty($find))
            {
                $status  = strtoupper($request->status);
                $expiry = Carbon::parse(now())->addDays(31);
                $find->update([
                    'paid' => $status != 'FAILED',
                    'expiry_date' =>$status != 'FAILED' ? $expiry : null,
                ]);

                $user = User::query()->find($find->user_id);

                $trial = CompanyTrialMode::query()->where('company_id', $user->company->id)->first();

                $status != 'FAILED' ? $trial->update(['trial'=>false]) : $trial->update(['trial'=>true]);

               $message = $status != 'FAILED' ? "SM-SA Payment successful your renewal date is $expiry" : 'SM-SA payment failed';
               $this->sendSms($message,$user->phone_number);

                return response()->json('payment successful');

            }
        }catch (\Exception $ex)
        {
            file_put_contents(public_path('socialPayment.log'),"{$ex->getMessage()} \n",FILE_APPEND);
        }

    }

    public function trending(){

        $twitter_accesstoken = UserSocial::query()->where('user_id','=', Auth()->user()->id)->select('twitter_access_token')->first();
        $twitter_access_secret = UserSocial::query()->where('user_id','=', Auth()->user()->id)->select('twitter_token_secret')->first();

//        dd($twitter_accesstoken);
        if($twitter_accesstoken == null || $twitter_access_secret == null){
            return redirect()->route('social.index')->with('myalert', 'You have not connected your twitter account yet?');
        }
        else{
            return view('social.trending',[
                'twitter_accesstoken' => $twitter_accesstoken,
                'twitter_access_secret' => $twitter_access_secret
            ]);
        }

    }

}
