<?php

namespace App\Opt;


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;


trait Media
{

    public function index()
    {
        return view('social.account.index');
    }

    public function dashboard()
    {
        $user = Auth::user();
        $now = date('Y-m-d');

        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->socialCredit()->where('paid',1)->first();
        $daily  = $user->posts()->whereDate('created_at',$now)->first();


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

        ]);

    }

    public function message(Request $request)
    {
        $user = Auth::user();
        $now = date('Y-m-d');
        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($request->isMethod('post')):

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

            $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->socialCredit()->where('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;


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

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

        else:

            $jsonPost  = '{
                "author" : "urn:li:person:'.$linked_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;
    }

    private function processImageForLinkedIn($linked_id,$access_token,$request)
    { 
        $register = '{
                "registerUploadRequest": {
                    "recipes": [
                        "urn:li:digitalmediaRecipe:feedshare-image"
                    ],
                    "owner": "urn:li:person:'.$linked_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": "urn:li:person:'.$linked_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');


//        $AppID2 = '655289554928599';
//        $secret2 = '07ba4bf4a1b65917ab3cf247eaa6947c';


        $appId = '432314024004251';
        $appSecret = '3a659294ccf3fc6ee827bc47978186e1';


        $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->socialCredit->expiry_date)
                return true;
        endif;
        return false;

    }
}
