<?php

/* Check the absolute path to the Social Auto Poster directory. */
if ( !defined( 'SAP_APP_PATH' ) ) {
    // If SAP_APP_PATH constant is not defined, perform some action, show an error, or exit the script
    // Or exit the script if required
    exit();
}

/**
 * Threads posting
 *
 * @package Social auto poster
 * @since 1.0.0
 */

class SAP_Threads {


    public $settings, $flash, $posts, $common,$threads, $logs, $quick_posts, $sap_common;
    public $grantaccessToken;

    public $api_url_me = "https://graph.threads.net/v1.0/me";
    public $apiurl = "https://graph.threads.net/v1.0/";
    public $fields = "id,username,name,threads_profile_picture_url,threads_biography"; // Fields to retrieve
    public $scope = "threads_basic,threads_content_publish"; // Required permissions

    public function __construct($user_id='') {
        global $sap_common;
        if (!class_exists('SAP_Quick_Posts')) {
            require_once( CLASS_PATH . 'Quick_Posts.php' );
        }

        if (!class_exists('SAP_Posts')) {
            require_once( CLASS_PATH . 'Posts.php' );
        }

        $this->settings = new SAP_Settings();
        $this->flash = new Flash();
        $this->posts = new SAP_Posts();
        $this->common = new Common();
        $this->logs = new SAP_Logs();
        $this->quick_posts = new SAP_Quick_Posts();
        $this->sap_common = $sap_common;

        /* Initialize the function */
        $this->sap_fb_initialize_for_threads($user_id);
        
    }

     /**
     * Get Social Auto poster Screen ID
     *
     * Handles to get social auto poster screen id
     *
     * @package Social Auto Poster
     * @since 1.0.0
     */

    public function sap_get_fb_threads_accounts($data_type = false, $user_id='') {

        // Taking some defaults
        $res_data = array();

        // Get stored fb app grant data
        $sap_threads_sess_data = $this->settings->get_user_setting('sap_fb_sess_data_for_threads',$user_id);
       
        if (is_array($sap_threads_sess_data) && !empty($sap_threads_sess_data)) {


            foreach ($sap_threads_sess_data as $fb_sess_key => $fb_sess_data) {

                $sap_threads_accounts = $sap_threads_sess_data[$fb_sess_key]['sap_threads_accounts'];
                $inta_accounts = array();

                if(!empty($sap_threads_accounts) && is_array($sap_threads_accounts)){

                    foreach(  $sap_threads_accounts as $key => $threads_accounts ) {

                        $inta_accounts[$key."|".$fb_sess_key] = $threads_accounts;
                       
                    } 

                    $res_data[$fb_sess_key] = $inta_accounts;
                }
            }
        }
        return $res_data;

    }    

    
    

     // fetch long live token by access token
    public function threads_get_long_lived_access_token($short_token, $client_secret) {
        $query_params = http_build_query([
            'grant_type'     => 'th_exchange_token',
            'client_secret'  => $client_secret,
            'access_token'   => $short_token,
        ]);

        $url = 'https://graph.threads.net/access_token?' . $query_params;

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $response = curl_exec($ch);

        if (curl_errno($ch)) {
            // Handle cURL error (you can replace this with your logging mechanism)
            error_log('Threads: ' . curl_error($ch));
            curl_close($ch);
            return false;
        }

        curl_close($ch);

        return json_decode($response, true);
    }


