<?php /** @noinspection PhpFullyQualifiedNameUsageInspection */
/** @noinspection PhpUndefinedClassInspection */

/** @noinspection PhpUndefinedFieldInspection */

namespace App\Http\Controllers;

use App\Opt\Media;
use App\Traits\SocialSubscription;
use App\UserSocial;
use Facebook\Exceptions\FacebookSDKException;
use Facebook\Facebook;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Abraham\TwitterOAuth\TwitterOAuth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Mail;

class SocialMediaController extends Controller
{
  
    use Media,SocialSubscription;

    public   $consumerKey = 'BIHTy0PaszoDriJO8nLGEE50Z';
    public   $consumer_secrete = 'wgC6eUXO3hsLdG0WJDJatxFEu4gNeLydmDviyOdebFZcqWCRri';

    public   $linkedInClientID = '86z3xkcpzttz9m';
    public   $linkedInSecret = 'PIwnk6NZb4WSJYjB';

    public   $faceAppId = '576850202828274';
    public   $faceAppSecret = 'de165a551dde984fc98ebf16f0c2acf1';

    public   $InstClientId = '2f39586f15694a56832e72b823a71ca8';
    public   $InstSecret = '38d863f43d4c46969144514d9bd5e61d';


    public function fb_loginIsValidated(Request $request)
    {

        $fb = new Facebook([
            'app_id' => $this->faceAppId,
            'app_secret' => $this->faceAppSecret,
            'default_graph_version' => 'v3.2',
        ]);


        $helper = $fb->getRedirectLoginHelper();

        if (isset($_GET['state']))
        {
            $helper->getPersistentDataHandler()->set('state', $_GET['state']);
        }


        $helper = $fb->getRedirectLoginHelper();


        try {
            $accessToken = $helper->getAccessToken(); //access
        } catch(Facebook\Exceptions\FacebookResponseException $e) {
            return redirect()->route('social.index')->withErrors('Could not connect to facebook business account please make sure you have facebook business account');
        } catch(Facebook\Exceptions\FacebookSDKException $e) {
            return redirect()->route('social.index')->withErrors('Could not connect to facebook business account please make sure you have facebook business account');
        }


try{
        $oAuth2Client = $fb->getOAuth2Client();


            $tokenMetadata = $oAuth2Client->debugToken($accessToken);
            $tokenMetadata->validateAppId($this->faceAppId);
            $tokenMetadata->validateExpiration();

        }catch (FacebookSDKException $ex)
        {
            return redirect()->route('social.index')->withErrors('Could not connect to facebook business account please make sure you have facebook business account');
        }

        if (! $accessToken->isLongLived()) {
            // Exchanges a short-lived access token for a long-lived one
            try {
                $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken);
            } catch (Facebook\Exceptions\FacebookSDKException $e) {
                return redirect()->route('social.index')->withErrors('Could not connect to facebook business account please make sure you have facebook business account');
            }

        }


        try {


//            $response = $fb->get('/me/?fields=accounts{access_token,posts.limit(10)},name', $accessToken);
            $response = $fb->get('/me/?fields=accounts{access_token,name},name', $accessToken);

            $user = $response->getGraphUser()->asArray();
            //if client lacks facebook business page then redirect or cancels app permission
            if(!isset($user['accounts']))
                return redirect()->route('social.index')->withErrors('Could not connect to facebook business account. Please make sure you have a facebook business account');


//            ? auth user has multiple accounts
            foreach ($user['accounts'] as $account):

                $data['facebook_name']   = $account['name'];
                $data['fb_access_token'] = $account['access_token'];
                $data['fb_user_access']  = $accessToken;
                $data['fb_page_id']      = $account['id'];

                $this->ajax_facebook($data);

            endforeach;

        } catch(Facebook\Exceptions\FacebookResponseException $e) {
        } catch(Facebook\Exceptions\FacebookSDKException $e) {

        }

