<?php

/**
 * Collection controller
 *
 * @package kirki
 */

namespace Kirki\API\KirkiComments;

if (!defined('ABSPATH')) {
	exit; // Exit if accessed directly.
}

use Kirki\Ajax\Collaboration\Collaboration;
use Kirki\HelperFunctions;
use WP_Error;
use WP_REST_Controller;
use WP_REST_Server;

/**
 * ContentManagerRest
 * 
 * @deprecated
 * @see \Kirki\App\Http\Controllers\Api\CollaborationCommentController 
 */
class KirkiCommentsRest extends WP_REST_Controller
{


	/**
	 * Initialize the media class
	 *
	 * @return void
	 */
	public function __construct()
	{
		$this->namespace = 'kirki/v1';
		$this->rest_base = 'kirki-comments';
	}

	/**
	 * Register register
	 *
	 * @return void
	 */
	public function register_routes()
	{
		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/all',
			array(
				array(
					'methods' => 'GET',
					'callback' => array($this, 'get_all_comments'),
					'permission_callback' => array($this, 'get_item_permissions_check'),
					'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::READABLE),
				),
				'schema' => array($this, 'get_item_schema'),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/create',
			array(
				array(
					'methods' => 'POST',
					'callback' => array($this, 'create_comment'),
					'permission_callback' => array($this, 'create_item_permissions_check'),
					'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE),
				),
				'schema' => array($this, 'get_item_schema'),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/resolve',
			array(
				array(
					'methods' => 'POST',
					'callback' => array($this, 'resolve_comment'),
					'permission_callback' => array($this, 'create_item_permissions_check'),
					'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE),
				),
				'schema' => array($this, 'get_item_schema'),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/all-users',
			array(
				array(
					'methods' => 'GET',
					'callback' => array($this, 'get_all_users'),
					'permission_callback' => array($this, 'get_item_permissions_check'),
					'args' => array(
						'query' => array(
							'description' => 'Search query for user display name.',
							'type' => 'string',
							'required' => false,
						),
					),
				),
				'schema' => null,
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/read',
			array(
				array(
					'methods' => 'POST',
					'callback' => array($this, 'read_comment'),
					'permission_callback' => array($this, 'create_item_permissions_check'),
					'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE),
				),
				'schema' => array($this, 'get_item_schema'),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/unread',
			array(
				array(
					'methods' => 'POST',
					'callback' => array($this, 'unread_comment'),
					'permission_callback' => array($this, 'create_item_permissions_check'),
					'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE),
				),
				'schema' => array($this, 'get_item_schema'),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/delete',
			array(
				array(
					'methods' => 'POST',
					'callback' => array($this, 'delete_comment'),
					'permission_callback' => array($this, 'create_item_permissions_check'),
					'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE),
				),
				'schema' => array($this, 'get_item_schema'),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/read-all',
			array(
				array(
					'methods' => 'POST',
					'callback' => array($this, 'read_all_comments'),
					'permission_callback' => array($this, 'create_item_permissions_check'),
					'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE),
				),
				'schema' => array($this, 'get_item_schema'),
			)
		);

		register_rest_route(
			$this->namespace,
			'/' . $this->rest_base . '/resolve-all',
			array(
				array(
					'methods' => 'POST',
					'callback' => array($this, 'resolve_all_comments'),
					'permission_callback' => array($this, 'create_item_permissions_check'),
					'args' => $this->get_endpoint_args_for_item_schema(WP_REST_Server::CREATABLE),
				),
				'schema' => array($this, 'get_item_schema'),
			)
		);
	}

	public function read_all_comments($request)
	{
		$post_id = HelperFunctions::sanitize_text(isset($request['post_id']) ? $request['post_id'] : '');
		$user_id = get_current_user_id();

		global $wpdb;
		$seen_table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE . '_seen';
		$comments_table = $wpdb->prefix . KIRKI_COMMENTS_TABLE;

		$wpdb->query(
			$wpdb->prepare(
				"INSERT IGNORE INTO $seen_table_name (user_id, comment_id) 
				SELECT %d, id FROM $comments_table 
				WHERE post_id = %d AND parent_id = 0",
				$user_id,
				$post_id
			)
		);

		return rest_ensure_response(
			array(
				'status' => 'success',
				'message' => __('All comments marked as read.', 'kirki'),
			)
		);
	}


	public function resolve_all_comments($request)
	{
		$post_id = HelperFunctions::sanitize_text(isset($request['post_id']) ? $request['post_id'] : '');
		$session_id = HelperFunctions::sanitize_text(isset($request['session_id']) ? $request['session_id'] : '');

		$status = 2;

		global $wpdb;
		$table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE;
		$wpdb->query(
			$wpdb->prepare(
				"UPDATE $table_name SET status = %d WHERE post_id = %d AND parent_id = 0",
				$status,
				$post_id
			)
		);

		$data = array(
			'type' => 'COLLABORATION_UPDATE_ALL_KIRKI_COMMENT',
			'payload' => array('data' => array('status' => '' . $status)),
		);
		Collaboration::save_action_to_db('post', $post_id, $data, 1, $session_id);

		return rest_ensure_response(
			array(
				'status' => 'success',
				'message' => __('All comments marked as resolved.', 'kirki'),
			)
		);
	}


	public function resolve_comment($request)
	{
		$comment_id = intval(HelperFunctions::sanitize_text(isset($request['id']) ? $request['id'] : '0'));
		$post_id = HelperFunctions::sanitize_text(isset($request['post_id']) ? $request['post_id'] : '');
		$status = intval(HelperFunctions::sanitize_text(isset($request['status']) ? $request['status'] : '1'));
		$session_id = HelperFunctions::sanitize_text(isset($request['session_id']) ? $request['session_id'] : '');

		global $wpdb;
		$table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE;
		$wpdb->query(
			$wpdb->prepare(
				"UPDATE $table_name SET status = %d WHERE id = %d",
				$status,
				$comment_id
			)
		);

		$data = array(
			'type' => 'COLLABORATION_UPDATE_KIRKI_COMMENT',
			'payload' => array(
				'data' => array('status' => '' . $status),
				'id' => '' . $comment_id,
			),
		);
		Collaboration::save_action_to_db('post', $post_id, $data, 1, $session_id);

		return rest_ensure_response($this->get_single_comment($comment_id));
	}

	public function read_comment($request)
	{
		$comment_id = intval(HelperFunctions::sanitize_text(isset($request['id']) ? $request['id'] : '0'));
		$user_id = get_current_user_id();

		global $wpdb;
		$seen_table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE . '_seen';

		$wpdb->query(
			$wpdb->prepare(
				"INSERT INTO $seen_table_name (user_id, comment_id) VALUES ( %d, %d )",
				$user_id,
				$comment_id
			)
		);
		return rest_ensure_response($this->get_single_comment($comment_id));
	}

	public function unread_comment($request)
	{
		$comment_id = intval(HelperFunctions::sanitize_text(isset($request['id']) ? $request['id'] : '0'));
		$user_id = get_current_user_id();

		global $wpdb;
		$seen_table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE . '_seen';

		$wpdb->query(
			$wpdb->prepare(
				"DELETE FROM $seen_table_name WHERE comment_id = %d AND user_id = %d",
				$comment_id,
				$user_id
			)
		);
		return rest_ensure_response($this->get_single_comment($comment_id));
	}

	public function delete_comment($request)
	{
		$comment_id = intval(HelperFunctions::sanitize_text(isset($request['id']) ? $request['id'] : '0'));
		$post_id = HelperFunctions::sanitize_text(isset($request['post_id']) ? $request['post_id'] : '');
		$session_id = HelperFunctions::sanitize_text(isset($request['session_id']) ? $request['session_id'] : '');
		$user = wp_get_current_user();

		$comment = $this->get_single_comment($comment_id);
		$allowed_roles = array('editor', 'administrator');
		if ($comment['user_id'] == $user->ID || array_intersect($allowed_roles, $user->roles)) {
			global $wpdb;
			$table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE;
			$wpdb->query(
				$wpdb->prepare(
					"DELETE FROM $table_name WHERE id = %d OR parent_id = %d",
					$comment_id,
					$comment_id
				)
			);

			$data = array(
				'type' => 'COLLABORATION_DELETE_KIRKI_COMMENT',
				'payload' => array('id' => '' . $comment_id),
			);
			Collaboration::save_action_to_db('post', $post_id, $data, 1, $session_id);

			return rest_ensure_response(
				array(
					'status' => 'success',
					'message' => __('Comment deleted successfully.', 'kirki'),
				)
			);
		} else {
			return rest_ensure_response(
				array(
					'status' => 'error',
					'message' => __('You do not have permission to delete this comment.', 'kirki'),
				)
			);
		}
	}

	public function get_all_users($request)
	{
		$roles = HelperFunctions::get_all_user_roles_by_access_levels(
			array(
				KIRKI_ACCESS_LEVELS['FULL_ACCESS'],
				KIRKI_ACCESS_LEVELS['CONTENT_ACCESS'],
				KIRKI_ACCESS_LEVELS['VIEW_ACCESS'],
			)
		);

		$query = isset($request['query']) ? sanitize_text_field($request['query']) : '';
		$per_page = HelperFunctions::sanitize_text(isset($request['per_page']) ? $request['per_page'] : 20);

		$args = array(
			'role__in' => $roles,
			'orderby' => 'display_name',
			'order' => 'ASC',
			'number' => $per_page,
			'search' => '*' . esc_attr($query) . '*',
			'search_columns' => array('user_login', 'user_nicename', 'display_name', 'user_email'),
		);

		$users = get_users($args);
		$formatted_users = array();

		foreach ($users as $user) {
			$formatted_users[] = array(
				'user_id' => $user->ID,
				'user_name' => $user->display_name,
				'user_avatar' => get_avatar_url($user->ID),
			);
		}

		return rest_ensure_response($formatted_users);
	}



	public function create_comment($request)
	{
		$comment = HelperFunctions::sanitize_text(isset($request['comment']) ? $request['comment'] : '[]');
		$post_id = HelperFunctions::sanitize_text(isset($request['post_id']) ? $request['post_id'] : '');
		$parent_id = HelperFunctions::sanitize_text(isset($request['parent_id']) ? $request['parent_id'] : 0);
		$status = HelperFunctions::sanitize_text(isset($request['status']) ? $request['status'] : 1);
		$meta_data = HelperFunctions::sanitize_text(isset($request['meta_data']) ? $request['meta_data'] : '[]');
		$session_id = HelperFunctions::sanitize_text(isset($request['session_id']) ? $request['session_id'] : '');
		$user_id = get_current_user_id();


		global $wpdb;
		$table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE;
		$wpdb->query(
			$wpdb->prepare(
				"INSERT INTO $table_name (user_id, post_id, parent_id, comment, meta_data, status ) VALUES ( %d, %d, %d, %s, %s, %d )",
				$user_id,
				$post_id,
				$parent_id,
				$comment,
				$meta_data,
				$status
			)
		);
		$comment_id = $wpdb->insert_id;

		if ($parent_id === '0') {
			$seen_table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE . '_seen';
			$wpdb->query(
				$wpdb->prepare(
					"INSERT INTO $seen_table_name (user_id, comment_id) VALUES ( %d, %d )",
					$user_id,
					$comment_id
				)
			);
		} else {
			$seen_table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE . '_seen';
			$wpdb->query(
				$wpdb->prepare(
					"DELETE FROM $seen_table_name WHERE comment_id = %d AND user_id != %d",
					$parent_id,
					$user_id
				)
			);
		}

		$comment = $this->get_single_comment($comment_id);
		$data = array(
			'type' => 'COLLABORATION_ADD_KIRKI_COMMENT',
			'payload' => array('comment' => array_merge($comment, array('read' => '0'))),
		);
		Collaboration::save_action_to_db('post', $post_id, $data, 1, $session_id);

		return rest_ensure_response($comment);
	}


	/**
	 * get_all_comments
	 *
	 * @param \WP_REST_Request $request all user request parameter.
	 *
	 * @return \WP_Error|WP_REST_Response
	 */
	public function get_all_comments($request)
	{
		global $wpdb;

		$post_id = HelperFunctions::sanitize_text(isset($request['post_id']) ? $request['post_id'] : null);
		$current_page = HelperFunctions::sanitize_text(isset($request['page']) ? $request['page'] : 1);
		$per_page = HelperFunctions::sanitize_text(isset($request['per_page']) ? $request['per_page'] : 20);
		$user_id = get_current_user_id();

		$table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE;
		$seen_table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE . '_seen';

		$offset = ($current_page - 1) * $per_page;

		$params = array();

		// Escape table names for security
		$table_name_esc = esc_sql($table_name);
		$seen_table_name_esc = esc_sql($seen_table_name);

		$read_data = "CASE WHEN $seen_table_name_esc.comment_id IS NOT NULL THEN 1 ELSE 0 END AS `read`";
		$read_join = "LEFT JOIN $seen_table_name_esc ON $table_name_esc.id = $seen_table_name_esc.comment_id AND $seen_table_name_esc.user_id = %d";
		$params[] = $user_id;

		$where = "WHERE $table_name_esc.parent_id = %d";
		$params[] = 0;

		if ($post_id !== null) {
			$where .= " AND $table_name_esc.post_id = %d";
			$params[] = $post_id;
		}

		$sql = "
        SELECT $table_name_esc.*, $read_data 
        FROM $table_name_esc 
        $read_join 
        $where 
        ORDER BY $table_name_esc.created_at DESC 
        LIMIT %d, %d
    ";

		$params[] = $offset;
		$params[] = $per_page;

		// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- Table names are escaped with esc_sql() above
		$all_comments = $wpdb->get_results($wpdb->prepare($sql, $params), ARRAY_A);

		foreach ($all_comments as $key => $comment) {
			$all_comments[$key] = $this->format_single_comment($comment);
		}

		// Count query (also conditionally add post_id)
		$count_where = 'WHERE parent_id = 0';
		$count_args = array();
		if ($post_id !== null) {
			$count_where .= ' AND post_id = %d';
			$count_args[] = $post_id;
		}

		$count_sql = "SELECT COUNT(*) FROM $table_name $count_where";
		if (!empty($count_args)) {
			$count = $wpdb->get_var($wpdb->prepare($count_sql, $count_args)); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		} else {
			$count = $wpdb->get_var($count_sql); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		}

		$res = array(
			'total' => $count,
			'per_page' => $per_page,
			'current_page' => $current_page,
			'data' => $all_comments,
		);

		return rest_ensure_response($res);
	}

	private function get_single_comment($comment_id)
	{
		global $wpdb;

		$user_id = get_current_user_id();
		$table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE;
		$seen_table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE . '_seen';

		$read_data = "CASE WHEN $seen_table_name.comment_id IS NOT NULL THEN 1 ELSE 0 END AS `read`";
		$read_join = $wpdb->prepare("LEFT JOIN $seen_table_name ON $table_name.id = $seen_table_name.comment_id AND $seen_table_name.user_id = %d", $user_id);

		$sql = $wpdb->prepare("SELECT $table_name.*, $read_data FROM $table_name $read_join WHERE $table_name.id = %d", $comment_id);
		$comment = $wpdb->get_row($sql, ARRAY_A); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		return $this->format_single_comment($comment);
	}
	private function format_single_comment($comment)
	{
		$comment['replies'] = $this->get_all_replies($comment['id']);
		$comment['meta_data'] = json_decode($comment['meta_data'], true);
		$comment['comment'] = json_decode($comment['comment'], true);
		$comment['user_avatar'] = get_avatar_url($comment['user_id']);
		$comment['user_name'] = get_the_author_meta('display_name', $comment['user_id']);
		return $comment;
	}

	private function get_all_replies($comment_id)
	{
		global $wpdb;
		$table_name = $wpdb->prefix . KIRKI_COMMENTS_TABLE;
		$sql = $wpdb->prepare("SELECT * FROM $table_name WHERE parent_id = %d ORDER BY created_at ASC", $comment_id);
		$all_replies = $wpdb->get_results($sql, ARRAY_A); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		foreach ($all_replies as $key => $reply) {
			$all_replies[$key] = $this->format_single_comment($reply);
		}
		return $all_replies;
	}

	public function get_item_permissions_check($request)
	{
		if (HelperFunctions::is_api_call_from_editor_preview() && HelperFunctions::is_api_header_post_editor_preview_token_valid()) {
			return true;
		}

		return HelperFunctions::has_access(
			array(
				KIRKI_ACCESS_LEVELS['FULL_ACCESS'],
				KIRKI_ACCESS_LEVELS['CONTENT_ACCESS'],
				KIRKI_ACCESS_LEVELS['VIEW_ACCESS'],
			)
		);
	}

	public function create_item_permissions_check($request)
	{
		return HelperFunctions::has_access(
			array(
				KIRKI_ACCESS_LEVELS['FULL_ACCESS'],
				KIRKI_ACCESS_LEVELS['CONTENT_ACCESS'],
			)
		);
	}
}