    /**
     * Assign Threads User's all Data to session
     *
     * Handles to assign user's threads data
     * to sessoin & save to database
     * Needed
     * @package Social Auto Poster
     * @since 1.0.0
     */
    public function sap_fb_initialize_for_threads($user_id='') {
        
        // Get global SAP threads options
        $sap_facebook_options = $this->settings->get_user_setting('sap_facebook_options',$user_id);

        if (isset($_GET['wpw_auto_poster_threads_app_method']) && $_GET['wpw_auto_poster_threads_app_method'] == 'appmethod') {

            if (isset($_GET['access_token']) && $_GET['access_token'] != '' && $_GET['wpw_threads_grant'] == 'true') {
                
                $this->grantaccessToken = $_GET['access_token'];
                try {

                    // Build the query parameters
                    $query_params = [
                        'fields' => $this->fields,
                        'access_token' => $this->grantaccessToken,
                    ];
                    // Initialize cURL
                    $ch = curl_init();

                    // Set cURL options
                    curl_setopt($ch, CURLOPT_URL, $this->api_url_me . '?' . http_build_query($query_params)); // Add query parameters to URL
                    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Return response as a string
                    curl_setopt($ch, CURLOPT_HEADER, true); // Include headers in the output

                    // Execute the cURL request
                    $response = curl_exec($ch);

                    // Check for cURL errors
                    if (curl_errno($ch)) {
                        echo "cURL Error: " . curl_error($ch);
                    } else {
                        // Separate headers and body
                        $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
                        $headers = substr($response, 0, $header_size);
                        $body = substr($response, $header_size);

                        // Decode JSON
                        $response_data = json_decode($body, true);
                        $user = $response_data;
                    }


                } catch (Exception $e) {
                    echo $this->sap_common->lang('social_fbconfig_graph_error').''. $e->getMessage();
                    $this->sap_common->sap_script_logs('Threads error : ' . $e->getMessage(), $user_id);
                    exit;
                } catch (Exception $e) {
                    echo $this->sap_common->lang('social_fbconfig_sdk_error').''. $e->getMessage();
                    $this->sap_common->sap_script_logs('Threads error : ' . $e->getMessage(), $user_id);
                    exit;
                }
              
                if (!empty($user)) {
                    $this->sap_common->sap_script_logs('Threads User ID : ' . $user['id'], $user_id);

                    try {
                    
                        $_SESSION['sap_threads_user_cache'] = $user;
                        $this->_user_cache = $_SESSION['sap_threads_user_cache'];
                        $_SESSION['sap_threads_user_id'] = $user['id'];
                       

                        $accessTokenLong = $this->threads_get_long_lived_access_token($this->grantaccessToken, SAP_NEW_FB_APP_METHOD_SECRET_FOR_THREADS);
                        if(is_array($accessTokenLong) && isset($accessTokenLong['access_token']) && !empty($accessTokenLong['access_token']) && $accessTokenLong !== false){
                            $_SESSION['long_access_token'] = $accessTokenLong['access_token'];
                        }else{
                            $_SESSION['long_access_token'] = $_GET['access_token'];
                        }
                        $wpweb_threads_user_accounts_arr[$user['id']]=$user['username'];
                        $threads_accounts_list = $wpweb_threads_user_accounts_arr;
                        $_SESSION['threads_accounts'] = $threads_accounts_list;
                        $sap_threads_sess_data = $this->settings->get_user_setting('sap_fb_sess_data_for_threads',$user_id);
                        
                        if (empty($sap_threads_sess_data)) {
                            $sap_threads_sess_data = array();
                        }

                        if (!isset($sap_threads_sess_data[$user['id']])) {

                            $sess_data = array(
                                'sap_threads_user_cache' => $_SESSION['sap_threads_user_cache'],
                                'sap_threads_user_id' => $_SESSION['sap_threads_user_id'],
                                'sap_threads_accounts' => $_SESSION['threads_accounts'],
                                'threads_' . $user['id'] . '_long_access_token' => $_SESSION['long_access_token'],
                                'threads_' . $user['id'] . '_code' => $_GET['code'],
                                'threads_' . $user['id'] . '_access_token' => $_GET['access_token'],
                                'threads_' . $user['id'] . '_user_id' => $user['id'],
                              
                            );


                            $key_user_id = strval($user['id']);
                            $sap_threads_sess_data[$key_user_id] = $sess_data;

                            // Update session data to options
                            $this->settings->update_user_setting('sap_fb_sess_data_for_threads', $sap_threads_sess_data);
                            $this->sap_common->sap_script_logs('Threads Session Data Updated to Options',$user_id);
                        }
                        $_SESSION['display_threads_post_msg'] = 'Grant Extended Permission Successfully.';
                        $this->sap_common->sap_script_logs('Threads Grant Extended Permission Successfully.',$user_id);
                    } catch (Exception $e) {
                        //record logs exception generated
                        $this->sap_common->sap_script_logs('Threads Exception : ' . $e->__toString(), $user_id);
                        //user is null
                        $user = null;
                    }
                }
                $_SESSION['sap_active_tab'] = 'threads';
                header("Location:" . SAP_SITE_URL . "/settings/");
                exit;
            } else if(isset($_GET['wpw_threads_grant']) && $_GET['wpw_threads_grant'] == 'false' && isset($_GET['error']) && $_GET['error'] != ''){
                $this->flash->setFlash('Threads error : ' . $_GET['error'], 'error' ,'',true);
                $this->sap_common->sap_script_logs('Threads Exception : '.$_GET['error'], $user_id);
                
                $_SESSION['sap_active_tab'] = 'threads';
                header("Location:" . SAP_SITE_URL . "/settings/");
                exit;
            }
        }    
        
    }

    /**
     * Threads Login URL Using APP method
     *
     * Getting the login URL from Threads.
     * Threads App method
     * Needed
     * @package Social Auto Poster
     * @since 1.0.0
     */ 
    public function sap_auto_poster_get_fb_app_method_login_url($user_id='') {


        $appId = SAP_NEW_FB_APP_METHOD_ID_FOR_THREADS; // Threads App ID
        $redirectUri = urlencode(SAP_NEW_FB_APP_REDIRECT_URL_FOR_THREADS); // Redirect URI
        
        // Additional permissions (uncomment if needed): "threads_manage_replies", "threads_read_replies", "threads_manage_insights"
        $state = "custom_state"; // Optional state parameter for CSRF protection

        // Construct the authorization URL
        $log_in = "https://threads.net/oauth/authorize" .
            "?client_id=" . $appId .
            "&redirect_uri=" . $redirectUri .
            "&scope=" . urlencode($this->scope) .
            "&response_type=code" .
            "&state=" . SAP_SITE_URL;
        return $log_in;
    }