        return redirect()->route('social.index');

    }


    public function fb_retrieved_data(Request $request)
    {
        $feeds = session()->get('user_feeds');
        $fb_username = session()->get('fb_username');

        return view('social.facebook.index',compact('feeds','fb_username'));
    }


    public function fb_accounts()
    {
        return Auth::user()->social()->select('fb_access_token','facebook_name')->get();
    }
    public function ln_accounts()
    {
        return Auth::user()->social()->select('linked_page_name','linkedin_name','linkedin_person_id','linked_in_page_id')->get();
    }

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

    public  function instagram()
    {

        $redirectUrl = route('social.ins-redirected');
        return redirect("https://api.instagram.com/oauth/authorize/?client_id={$this->InstClientId}&redirect_uri={$redirectUrl}&response_type=code");

    }


    public function ins_redirected(Request $request)
    {
        $code = $request->code;
        if(empty($code))
            return redirect()->route('social.index')->withErrors('Could not connect to instagram at the moment');


        $grant_type = 'authorization_code';
        $callback   = route('social.ins-redirected');
        $endpoint = "https://api.instagram.com/oauth/access_token";

        //for access token
        $client = new Client;
        $res = $client->request('POST', $endpoint, [
            'form_params' => [
                'client_id' => $this->InstClientId,
                'client_secret' => $this->InstSecret,
                'grant_type' => $grant_type,
                'redirect_uri' => $callback,
                'code' => $code
            ]
        ]);

        $guzzle_response = json_decode($res->getBody());

        $token = $guzzle_response->access_token;

        $self  = $client->request('GET', "https://api.instagram.com/v1/users/self/?access_token={$token}");
        $media = $client->request('GET', "https://api.instagram.com/v1/users/self/media/recent/?access_token={$token}");


        /** @var @decode the body of the message  $self_info & $media_inf */
        $self_info  =  json_decode($self->getBody());
        $media_info =  json_decode($media->getBody());

        $media_posts = array();

        $person = [

            'self_photo'    => $self_info->data->profile_picture,
            'self_name'     => $self_info->data->full_name,
            'self_bio'      => $self_info->data->bio,
            'self_website'  => $self_info->data->website,
            'media'         => $self_info->data->counts->media,
            'follows'       => $self_info->data->counts->follows,
            'followed_by'   => $self_info->data->counts->followed_by,

        ];



        foreach ($media_info->data as $ig_post):
            if($ig_post->type = 'image'):
                $push = [
                    'imageOriginal' => $ig_post->images->standard_resolution->url,
                    'imageCaption'  => !empty($ig_post->caption) ? $ig_post->caption->text : 'N/A',
                    'imgLikes'      => $ig_post->likes->count,
                    'mediaLink'     => $ig_post->link
                ];
                array_push($media_posts,$push);
            endif;
        endforeach;


        session(['user_posts' => $media_posts,'person'=>$person]);

        return redirect()->route('social.ins-access-callback');

    }

    public function ins_access_callback(Request $request)
    {
        $media_posts = session()->get('user_posts');

        $person = session()->get('person');

        return view('social.instagram.index',compact('media_posts','person'));
    }


    //linked Integration
    public function linkedIn()
    {
        $permissions = urlencode("r_liteprofile r_emailaddress w_member_social r_1st_connections_size rw_organization_admin r_organization_social r_ads_reporting r_basicprofile rw_ads w_organization_social r_ads");
        $redirectUrl =  route('social.linkedin.callback');
        return redirect("https://www.linkedin.com/oauth/v2/authorization/?client_id={$this->linkedInClientID}&redirect_uri={$redirectUrl}&response_type=code&scope={$permissions}");

    }

    public function linkedIn0Auth(Request $request)
    {

        $code = $request->code;
        if(empty($code))
            return redirect()->route('social.index')->withErrors('Could not connect to linkedIn account');

        /**  retrieve access token **/
        $client = new Client;
        $client_id = $this->linkedInClientID;
        $secret    = $this->linkedInSecret;
        $endpoint =    'https://www.linkedin.com/oauth/v2/accessToken';
        $redirectUrl = route('social.linkedin.callback');
        $res = $client->request('POST', $endpoint, [
            'form_params' => [
                'client_id' => $client_id,
                'client_secret' => $secret,
                'code' => $code,
                'grant_type' => 'authorization_code',
                'redirect_uri' => $redirectUrl,
                'Content-Type' => 'application/x-www-form-urlencoded'
            ]
        ]);


        $self_info  =  json_decode($res->getBody());

        $access_token = $self_info->access_token;


        //Get the profile details
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, "https://api.linkedin.com/v2/me?oauth2_access_token={$access_token}");
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        $result = curl_exec($curl);

        $profile = json_decode($result);

        session([

            'linked_id' => $profile->id,
            'linked_username'=>$profile->firstName->localized->en_US.' '.$profile->lastName->localized->en_US,
            'linked_token'=>$access_token

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

        $pages =$this->retrieveOrganisation($access_token);



        foreach ($pages as $page):
            foreach ($page as $linkedInPage):
            $values['linked_in_page_id'] = $linkedInPage->organization;
            $values['linked_page_name'] = json_decode(json_encode($linkedInPage), true)["organization~"]['localizedName'];
            $this->ajax_linkedIn($values);
            endforeach;
        endforeach;



        $values['linkedin_name'] = $profile->firstName->localized->en_US.' '.$profile->lastName->localized->en_US;
        $values['linkedin_person_id'] = "urn:li:person:$profile->id";
        $values['linkedin_access_token'] = $self_info->access_token;
        $values['linkedin_expire'] = $self_info->expires_in;

        $this->ajax_linkedIn($values);


        return redirect()->route('social.index')->with('success','Account setup complete');

    }

    public function linked_page(Request $request)
    {
        $linked_id = session()->get('linked_id');

        $linked_username = session()->get('linked_username');

        $access_token   = session()->get('linked_token');


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

            $this->validate($request,[
                'post_field' => 'required'
            ]);

            $post = $request->post_field;


            $sample  = '{
                "author" : "urn:li:person:'.$linked_id.'",
                "lifecycleState" : "PUBLISHED",
                "specificContent" : {
                    "com.linkedin.ugc.ShareContent" : {
                        "shareCommentary" : {
                            "text" : "'.$post.'"
                        },
                        "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, $sample);
                curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
                $result = curl_exec($curl);


            } catch (\Exception $e) {
                redirect()->back()->withErrors($e->getMessage());
            }

            return redirect()->back()->with('success','Done! successfully posted to your linkedIn page');

        endif;


        return view('social.linkedIn.index',compact('linked_id','linked_username'));
    }

    /** Twitter */
    public function twitter()
    {


        $redirectUrl = route('social.twitter.callback');

        try{

            $connection = new TwitterOAuth($this->consumerKey, $this->consumer_secrete);
            $request_token = $connection->oauth('oauth/request_token', array('oauth_callback' => $redirectUrl));


            session([
                'twitter_app_token'=>$request_token['oauth_token'],
                'twitter_oauth_token_secret'=>$request_token['oauth_token_secret']
            ]);

            $url = $connection->url('oauth/authorize', array('oauth_token' => $request_token['oauth_token']));
            return redirect($url);
        }
        catch (\Exception $spa){
            file_put_contents(public_path('twitter.log'),"{$spa->getMessage()} \n",FILE_APPEND);
            return redirect()->back()->withErrors('Unable to connect to twitter at the moment');
        }

    }

    public function twitter_callback(Request $request)
    {

        $token =session()->get('twitter_app_token');
        $secret = session()->get('twitter_oauth_token_secret');

        if(empty($request->oauth_verifier))
        {
            return redirect()->route('social.index')->withErrors('Could not connect to account');
        }
        $twitter = new TwitterOAuth($this->consumerKey, $this->consumer_secrete,$token,$secret);
        $extra_info = $twitter->oauth("oauth/access_token", ["oauth_verifier" => $request->oauth_verifier]);

        session(['screen_name'=>$extra_info['screen_name']]);

        $this->ajax_twitter($extra_info);

        return redirect()->route('social.index')->with('success',"Account setup complete !");
    }

    public function retrieveOrganisation($access_token)
    {
        $curl = curl_init();
        $org_api = "https://api.linkedin.com/v2/organizationAcls?q=roleAssignee&role=ADMINISTRATOR&projection=(elements*(*,roleAssignee~(localizedFirstName,localizedLastName),organization~(localizedName)))&oauth2_access_token=$access_token";
        curl_setopt($curl, CURLOPT_URL, $org_api);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        $result = curl_exec($curl);
        $result = json_decode($result);
        return $result;
    }


    public  function sendEmail($content)
    {
        Mail::send('email_approved', $content, function ($m) use ($content) {
            $m->from('sms@deywuro.com', 'Deywuro');
            $m->to($content['to'],  $content['name']);
            $m->subject($content['subject'] ?? 'DEYWURO ALERT');
        });
    }



}
