<?php
if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly
}

/**
 * REST API endpoints functionality of the plugin.
 *
 * @link       #
 * @since      1.3.0
 *
 * @package    commenting-feature
 */

class Commenting_Block_Rest_Routes extends Commenting_block_Functions {

	private $namespace;

	/**
	 * Constructor
	 */
	public function __construct() {
		$this->namespace = 'multicollab/v2';
		add_action( 'rest_api_init', array( $this, 'create_rest_routes' ) );
	}

	/**
	 * Defines Rest Routes
	 *
	 * @return void
	 */
	public function create_rest_routes() {
		register_rest_route(
			$this->namespace,
			'/activities',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'get_activities' ),
				'permission_callback' => array( $this, 'check_activity_post_access' ),
			)
		);

		register_rest_route(
			$this->namespace,
			'/activitiesCount',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'get_activities_count' ),
				'permission_callback' => array( $this, 'check_activity_post_access' ),
			)
		);

		register_rest_route(
			$this->namespace,
			'/getuserdata',
			array(
				'methods'             => 'GET',
				'callback'            => array( $this, 'multicollab_rest_get_userdata' ),
				'permission_callback' => array( $this, 'multicollab_rest_check_get_userdata_access' ),
			)
		);
	}

	/**
	 * REST permission: user must be logged in and able to edit the post whose collaboration data is requested.
	 *
	 * @param \WP_REST_Request $request Request.
	 * @return bool
	 */
	public function check_activity_post_access( $request ) {
		if ( ! is_user_logged_in() ) {
			return false;
		}
		$post_id = absint( $request->get_param( 'postID' ) );
		if ( ! $post_id ) {
			return false;
		}
		$post = get_post( $post_id );
		if ( ! $post instanceof \WP_Post ) {
			return false;
		}
		return current_user_can( 'edit_post', $post_id );
	}

	/**
	 * REST permission for user profile payload: self, users who can list/edit users, or collaborator on a post (optional postID).
	 *
	 * @param \WP_REST_Request $request Request.
	 * @return bool
	 */
	public function multicollab_rest_check_get_userdata_access( $request ) {
		if ( ! is_user_logged_in() ) {
			return false;
		}
		$userid = absint( $request->get_param( 'userid' ) );
		if ( ! $userid ) {
			return false;
		}
		if ( (int) $userid === (int) get_current_user_id() ) {
			return true;
		}
		if ( current_user_can( 'list_users' ) || current_user_can( 'edit_users' ) ) {
			return true;
		}
		$post_id = absint( $request->get_param( 'postID' ) );
		if ( $post_id && get_post( $post_id ) && current_user_can( 'edit_post', $post_id ) ) {
			return true;
		}
		return false;
	}

	public function get_activities_count( $data ) {

		$current_post_id = intval( $data->get_param( 'postID' ) );  //phpcs:ignore

		// Modify Query
		global $wpdb;

		$like            = $wpdb->esc_like( '_el' ) . '%';
		$c_reg_exp       = $wpdb->esc_like( '_el[0-9]' );
		$threads         = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}postmeta WHERE post_id=%d AND meta_key LIKE %s AND meta_key REGEXP %s", $current_post_id, $like, $c_reg_exp ), ARRAY_A ); // phpcs:ignore

		return rest_ensure_response( count( $threads ) );
	}

	/**
	 * Callback to send the rest response.
	 *
	 * @param array $data
	 * @return array
	 */
	public function get_activities( $data ) {

        $current_post_id = intval($data->get_param('postID'));  //phpcs:ignore
		$date_format     = get_option( 'date_format' );
		$time_format     = get_option( 'time_format' );
		$timestamp       = current_time( 'timestamp' );
		$cf_options      = get_option( 'multicollab_permissions' );
		$cf_edd          = new Multicollab_EDD();

		// Modify Query
		global $wpdb;
		$user_id = apply_filters( 'determine_current_user', false ); // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Core WP filter; hook name cannot be prefixed.
		wp_set_current_user( $user_id );
		$current_users   = get_userdata( $user_id );

		$currunt_user_roles = isset( $current_users->roles ) ? array_values( $current_users->roles ) : '';
		$current_user_role  = array_shift( $currunt_user_roles );
		$hide_comment    = isset( $cf_options[ isset( $current_user_role) ? $current_user_role : '' ]['hide_comment'] ) ? $cf_options[ isset( $current_user_role ) ? $current_user_role : '' ]['hide_comment'] : '';
		
        $like            = $wpdb->esc_like( '_el' ) . '%';
		$c_reg_exp       = $wpdb->esc_like( '_el[0-9]' );
		$results = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->prefix}postmeta WHERE post_id=%d AND meta_key LIKE %s AND meta_key REGEXP %s", $current_post_id, $like, $c_reg_exp), ARRAY_A); // phpcs:ignore

		$threads = array();
		if ((is_array($results) && !empty($results)) || (is_object($results) && !empty((array)$results))) {
			foreach ( $results as $row ) {
				$cmnts = array();

				// passing the last activity parameters in thread for displaying in activity center last activity.
				$lastpostid     = $row['post_id'];
				$editedLastUser = get_post_meta( $lastpostid, 'last_user_edited', true );

				// Get post default author name.
				$author_id     = get_post_field( 'post_author', $lastpostid );
				$defaultAuthor = get_the_author_meta( 'nickname', $author_id );

				$lasteditedtime = get_the_modified_time( 'U', $lastpostid );
				$usr_login_name = get_user_by( 'login', $editedLastUser );
				if ( ( get_user_by( 'login', $editedLastUser ) ) !== false ) {
					$lasteditedUsersID = isset( $usr_login_name ) ? (int) $usr_login_name->ID : 0;
				} else {
					$lasteditedUsersID = null;
					if($this->get_userid_by_display_name( $editedLastUser )){
						$lasteditedUsersID = $this->get_userid_by_display_name( $editedLastUser ) ?? null;
						$usr_login_name = get_user_by( 'ID', $lasteditedUsersID );
					}
				}

				$lasteditedUsersUrl = get_avatar_url( $lasteditedUsersID );
				$elID               = str_replace( '_', '', $row['meta_key'] );
				$comments           = maybe_unserialize( $row['meta_value'] );

				if ((is_array($comments['comments']) && !empty($comments['comments'])) || (is_object($comments['comments']) && !empty((array)$comments['comments']))) {
					foreach ( $comments['comments'] as $timestamp => $comment ) {

						$user_info = get_userdata( isset( $comment['userData'] ) ? $comment['userData'] : '' );

						// Add break if $user_info->roles is giving null value.
						if( empty( $user_info->roles ) ) {
							break;
						}

						$commenting_block = new Commenting_block_Functions();
						$needToSortArray  = $commenting_block->multicollab_get_reorder_user_role( $user_info->roles );
						$user_info->roles = array_values( $needToSortArray );
						$roles            = $user_info->roles[0] ?? '';
						$comment_status   = isset( $comment['status'] ) ? $comment['status'] : '';
						if ( 'draft' !== $comment_status && 'permanent_draft' !== $comment_status ) {
							$cmnts[] = array(
								'id'              => $timestamp,
								'status'          => isset( $comment_status ) ? $comment_status : '',
								'created_at'      => isset( $comment['created_at'] ) ? $comment['created_at'] : '',
								'timestamp'       => gmdate( $time_format . ' ' . $date_format, intval( $timestamp ) ),
								'editedTime'      => isset( $comment['editedTime'] ) ? $comment['editedTime'] : '',
								'editedTimestamp' => isset( $comment['editedTimestamp'] ) ? $comment['editedTimestamp'] : '',
								'userData'        => array(
									'id'        => isset( $user_info->ID ) ? intval( $user_info->ID ) : 0,
									'username'  => isset( $user_info->display_name ) ? $user_info->display_name : '',
									'avatarUrl' => get_avatar_url( isset( $user_info->user_email ) ? $user_info->user_email : '' ),
									'userRole'  => $roles ?? '',
								),
								'thread'          => isset( $comment['thread'] ) ? $comment['thread'] : '',
								'attachmentText'  => isset( $comment['attachmentText'] ) ? $comment['attachmentText'] : '',
							);
						}
					}
				}

				$resolved_by = array();
				if ( isset( $comments['resolved'] ) && 'true' === $comments['resolved'] ) {
					if ( isset( $comments['resolved_by'] ) ) {
						$resolved_user = get_userdata( $comments['resolved_by'] );
						$resolved_by   = array(
							'username'  => $resolved_user->display_name,
							'avatarUrl' => get_avatar_url( $resolved_user->user_email ),
						);
					}
				}

				$assigned_user = array();
				if ( isset( $comments['assigned_to'] ) ) {
					$assigned_user_info = get_userdata( $comments['assigned_to'] );
					if ( $assigned_user_info instanceof \WP_User ) {
						$assigned_label = ( (int) $user_id === (int) $assigned_user_info->ID )
							? __( 'You', 'commenting-feature' )
							: $assigned_user_info->display_name;
						$assigned_user  = array(
							'ID'           => (int) $assigned_user_info->ID,
							'display_name' => $assigned_label,
							'username'     => $assigned_label,
							'user_email'   => $assigned_user_info->user_email,
							'email'        => $assigned_user_info->user_email,
							'avatar'       => get_avatar_url( $assigned_user_info->ID, array( 'size' => 32 ) ),
						);
					}
				}

				// Get post default author name.
				$author_id         = get_post_field( 'post_author', $current_post_id );
				$defaultAuthor     = get_the_author_meta( 'display_name', $author_id );
				$defaultAuthorLink = get_avatar_url( get_the_author_meta( 'user_email', $author_id ) );
				$Defaultusers      = get_userdata( $author_id );

				$commenting_block    = new Commenting_block_Functions();
				$needToSortArray     = $commenting_block->multicollab_get_reorder_user_role( $Defaultusers->roles );
				$Defaultusers->roles = array_values( $needToSortArray );
				$roles               = $Defaultusers->roles[0] ?? '';

				if ( ! empty( $cmnts ) ) {
					$threads[] = array(
						'elID'              => $elID,
						'activities'        => $cmnts,
						'selectedText'      => isset( $comments['commentedOnText'] ) ? $comments['commentedOnText'] : '',
						'resolved'          => isset( $comments['resolved'] ) ? $comments['resolved'] : 'false',
						'resolvedTimestamp' => isset( $comments['resolved_timestamp'] ) ? $comments['resolved_timestamp'] : '',
						'resolvedBy'        => $resolved_by,
						'updatedAt'         => isset( $comments['updated_at'] ) ? $comments['updated_at'] : '',
						'assignedTo'        => $assigned_user,
						'blockType'         => isset( $comments['blockType'] ) ? $comments['blockType'] : '',
						'lastUser'          => $editedLastUser,
						'defaultAuthor'     => $defaultAuthor,
						'defaultAuthorLink' => $defaultAuthorLink,
						'defaultUserRole'   => $roles ?? '',
						'lastEditedTime'    => $lasteditedtime,
						'lastUsersUrl'      => isset( $lasteditedUsersUrl ) ? $lasteditedUsersUrl : '',
						'type'              => 'el',
					);
			
						$threads = $threads;
					
				}
			}
		}

		if ( ! metadata_exists( 'post', $current_post_id, '_autodraft_ids' ) ) {
			// create new meta if meta key doesn't exists
			add_post_meta( $current_post_id, '_autodraft_ids', '' );
		}
		array_multisort( array_column( $threads, 'updatedAt' ), SORT_DESC, $threads );

		$response = array(
			'threads' => $threads,
		);

		return rest_ensure_response( $response );
	}

	 /**
	  * Return collaborator activities array
	  *
	  * @param integer $data
	  * @return array
	  */
	public function get_collaborator_activities( $postId ) {
		unset( $postId );
		return array();
	}

	// custom rest end point to get userdata by user id
	public function multicollab_rest_get_userdata( $data ) {
        $userid = intval($data->get_param('userid'));  //phpcs:ignore

		if ( ! $userid || $userid === '' ) {
			return null;
		}

		$user_info = get_userdata( $userid );
		if ( ! empty( $user_info ) ) {

			$userdata = array(
				'id'        => isset( $user_info->ID ) ? intval( $user_info->ID ) : 0,
				'username'  => isset( $user_info->display_name ) ? $user_info->display_name : '',
				'avatarUrl' => get_avatar_url( isset( $user_info->user_email ) ? $user_info->user_email : '' ),
				'userRole'  => isset( $user_info->roles ) ? implode( ', ', $user_info->roles ) : '',
			);

			return rest_ensure_response( $userdata );
		}

		return null;
	}

	/**
	 * get user by display_name of the user
	 * @param string $display_name - consist with user's display name.
	 */
	public function multicollab_rest_get_user_id_by_display_name( $display_name ) {
		global $wpdb;
		$user_id = '';
		$checkLastEditedUser = $wpdb->get_row($wpdb->prepare("SELECT ID FROM $wpdb->users WHERE display_name = %s", $display_name)); //phpcs:ignore
		if(!empty($checkLastEditedUser)){ 
			$user_id = $checkLastEditedUser->ID;
		}
		return $user_id;
	}
}
new Commenting_Block_Rest_Routes();