    /**
     * Reset Sessions
     *
     * Resetting the Threads sessions when the admin clicks on
     * its link within the settings page.
     *
     * @package Social Auto Poster
     * @since 1.0.0
     */
    public function sap_fb_reset_session_for_threads() {

        // Check if threads reset user link is clicked and threads_reset_user is set to 1 and threads app id is there
        if (isset($_GET['threads_reset_user']) && $_GET['threads_reset_user'] == '1' && !empty($_GET['sap_threads_userid'])) {
            $fb_app_id = $_GET['sap_threads_userid'];

            unset($_SESSION['sap_threads_user_id']);
            unset($_SESSION['sap_threads_user_cache']);
            unset($_SESSION['sap_threads_user_accounts']);

            unset($_SESSION['threads_' . $fb_app_id . '_code']);
            unset($_SESSION['threads_' . $fb_app_id . '_access_token']);
            unset($_SESSION['threads_' . $fb_app_id . '_user_id']);
            unset($_SESSION['threads_' . $fb_app_id . '_state']);

            //Getting stored threads app data
            $sap_threads_sess_data = $this->settings->get_user_setting('sap_fb_sess_data_for_threads');

            // Unset perticular app value data and update the option
            if (isset($sap_threads_sess_data[$fb_app_id])) {

                unset($sap_threads_sess_data[$fb_app_id]);
                $this->settings->update_user_setting('sap_fb_sess_data_for_threads', $sap_threads_sess_data);
                $this->sap_common->sap_script_logs('Threads ' . $fb_app_id . ' Account Reset Successfully.');
                $_SESSION['sap_active_tab'] = 'threads';
                header("Location:" . SAP_SITE_URL . "/settings/");
                exit;
            }
        }
    }

    /**
     * Post to User Wall on Threads
     *
     * Handles to post user wall on threads
     *
     * @package Social Auto Poster
     * @since 1.0.0
     */
    public function sap_threads_post_to_userwall($post_id) {
        
        $postflg = false;
      
        $post = $this->posts->get_post($post_id, true);
        $user_id = isset( $post->user_id ) ? $post->user_id : '';

        //Getting Threads Options
        $threads_options = $this->settings->get_user_setting('sap_threads_options', $user_id);

       //Getting stored threads app data
        $sap_threads_sess_data = $this->settings->get_user_setting('sap_fb_sess_data_for_threads', $user_id);

        // General setting
        $sap_general_options = $this->settings->get_user_setting('sap_general_options',$user_id);

        $link_timestamp = isset($sap_general_options['timestamp_link']) ? "?".time() : '';
        
        if( !empty( $sap_threads_sess_data ) ) {

            $sap_threads_custom_msg = $this->posts->get_post_meta($post_id, '_sap_threads_post_msg');
            $sap_threads_custom_accounts = $this->posts->get_post_meta($post_id, '_sap_threads_post_accounts');
            $sap_threads_custom_image = $this->posts->get_post_meta($post_id, '_sap_threads_post_image');
            $threads_image = !empty($threads_options['threads_image']) ? $threads_options['threads_image'] : '';
            $default_accounts = !empty($threads_options['posts_users']) ? $threads_options['posts_users'] : '';

            $post_as = $this->posts->get_post_meta($post_id, '_sap_threads_post_type');
            $post_as = !empty($post_as) ? $post_as : $threads_options['share_posting_type'];
            $sap_threads_video = !empty($this->posts->get_post_meta($post_id, '_sap_threads_post_video')) ? $this->posts->get_post_meta($post_id, '_sap_threads_post_video') : $threads_options['sap_threads_video'];

            $message = !empty($sap_threads_custom_msg) ? $sap_threads_custom_msg : $post->body;
            $message = html_entity_decode(strip_tags($message), ENT_QUOTES);

            if( !empty( $post->share_link ) ) {
                $message .= " ".$post->share_link."".$link_timestamp;
            }

            if( !empty( $sap_threads_custom_image ) ) {
                $postimage = $sap_threads_custom_image;
            } 
            elseif( isset($post->img) && $post->img != '0' && $post->img != '' ) {
                $postimage = $post->img;
            } 
            else {
                $postimage = $threads_image;
            }

            
            // Post limit 2200 character per post
            if (!empty($message))
                $message = $this->posts->sap_limit_character($message, 2200);

            //posting logs data
            $posting_logs_data = array();
            $accounts = !empty($sap_threads_custom_accounts) ? $sap_threads_custom_accounts : $default_accounts;

             //Check Accounts exist
            if (empty($accounts)) {
                $this->flash->setFlash('Threads posting users are not selected.', 'error','',true);
                $this->sap_common->sap_script_logs('Threads posting users are not selected.', $user_id );
                $status_meta_array[] = array(
                    "status" => 'error',
                    "message" => 'Threads posting users are not selected.'
                );
                $this->quick_posts->update_post_meta($post_id,"sap_instgram_posting_error", $status_meta_array);
                return false;
            }

 
            if (!empty($accounts)) { // Check all user ids
                  
                foreach ($accounts as $key => $value) {
                    try {
                        if ($post->share_link != '') {
                            $posting_logs_data['link'] = $post->share_link."".$link_timestamp;
                        }
                                    
                        $posting_image = SAP_IMG_URL . $postimage;
                        $posting_logs_data['image'] = $posting_image;
                        $posting_logs_data['message'] = $message;
   
                        $account_data = explode("|",$value);
                        $long_access_token  = $sap_threads_sess_data[$account_data[1]]["threads_".$account_data[1].'_long_access_token'];
                        $threads_accounts =  $sap_threads_sess_data[$account_data[1]]['sap_threads_accounts'];
                         
                        if(!empty($account_data[0]) && $long_access_token !=''){
    
                            $base_caption   = $message;
                            $base_image_url = $posting_image;
                            
                            if( $post_as == 'reel_posting' ){
                                if( !empty ($sap_threads_video) ){
                                    $preview_name = !empty($sap_threads_video) ? $sap_threads_video : '';
                                    $preview_video = !empty($sap_threads_video) ? SAP_SITE_URL.'/uploads/'. $preview_name : '';
                                    unset($posting_logs_data['image']);
                                    $posting_logs_data['reel'] = $preview_video;

                                    $container_api  = $this->apiurl . $account_data[0] . '/threads';
                                    $container_curl = curl_init();

                                    curl_setopt($container_curl, CURLOPT_URL, $container_api);
                                    curl_setopt($container_curl, CURLOPT_POST, 1);
                                    curl_setopt($container_curl, CURLOPT_POSTFIELDS, [
                                        'media_type' => 'VIDEo',
                                        'video_url' => $preview_video,
                                        'text' => $base_caption,
                                        'access_token' => $long_access_token
                                    ]);

                                    // Receive server response ...
                                    curl_setopt($container_curl, CURLOPT_RETURNTRANSFER, true);
                                    $server_output = curl_exec($container_curl);
                                    $server_response = json_decode($server_output);

                                    curl_close($container_curl);
                                    
                                    if ((isset($server_response->error) && !empty($server_response->error))) {
                                        $error_message = $server_response->error->error_user_msg;
                                        if ($server_response->error->code == "36003") {
                                            $error_message = "The image's aspect ratio does not fall within our acceptable range. Advise the app user to try again with an image that falls withing a 4:5 to 1.91:1 range.";
                                        }
    
                                        if( !empty( $server_response->error->message ) ){
                                            $error_message = $server_response->error->message;
                                        }
    
                                        $this->flash->setFlash('Threads posting exception : ' . $server_response->error->code . ' | ' . $error_message, 'error','',true);
                                        $this->sap_common->sap_script_logs('Threads error : ' . $server_response->error->code . ' | ' . $error_message, $user_id );
                                        $status_meta_array[$threads_accounts[$account_data[0]]] = array(
                                            "status" => 'error',
                                            "message" => $server_response->error->code . ' | ' . $error_message
                                        );
                                        $postflg = false;
                                    }else{
                                        $data = $this->sap_publish_threads_reel( $server_response->id , $account_data[0] , $long_access_token , $posting_logs_user_details , $posting_logs_data, $post_id, $user_id);
                                        
                                        if( $data == 'success' ){
                                            //record logs for post posted to Threads
                                            $this->flash->setFlash( 'Threads : Reel sucessfully posted on - '.$threads_accounts[$account_data[0]], 'success','',true );
                                            $this->sap_common->sap_script_logs('Threads : Reel sucessfully posted on - ' . $threads_accounts[$account_data[0]], $user_id );
                                            $this->sap_common->sap_script_logs('Threads post data : ' . var_export($posting_logs_data,true), $user_id);
            
                                            $status_meta_array[$threads_accounts[$account_data[0]]] = array(
                                                "status" => 'success'
                                            );
                                            //posting flag that posting successfully
                                            $postflg = true;
                                            $this->logs->add_log('threads', $posting_logs_data,'default', $user_id);
                                        }else{
                                            $postflg = false;
                                        }
                                    }
                                }

                            }else{
                        
                                if($post_as == 'image_posting'){
                                        $media_type = 'IMAGE';
                                        //Custom code for fetching the container-id while posting
                                        $container_api  = $this->apiurl . $account_data[0] . '/threads?media_type='.$media_type.'&image_url=' . $base_image_url . '&text=' . urlencode($base_caption) . '&access_token=' . $long_access_token;
                                    }else{
                                        $media_type = 'TEXT';
                                        unset($posting_logs_data['image']);
                                        //Custom code for fetching the container-id while posting
                                        $container_api  = $this->apiurl . $account_data[0] . '/threads?media_type='.$media_type.'&text=' . urlencode($base_caption) . '&access_token=' . $long_access_token;
                                   
                                    }
                                $container_curl = curl_init();
                                
                                curl_setopt($container_curl, CURLOPT_URL,$container_api);
                                curl_setopt($container_curl, CURLOPT_POST, 1);  
                                curl_setopt($container_curl, CURLOPT_POSTFIELDS,$container_api);
        
                                // Receive server response ...
                                curl_setopt($container_curl, CURLOPT_RETURNTRANSFER, true);
                                $server_output = curl_exec($container_curl);
                                $server_response = json_decode($server_output);
        
                                curl_close($container_curl);
        
                                if (! empty($server_response)) {
                                
                                    $container_id    =  $server_response->id;

                                    if( !empty( $container_id ) ) {

                                        $api_post        =  $this->apiurl . $account_data[0].'/threads_publish?creation_id=' . $container_id . '&access_token=' . $long_access_token;
                                        $curl = curl_init();
                                        curl_setopt_array($curl, array(
                                            CURLOPT_URL => $api_post,
                                            CURLOPT_RETURNTRANSFER => true,
                                            CURLOPT_ENCODING => '',
                                            CURLOPT_MAXREDIRS => 10,
                                            CURLOPT_TIMEOUT => 0,
                                            CURLOPT_FOLLOWLOCATION => true,
                                            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                                            CURLOPT_CUSTOMREQUEST => 'POST',
                                        ));
            
                                        $response = curl_exec($curl);
                                        $response = json_decode($response);
                                        $result = (array) $response;
                                        
                                        curl_close($curl);
                                    
                                        if(!empty($result['id'])){
            
                                            $posting_logs_user_details = array(
                                                'account_id' => $account_data[0],
                                                'display_name' => $threads_accounts[$account_data[0]],
                                        
                                            );     
            
                                            $posting_logs_data['account_id'] = $account_data[0];
                                            $posting_logs_data['display_name'] = $threads_accounts[$account_data[0]];
                                        
                                            //record logs for post posted to twitter
                                            $this->flash->setFlash( 'Threads : Post sucessfully posted on - '.$threads_accounts[$account_data[0]], 'success','',true );
                                            $this->sap_common->sap_script_logs('Threads : Post sucessfully posted on - ' . $threads_accounts[$account_data[0]], $user_id );
                                            $this->sap_common->sap_script_logs('Threads post data : ' . var_export($posting_logs_data,true), $user_id);
            
                                            $status_meta_array[$threads_accounts[$account_data[0]]] = array(
                                                "status" => 'success'
                                            );
                                            //posting flag that posting successfully
                                            $postflg = true;
            
                                        }

                                        if((isset($server_response->error) && !empty($server_response->error))){

                                            $error_message = $server_response->error->error_user_msg;
                                            if( $server_response->error->code == "36003" ) {
                                                $error_message = "The image's aspect ratio does not fall within our acceptable range. Advise the app user to try again with an image that falls withing a 4:5 to 1.91:1 range.";
                                            }
                                            $this->flash->setFlash('Threads posting exception : ' . $server_response->error->code . ' | ' . $error_message, 'error','',true);
                                            $this->sap_common->sap_script_logs('Threads error : ' . $server_response->error->code . ' | ' . $error_message,$user_id );
                                            $status_meta_array[$threads_accounts[$account_data[0]]] = array(
                                                "status" => 'success',
                                                "message" => $server_response->error->code . ' | ' . $error_message
                                            );

                                        }

                                        //check error is set
                                        if (isset($result->error) && !empty($result->error)) {
                                            //record logs for twitter posting exception
                                            $error_message = $result->error->error_user_msg;
                                            $this->flash->setFlash('Threads posting exception : ' . $result->error->code . ' | ' . $error_message, 'error','',true);
                                            $this->sap_common->sap_script_logs('Threads error : ' . $result->error->code . ' | ' . $error_message, $user_id );
                                            $status_meta_array[$threads_accounts[$account_data[0]]] = array(
                                                "status" => 'success',
                                                "message" => $result->error->code . ' | ' . $error_message
                                            );
                                        }
                                    
                                        if ($postflg) {
                                            $this->logs->add_log('threads', $posting_logs_data,'default', $user_id);
                                        }

                                    } else {
                                        $this->sap_common->sap_script_logs('Threads error : '.$server_response->error->message, $user_id);
                                        $this->flash->setFlash('Threads posting exception : ' . $server_response->error->message, 'error','',true);
                                    }

                                }
                            }    
                        }else{
                            $this->flash->setFlash('Threads Account not found.', 'error','',true);
                            $this->sap_common->sap_script_logs('Threads Account not found.', $user_id );
                        }    
                        
                    } catch (Exception $e) {
    
                        //record logs exception generated
                        $this->flash->setFlash('Threads posting time out, Please try again', 'error','',true);
                        $this->sap_common->sap_script_logs('Threads posting time out, Please try again.', $user_id );
                        $status_meta_array[$threads_accounts[$account_data[0]]] = array(
                            "status" => 'error',
                            "message" => 'Threads posting time out, Please try again'
                        );
                       
                        return false;
                    }
                }   
    
            } else {
                $this->flash->setFlash('Threads Account not found.', 'error','',true);
                $this->sap_common->sap_script_logs('Threads Account not found.', $user_id );
                return false;
            }
                

        } else {
            $this->flash->setFlash('Require Threads grant extended permissions for publishing content on Threads account', 'error','',true);
            $this->sap_common->sap_script_logs('Require Threads grant extended permissions for publishing content on Threads account', $user_id );
            
            return false;
        }
        
        //returning post flag
        return $postflg;
       
    }

    /**
     * Check and wait for ready to post
     *
     * @package Social Auto Poster
     * @since 1.0.0
     */
    public function sap_publish_threads_reel( $container_id , $threads_account_id , $long_access_token , $posting_logs_user_details , $posting_logs_data, $post_id = '', $user_id = '' ){
      
        $api_post = $this->apiurl .$threads_account_id.'/threads_publish?creation_id=' . $container_id . '&access_token=' . $long_access_token;
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $api_post,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_TIMEOUT => 100,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_SSL_VERIFYPEER => false,
        ));
    
        $response = curl_exec($curl);
        $response_data = json_decode($response);
        $result = (array) $response;

        curl_close($curl);
       
        if (!empty($response_data) && !empty($response_data->id)) {
            $threads_posting_status = 'success' ;
        } else {
            if($response_data->error && $response_data->error->code == 24 ){
                return $this->sap_publish_threads_reel( $container_id , $threads_account_id , $long_access_token , $posting_logs_user_details , $posting_logs_data, $post_id, $user_id);
            }
            $errorMessage = $response_data->error->error_user_msg;

            $this->flash->setFlash('Threads posting exception : ' . $response_data->error->code . ' | ' . $errorMessage, 'error','',true);
            $this->sap_common->sap_script_logs('Threads error : ' . $response_data->error->code . ' | ' . $errorMessage, $user_id );
            $status_meta_array[$threads_account_id] = array(
                "status" => 'error',
                "message" => $response_data->error->code . ' | ' . $errorMessage
            );
            $this->quick_posts->update_post_meta($post_id,"sap_threads_posting_error", $status_meta_array);
            $threads_posting_status = 'fail' ;
        }
        return $threads_posting_status;    
    }

    /**
     * Quick Post On Threads
     *
     * @package Social Auto Poster
     * @since 1.0.0
     */
    public function sap_quick_post_on_threads_post($post_id) {
    
        $postflg = false;
        //Get Post details
        $status_meta_array = array();
        
        $quick_post = $this->quick_posts->get_post($post_id, true);
        $user_id = isset( $quick_post->user_id ) ? $quick_post->user_id : '';
        
        $video_uploaded = $quick_post->video;

        $sap_networks_meta = $this->quick_posts->get_post_meta($post_id, 'sap_networks');
        
        $accounts = !empty($sap_networks_meta['threads_accounts']) ? $sap_networks_meta['threads_accounts'] : array();

        $global_share_post_type = !empty($sap_networks_meta['fb_posting_type']) ? $sap_networks_meta['fb_posting_type'] : 'link_posting';
        // Global General setting
        $sap_general_options = $this->settings->get_user_setting('sap_general_options',$user_id);

        $link_timestamp = isset($sap_general_options['timestamp_link']) ? "?".time() : '';

        //Get general options;
        $sap_threads_options = $this->settings->get_user_setting('sap_threads_options', $user_id);
        $sap_threads_sess_data = $this->settings->get_user_setting('sap_fb_sess_data_for_threads', $user_id);
      
        $default_accounts = !empty($sap_threads_options['posts_users']) ? $sap_threads_options['posts_users'] : '';

        $post_link = strip_tags($quick_post->share_link);

        if(!empty($post_link)) {
            $post_link = $post_link."".$link_timestamp;
        }

        $customlink  = !empty($post_link) ? 'true' : 'false';
      
        $post_body = !empty($quick_post->message) ? html_entity_decode(strip_tags($quick_post->message),ENT_QUOTES) : '';

        $post_desc = $image = '';
        $post_body .= (!empty($post_link) ) ? "\r\n".$post_link . "\r\n" : '';
        $post_desc .= (!empty($post_body) ) ? $post_body . "\r\n" : '';
      
        $accounts = !empty($accounts) ? $accounts : $default_accounts;
        
        // Post limit 2200 character per post
        if (!empty($post_body))
            $post_body = $this->quick_posts->sap_limit_character($post_body, 2200);

        //Check Accounts exist
        if (empty($accounts) ) {
            $this->flash->setFlash('Threads posting users are not selected.', 'error','',true);
            $this->sap_common->sap_script_logs('Threads posting users are not selected.',$user_id );
            $status_meta_array[] = array(
                "status" => 'error',
                "message" => 'Threads posting users are not selected.'
            );
            $this->quick_posts->update_post_meta($post_id,"sap_instgram_posting_error", $status_meta_array);
            return false;
        }

        if (isset($sap_threads_options['threads_image'])) {
            $general_threads_image = $sap_threads_options['threads_image'];
        }

        $image = !empty($quick_post->image) ? $quick_post->image : $general_threads_image;

        //posting logs data
        $posting_logs_data = array();
       
        if (!empty($accounts) && !empty($sap_threads_sess_data)) { // Check all user ids
             
            foreach ($accounts as $key => $value) {
                try {
                    if ($post_link != '') {
                        $posting_logs_data['link'] = $post_link."".$link_timestamp;
                    }
                                
                    $posting_image = SAP_IMG_URL . $image;
                    $posting_logs_data['image'] = $posting_image;
                    $posting_logs_data['message'] = $post_body;
                    
                    $account_data = explode("|",$value);
                    if(!empty($sap_threads_sess_data)){
                        $long_access_token  = $sap_threads_sess_data[$account_data[1]]["threads_".$account_data[1].'_long_access_token'];
                        $threads_accounts =  $sap_threads_sess_data[$account_data[1]]['sap_threads_accounts'];

                    }
                   
                    if(!empty($account_data[0]) && $long_access_token != '' && !empty($threads_accounts)){

                        $base_caption   = $post_body;
						$base_image_url = $posting_image;

                        $preview_video = SAP_SITE_URL.'/uploads/'.$video_uploaded;
                        
                        if( !empty($video_uploaded) && !empty($preview_video) && $sap_networks_meta['sap_share_posting_type_threads']=='reel_posting'){

                            unset($posting_logs_data['image']);
                            $posting_logs_data['reel'] = $preview_video;
                            
                            $container_api  = $this->apiurl . $account_data[0] . '/threads';
                            $container_curl = curl_init();

                            curl_setopt($container_curl, CURLOPT_URL, $container_api);
                            curl_setopt($container_curl, CURLOPT_POST, 1);
                            curl_setopt($container_curl, CURLOPT_POSTFIELDS, [
                                'media_type' => 'VIDEO',
                                'video_url' => $preview_video,
                                'text' => $base_caption,
                                'access_token' => $long_access_token
                            ]);

                            // Receive server response ...
                            curl_setopt($container_curl, CURLOPT_RETURNTRANSFER, true);
                            $server_output = curl_exec($container_curl);
                            $server_response = json_decode($server_output);
                            
                            curl_close($container_curl);
                           
                            if ((isset($server_response->error) && !empty($server_response->error))) {
                                $error_message = $server_response->error->error_user_msg;
                                if ($server_response->error->code == "36003") {
                                    $error_message = "The image's aspect ratio does not fall within our acceptable range. Advise the app user to try again with an image that falls withing a 4:5 to 1.91:1 range.";
                                }

                                if( !empty( $server_response->error->message ) ){
                                    $error_message = $server_response->error->message;
                                }

                                $this->flash->setFlash('Threads posting exception : ' . $server_response->error->code . ' | ' . $error_message, 'error','',true);
                                $this->sap_common->sap_script_logs('Threads error : ' . $server_response->error->code . ' | ' . $error_message, $user_id );
                                $status_meta_array[$threads_accounts[$account_data[0]]] = array(
                                    "status" => 'error',
                                    "message" => $server_response->error->code . ' | ' . $error_message
                                );
                                $postflg = false;
                            }else{
                                $data = $this->sap_publish_threads_reel( $server_response->id , $account_data[0] , $long_access_token , $posting_logs_user_details , $posting_logs_data, $post_id, $user_id);
                                
                                if( $data == 'success' ){
                                    //record logs for post posted to twitter
                                    $this->flash->setFlash( 'Threads : Video sucessfully posted on - '.$threads_accounts[$account_data[0]], 'success','',true );
                                    $this->sap_common->sap_script_logs('Threads : Reel sucessfully posted on - ' . $threads_accounts[$account_data[0]], $user_id );
                                    $this->sap_common->sap_script_logs('Threads post data : ' . var_export($posting_logs_data,true), $user_id);
    
                                    $status_meta_array[$threads_accounts[$account_data[0]]] = array(
                                        "status" => 'success'
                                    );
                                    //posting flag that posting successfully
                                    $postflg = true;
                                    $this->logs->add_log('threads', $posting_logs_data,'default', $user_id);
                                }else{
                                    $postflg = false;
                                }
                            }

                        }else{

                            if(!empty($image) && $sap_networks_meta['sap_share_posting_type_threads']=='image_posting'){
                                $media_type = 'IMAGE';
                                //Custom code for fetching the container-id while posting
                                $container_api  = $this->apiurl . $account_data[0] . '/threads?media_type='.$media_type.'&image_url=' . $base_image_url . '&text=' . urlencode($base_caption) . '&access_token=' . $long_access_token;
                            }else{
                                $media_type = 'TEXT';
                                unset($posting_logs_data['image']);
                                //Custom code for fetching the container-id while posting
                                $container_api  = $this->apiurl . $account_data[0] . '/threads?media_type='.$media_type.'&text=' . urlencode($base_caption) . '&access_token=' . $long_access_token;
                            
                            }
                           
                            $container_curl = curl_init();
                            
                            curl_setopt($container_curl, CURLOPT_URL,$container_api);
                            curl_setopt($container_curl, CURLOPT_POST, 1);  
                            curl_setopt($container_curl, CURLOPT_POSTFIELDS,$container_api);

                            // Receive server response ...
                            curl_setopt($container_curl, CURLOPT_RETURNTRANSFER, true);
                            $server_output = curl_exec($container_curl);
                            $server_response = json_decode($server_output);
                             
                            if (! empty($server_response)) {
                            
                                $container_id    =  $server_response->id;

                                if( !empty( $container_id ) ) {

                                    $api_post        = $this->apiurl .$account_data[0].'/threads_publish?creation_id=' . $container_id . '&access_token=' . $long_access_token;
                                    $curl = curl_init();
                                    curl_setopt_array($curl, array(
                                        CURLOPT_URL => $api_post,
                                        CURLOPT_RETURNTRANSFER => true,
                                        CURLOPT_ENCODING => '',
                                        CURLOPT_MAXREDIRS => 10,
                                        CURLOPT_TIMEOUT => 0,
                                        CURLOPT_FOLLOWLOCATION => true,
                                        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
                                        CURLOPT_CUSTOMREQUEST => 'POST',
                                    ));

                                    $response = curl_exec($curl);
                                    $response = json_decode($response);
                                    
                                    $result = (array) $response;
                                    curl_close($curl);
                                    if(!empty($result['id'])){

                                        $posting_logs_user_details = array(
                                            'account_id' => $account_data[0],
                                            'display_name' => $threads_accounts[$account_data[0]],
                                    
                                        );     

                                        $posting_logs_data['account_id'] = $account_data[0];
                                        $posting_logs_data['display_name'] = $threads_accounts[$account_data[0]];
                                    
                                        //record logs for post posted to twitter
                                        $this->flash->setFlash( 'Threads : Post sucessfully posted on - '.$threads_accounts[$account_data[0]], 'success','',true );
                                        $this->sap_common->sap_script_logs('Threads : Post sucessfully posted on - ' . $threads_accounts[$account_data[0]], $user_id );
                                        $this->sap_common->sap_script_logs('Threads post data : ' . var_export($posting_logs_data,true), $user_id);

                                        $status_meta_array[$threads_accounts[$account_data[0]]] = array(
                                            "status" => 'success'
                                        );
                                        //posting flag that posting successfully
                                        $postflg = true;

                                    }
                                    
                                    if((isset($server_response->error) && !empty($server_response->error))){

                                            $error_message = $server_response->error->error_user_msg;
                                            if( $server_response->error->code == "36003" ) {
                                                $error_message = "The image's aspect ratio does not fall within our acceptable range. Advise the app user to try again with an image that falls withing a 4:5 to 1.91:1 range.";
                                            }
                                            $this->flash->setFlash('Threads posting exception : ' . $server_response->error->code . ' | ' . $error_message, 'error','',true);
                                            $this->sap_common->sap_script_logs('Threads error : ' . $server_response->error->code . ' | ' . $error_message,$user_id );
                                            $status_meta_array[$threads_accounts[$account_data[0]]] = array(
                                                "status" => 'success',
                                                "message" => $server_response->error->code . ' | ' . $error_message
                                            );

                                        }

                                    if ($postflg) {
                                        $this->logs->add_log('threads', $posting_logs_data,'default', $user_id);
                                    }

                                } else {
                                    $this->sap_common->sap_script_logs('Threads error : '.$server_response->error->message, $user_id);
                                    $this->flash->setFlash('Threads posting exception : ' . $server_response->error->message, 'error','',true);
                                }
                                
                            } 
                        }
                    }else{
                        $this->flash->setFlash('Threads Account not found.', 'error','',true);
                        $this->sap_common->sap_script_logs('Threads Account not found.', $user_id );
                    }    
                    
                } catch (Exception $e) {

                    //record logs exception generated
                    $this->flash->setFlash('Threads posting time out, Please try again', 'error','',true);
                    
                    $this->sap_common->sap_script_logs('Twitter posting time out, Please try 
                        again.', $user_id);

                    $status_meta_array[$threads_accounts[$account_data[0]]] = array(
                        "status"  => 'success',
                        "message" => 'Threads posting time out, Please try again'
                    );
                   
                    return false;
                }
            }

            $this->quick_posts->update_post_meta($post_id,"sap_threads_posting_error", $status_meta_array);

        }else{

            $this->flash->setFlash('Threads Account not found.', 'error','',true);
            $this->sap_common->sap_script_logs('Threads Account not found.', $user_id );
            return false;
        }

        //returning post flag
        return $postflg;
        
    }

}
