<?php
/**
 * MainWP REST Controller
 *
 * This class handles the REST API
 *
 * @package MainWP\Dashboard
 */

use MainWP\Dashboard\MainWP_Sync;
use MainWP\Dashboard\MainWP_DB;
use MainWP\Dashboard\MainWP_Manage_Sites_View;
use MainWP\Dashboard\MainWP_Manage_Sites_Handler;
use MainWP\Dashboard\MainWP_Connect;
use MainWP\Dashboard\MainWP_Monitoring_Handler;
use MainWP\Dashboard\MainWP_Extra_Exception;
use MainWP\Dashboard\MainWP_DB_Client;
use MainWP\Dashboard\Module\CostTracker\Cost_Tracker_DB;
use MainWP\Dashboard\Module\CostTracker\Cost_Tracker_Rest_Api_Handle_V1;
use MainWP\Dashboard\MainWP_DB_Common;
use MainWP\Dashboard\MainWP_Utility;
use MainWP\Dashboard\MainWP_DB_Site_Actions;
use MainWP\Dashboard\MainWP_Logger;
/**
 * Class MainWP_Rest_Sites_Controller
 *
 * @package MainWP\Dashboard
 */
class MainWP_Rest_Sites_Controller extends MainWP_REST_Controller{ //phpcs:ignore -- NOSONAR - multi methods.

    // phpcs:disable Generic.Metrics.CyclomaticComplexity -- complexity.

    /**
     * Protected static variable to hold the single instance of the class.
     *
     * @var mixed Default null
     */
    private static $instance = null;

    /**
     * Endpoint namespace.
     *
     * @var string
     */
    protected $namespace = 'mainwp/v2';

    /**
     * Route base.
     *
     * @var string
     */
    protected $rest_base = 'sites';


    /**
     * Constructor.
     */
    public function __construct() {
        add_filter( 'mainwp_rest_routes_sites_controller_filter_allowed_fields_by_context', array( $this, 'hook_filter_allowed_fields_by_context' ), 10, 3 );
        add_filter( 'mainwp_rest_routes_sites_controller_get_allowed_fields_by_context', array( $this, 'hook_get_allowed_fields_by_context' ), 10, 1 );
    }

    /**
     * Method instance()
     *
     * Create public static instance.
     *
     * @static
     * @return static::$instance
     */
    public static function instance() {
        if ( null === static::$instance ) {
            static::$instance = new self();
        }
        return static::$instance;
    }


    /**
     * Get filter sites.
     *
     * @param object $item item data.
     * @param string $context context.
     * @param mixed  $request The rest request.
     *
     * @return object item in context.
     */
    public function hook_filter_allowed_fields_by_context( $item, $context = 'view', $request = array() ) {
        return $this->filter_response_data_by_allowed_fields( $this->prepare_item_for_response( $item, $request ), $context );
    }

    /**
     * Get filter sites.
     *
     * @param string $context context.
     *
     * @return object item in context.
     */
    public function hook_get_allowed_fields_by_context( $context = 'view' ) {
        return $this->get_allowed_fields_by_context( $context );
    }

    /**
     * Method register_routes()
     *
     * Creates the necessary endpoints for the api.
     * Note, for a request to be successful the URL query parameters consumer_key and consumer_secret need to be set and correct.
     */
    public function register_routes() { // phpcs:ignore -- NOSONAR - complex.

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base,
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_items' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/basic',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_basic_items' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/count',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'count_items' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/sync',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'sync_items' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/reconnect',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'reconnect_items' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/disconnect',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'disconnect_sites' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/check',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'check_items' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[\d]+)',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_item' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => array(
                        'id_domain' => array(
                            'description' => __( 'Site ID or domain.', 'mainwp' ),
                            'type'        => 'string',
                        ),
                    ),
                ),
                'schema' => array( $this, 'get_public_item_schema' ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[A-Za-z0-9-\.]*[A-Za-z0-9-]{1,63}\.[A-Za-z]{2,6}$)',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_item' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => array(
                        'id_domain' => array(
                            'description' => __( 'Site ID or domain.', 'mainwp' ),
                            'type'        => 'string',
                        ),
                    ),
                ),
                'schema' => array( $this, 'get_public_item_schema' ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/add',
            array(
                array(
                    'methods'             => WP_REST_Server::CREATABLE,
                    'callback'            => array( $this, 'create_item' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/edit',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'update_item' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/sync',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'sync_item' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/security',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'security_item' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/plugins',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_site_plugins' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/plugins/activate',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'activate_plugins_of_site' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/plugins/deactivate',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'deactivate_plugins_of_site' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/plugins/delete',
            array(
                array(
                    'methods'             => WP_REST_Server::DELETABLE,
                    'callback'            => array( $this, 'delete_plugins_of_site' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_collection_params(),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/plugins/abandoned',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_abandoned_plugins_of_site' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_collection_params(),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/themes',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_site_themes' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/themes/activate',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'activate_themes_of_site' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/themes/delete',
            array(
                array(
                    'methods'             => WP_REST_Server::DELETABLE,
                    'callback'            => array( $this, 'delete_themes_of_site' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/themes/abandoned',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_abandoned_themes_of_site' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_collection_params(),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/non-mainwp-changes',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_non_mainwp_changes_of_site' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_collection_params(),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/reconnect',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'reconnect_item' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_collection_params(),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/disconnect',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'disconnect_site' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_collection_params(),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/suspend',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'suspend_item' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_collection_params(),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/unsuspend',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'unsuspend_item' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_collection_params(),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/check',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'check_item' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/remove',
            array(
                array(
                    'methods'             => WP_REST_Server::DELETABLE,
                    'callback'            => array( $this, 'delete_item' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_collection_params(),
                ),
            )
        );

        // Retrieves client Object for the site by site ID or Domain.
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/client',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_client_site' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_collection_params(),
                ),
            )
        );

        // Retrieves costs for the site by ID or Domain.
        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/(?P<id_domain>[a-zA-Z0-9\-\.\_]+)/costs',
            array(
                array(
                    'methods'             => WP_REST_Server::READABLE,
                    'callback'            => array( $this, 'get_costs_site' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_collection_params(),
                ),
            )
        );

        register_rest_route(
            $this->namespace,
            '/' . $this->rest_base . '/batch',
            array(
                array(
                    'methods'             => WP_REST_Server::EDITABLE,
                    'callback'            => array( $this, 'batch_items' ),
                    'permission_callback' => array( $this, 'get_rest_permissions_check' ),
                    'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
                ),
                'schema' => array( $this, 'get_public_batch_schema' ),
            )
        );
    }


    /**
     * Get item.
     *
     * @param  WP_REST_Request $request Request object.
     *
     * @return array|mixed Response data, ready for insertion into collection data.
     */
    public function get_item( $request ) {

        $value = isset( $request['id_domain'] ) ? $request['id_domain'] : '';
        $by    = 'domain';

        if ( is_numeric( $value ) ) {
            $by = 'id';
        } else {
            $value = urldecode( $value );
        }

        $with_tags = isset( $request['with_tags'] ) ? mainwp_string_to_bool( $request['with_tags'] ) : false;

        $prepared_args = array(
            'with_tags' => $with_tags,
        );

        $item = $this->get_site_by( $by, $value, $prepared_args );

        if ( is_wp_error( $item ) ) {
            return $item;
        }

        $params   = array(
            'full_data'    => true,
            'selectgroups' => true,
            'include'      => array( $item->id ),
            'fields'       => $this->get_fields_for_response( $request ),
        );
        $websites = MainWP_DB::instance()->get_websites_for_current_user( $params );
        $data     = $websites ? current( $websites ) : array();
        if ( ! empty( $data ) ) {
            $data = $this->filter_response_data_by_allowed_fields( $this->prepare_item_for_response( $data, $request ), 'view' );
        }
        return rest_ensure_response( array( 'data' => $data ) );
    }



    /**
     * Get all sites.
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_Error|WP_REST_Response
     */
    public function get_items( $request ) {

        $args = $this->prepare_objects_query( $request );
        $args = $this->validate_rest_args( $args, $this->get_validate_args_params( 'get_sites' ) );
        if ( is_wp_error( $args ) ) {
            return $args;
        }

        $args['selectgroups'] = isset( $request['with_tags'] ) ? mainwp_string_to_bool( $request['with_tags'] ) : true;
        $args['full_data']    = isset( $request['full_data'] ) ? mainwp_string_to_bool( $request['full_data'] ) : true;

        // get data.
        $websites = MainWP_DB::instance()->get_websites_for_current_user( $args );

        $data = array();

        if ( $websites ) {
            foreach ( $websites as $site ) {
                $data[] = $this->filter_response_data_by_allowed_fields( $this->prepare_item_for_response( $site, $request ), 'view' );
            }
        }
        return rest_ensure_response(
            array(
                'success' => 1,
                'total'   => count( $data ),
                'data'    => $data,
            )
        );
    }

    /**
     * Get all sites.
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_Error|WP_REST_Response
     */
    public function get_basic_items( $request ) {

        $args = $this->prepare_objects_query( $request );
        $args = $this->validate_rest_args( $args, $this->get_validate_args_params( 'get_sites' ) );

        if ( is_wp_error( $args ) ) {
            return $args;
        }

        $args['selectgroups'] = isset( $request['with_tags'] ) ? mainwp_string_to_bool( $request['with_tags'] ) : false;
        $args['full_data']    = isset( $request['full_data'] ) ? mainwp_string_to_bool( $request['full_data'] ) : false;

        // get data.
        $websites = MainWP_DB::instance()->get_websites_for_current_user( $args );

        $data = array();

        if ( $websites ) {
            foreach ( $websites as $site ) {
                $data[] = $this->filter_response_data_by_allowed_fields( $this->prepare_item_for_response( $site, $request ), 'simple_view' );
            }
        }
        return rest_ensure_response(
            array(
                'success' => 1,
                'total'   => count( $data ),
                'data'    => $data,
            )
        );
    }


    /**
     * Get the query params for collections.
     *
     * @return array
     */
    public function get_collection_params() {
        $params                       = array();
        $params['context']['default'] = 'view';
        return $params;
    }

    /**
     * Count all sites.
     *
     * @param  WP_REST_Request $request Request object.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function count_items( $request ) {
        $args = $this->prepare_objects_query( $request );

        $args = $this->validate_rest_args( $args, $this->get_validate_args_params( 'get_sites' ) );
        if ( is_wp_error( $args ) ) {
            return $args;
        }

        $params = array(
            'exclude' => isset( $args['exclude'] ) ? $args['exclude'] : array(),
            'include' => isset( $args['include'] ) ? $args['include'] : array(),
            'status'  => isset( $args['status'] ) ? $args['status'] : array(),
        );

        // get data.
        $websites = MainWP_DB::instance()->get_websites_for_current_user( $params );
        $data     = array(
            'count' => count( $websites ),
        );
        return rest_ensure_response( $data );
    }

    /**
     * Sync sites.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function sync_item( $request ) {

        $website = $this->get_request_item( $request );

        if ( is_wp_error( $website ) ) {
            return $website;
        }

        try {
            $success = MainWP_Sync::sync_site( $website );
        } catch ( \Exception $e ) {
            return new WP_Error( 'mainwp_rest_sync_site_error', $e->getMessage(), array( 'status' => 404 ) );
        }

        $data = array();

        if ( $success ) {
            $params   = array(
                'full_data'    => true,
                'selectgroups' => true,
                'include'      => array( $website->id ),
                'fields'       => $this->get_fields_for_response( $request ),
            );
            $websites = MainWP_DB::instance()->get_websites_for_current_user( $params );
            $data     = $websites ? current( $websites ) : array();
            $data     = $this->filter_response_data_by_allowed_fields( $this->prepare_item_for_response( $data, $request ), 'view' );
        }

        return rest_ensure_response(
            array(
                'success' => $success ? 1 : 0,
                'data'    => $data,
            )
        );
    }


    /**
     * Secure site info.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function security_item( $request ) {

        $website = $this->get_request_item( $request );

        if ( is_wp_error( $website ) ) {
            return $website;
        }

        try {
            $result = MainWP_Connect::fetch_url_authed( $website, 'security' );
        } catch ( \Exception $e ) {
            return new WP_Error( 'mainwp_rest_get_secure_site_error', $e->getMessage(), array( 'status' => 404 ) );
        }

        $data = array(
            'data' => $result,
            'site' => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );

        return rest_ensure_response( $data );
    }

    /**
     * Get plugins of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function get_site_plugins( $request ) { //phpcs:ignore -- NOSONAR - complex.

        $website = $this->get_request_item( $request );

        if ( is_wp_error( $website ) ) {
            return $website;
        }

        $args = $this->prepare_objects_query( $request );
        $args = $this->validate_rest_args( $args, $this->get_validate_args_params( 'site_plugins' ) );

        if ( is_wp_error( $args ) ) {
            return $args;
        }

        $data = json_decode( $website->plugins, 1 );

        if ( is_array( $data ) ) {
            if ( ! empty( $args['must_use'] ) ) {
                $data = MainWP_Utility::get_sub_array_having( $data, 'mu', 1 );
            }
            if ( ! empty( $args['s'] ) ) {
                $s = trim( $args['s'] );
                if ( ! empty( $s ) ) {
                    $data = mainwp_search_in_array(
                        $data,
                        $s,
                        array(
                            'search_in_key'    => false,
                            'in_sub_fields'    => array( 'name', 'description', 'version', 'slug' ),
                            'use_index_result' => false,
                        )
                    );
                }
            }

            if ( ! empty( $args['status'] ) && is_array( $args['status'] ) && ! in_array( 'any', $args['status'] ) ) {

                $status_act   = in_array( 'active', $args['status'] ) ? 1 : 0;
                $status_inact = in_array( 'inactive', $args['status'] ) ? 1 : 0;

                $status_val = false;
                if ( $status_act && $status_inact ) {
                    $status_val = false;
                } elseif ( $status_act ) {
                    $status_val = 1;
                } elseif ( $status_inact ) {
                    $status_val = 0;
                }

                if ( false !== $status_val ) {
                    $data = MainWP_Utility::get_sub_array_having( $data, 'active', $status_val );
                }
            }
            if ( ! empty( $args['paged'] ) && ! empty( $args['items_per_page'] ) ) {
                $pag  = (int) $args['paged'];
                $per  = (int) $args['items_per_page'];
                $data = MainWP_Utility::get_sub_array_with_limit( $data, $per * ( $pag - 1 ), $per );
            }
        }

        $resp_data = array(
            'success' => 1,
            'total'   => is_array( $data ) ? count( $data ) : 0,
            'data'    => $data,
            'site'    => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );
        return rest_ensure_response( $resp_data );
    }


    /**
     * Handle plugins actions of site.
     *
     * @param object $website object.
     * @param string $action action.
     * @param string $slugs plugins slugs.
     *
     * @return WP_Error|array
     */
    public function handle_plugins_actions_of_site( $website, $action, $slugs ) {
        try {
            $information = MainWP_Connect::fetch_url_authed(
                $website,
                'plugin_action',
                array(
                    'action' => $action,
                    'plugin' => implode( '||', $slugs ),
                )
            );

            $success = false;
            $data    = array();
            if ( is_array( $information ) && isset( $information['other_data']['plugin_action_data'] ) ) {
                $action_data = $information['other_data']['plugin_action_data'];
                foreach ( $action_data as $item ) {
                    $success = true;
                    $item    = MainWP_Utility::instance()->sanitize_data( $item );
                    if ( ! empty( $item ) && isset( $item['name'] ) ) {
                        $data[] = array(
                            'name'    => $item['name'],
                            'version' => $item['version'],
                            'slug'    => $item['slug'],
                        );
                    }
                }
            }

            return array(
                'success' => $success ? 1 : 0,
                'data'    => $data,
            );

        } catch ( \Exception $e ) {
            return new WP_Error( "mainwp_rest_{$action}_plugins_action", $e->getMessage() );
        }
    }


    /**
     * Activate plugins of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function activate_plugins_of_site( $request ) {
        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }

        $slugs = isset( $request['slug'] ) ? array_map( 'trim', wp_parse_list( $request['slug'] ) ) : array();
        if ( empty( $slugs ) ) {
            return new WP_Error( 'mainwp_rest_invalid_plugins_slugs', __( 'Plugins slugs are empty or invalid.', 'mainwp' ), 400 );
        }
        $result = $this->handle_plugins_actions_of_site( $website, 'activate', $slugs );

        if ( is_wp_error( $result ) ) {
            return $result;
        }

        $resp_data = array(
            'success' => ! empty( $result['success'] ) ? 1 : 0,
            'data'    => ! empty( $result['data'] ) ? $result['data'] : array(),
            'site'    => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );

        return rest_ensure_response( $resp_data );
    }

    /**
     * Deactivate plugins of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function deactivate_plugins_of_site( $request ) {
        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }

        $slugs = isset( $request['slug'] ) ? array_map( 'trim', wp_parse_list( $request['slug'] ) ) : array();
        if ( empty( $slugs ) ) {
            return new WP_Error( 'mainwp_rest_invalid_plugins_slugs', __( 'Plugins slug is empty or invalid.', 'mainwp' ), 400 );
        }
        $result = $this->handle_plugins_actions_of_site( $website, 'deactivate', $slugs );

        if ( is_wp_error( $result ) ) {
            return $result;
        }
        $resp_data = array(
            'success' => ! empty( $result['success'] ) ? 1 : 0,
            'data'    => ! empty( $result['data'] ) ? $result['data'] : array(),
            'site'    => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );

        return rest_ensure_response( $resp_data );
    }

    /**
     * Delete plugins of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function delete_plugins_of_site( $request ) {
        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }
        $slugs = isset( $request['slug'] ) ? array_map( 'trim', wp_parse_list( $request['slug'] ) ) : array();
        if ( empty( $slugs ) ) {
            return new WP_Error( 'mainwp_rest_invalid_plugins_slugs', __( 'Plugins slugs is empty or invalid.', 'mainwp' ), 400 );
        }
        $result = $this->handle_plugins_actions_of_site( $website, 'delete', $slugs );

        if ( is_wp_error( $result ) ) {
            return $result;
        }
        $resp_data = array(
            'success' => ! empty( $result['success'] ) ? 1 : 0,
            'data'    => ! empty( $result['data'] ) ? $result['data'] : array(),
            'site'    => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );

        return rest_ensure_response( $resp_data );
    }

    /**
     * Get abandoned plugins of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function get_abandoned_plugins_of_site( $request ) {

        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }

        // get data.
        $data = MainWP_DB::instance()->get_website_option( $website, 'plugins_outdate_info' );
        $data = ! empty( $data ) ? json_decode( $data, true ) : array();

        $resp_data = array(
            'success' => 1,
            'total'   => is_array( $data ) ? count( $data ) : 0,
            'data'    => $data,
            'site'    => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );

        return rest_ensure_response( $resp_data );
    }


    /**
     * Get themes of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function get_site_themes( $request ) { //phpcs:ignore - NOSONAR - complex.
        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }

        $args = $this->prepare_objects_query( $request );

        $args = $this->validate_rest_args( $args, $this->get_validate_args_params( 'site_themes' ) );
        if ( is_wp_error( $args ) ) {
            return $args;
        }

        if ( isset( $args['status'] ) ) {
            $args['status'] = array_unique( wp_parse_list( $args['status'] ) );
        }

        $data = json_decode( $website->themes, 1 );
        if ( is_array( $data ) ) {
            if ( ! empty( $args['s'] ) ) {
                $s = trim( $args['s'] );
                if ( ! empty( $s ) ) {
                    $data = mainwp_search_in_array(
                        $data,
                        $s,
                        array(
                            'search_in_key'    => false,
                            'in_sub_fields'    => array( 'name', 'description', 'version', 'slug', 'title' ),
                            'use_index_result' => false,
                        )
                    );
                }
            }

            if ( ! empty( $args['status'] ) ) {

                $status_act   = in_array( 'active', $args['status'] ) ? 1 : 0;
                $status_inact = in_array( 'inactive', $args['status'] ) ? 1 : 0;

                $status_val = false;
                if ( $status_act && $status_inact ) {
                    $status_val = false;
                } elseif ( $status_act ) {
                    $status_val = 1;
                } elseif ( $status_inact ) {
                    $status_val = 0;
                }

                if ( false !== $status_val ) {
                    $data = MainWP_Utility::get_sub_array_having( $data, 'active', $status_val );
                }
            }

            if ( ! empty( $args['paged'] ) && ! empty( $args['items_per_page'] ) ) {
                $pag  = (int) $args['paged'];
                $per  = (int) $args['items_per_page'];
                $data = MainWP_Utility::get_sub_array_with_limit( $data, $per * ( $pag - 1 ), $per );
            }
        }

        $resp_data = array(
            'success' => 1,
            'total'   => is_array( $data ) ? count( $data ) : 0,
            'data'    => $data,
            'site'    => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );
        return rest_ensure_response( $resp_data );
    }


    /**
     * Handle plugins actions of site.
     *
     * @param object $website object.
     * @param string $action action.
     * @param string $slugs themes slugs.
     *
     * @return WP_Error|array
     */
    public function handle_theme_actions_of_site( $website, $action, $slugs ) { //phpcs:ignore -- NOSONAR - complex.
        try {
            $information = MainWP_Connect::fetch_url_authed(
                $website,
                'theme_action',
                array(
                    'action' => $action,
                    'theme'  => $slugs,
                )
            );

            if ( ! is_array( $information ) ) {
                $information = array();
            }

            $success = 0;
            $data    = array();

            if ( 'delete' === $action && is_array( $information ) && ! empty( $information['error']['is_activated_theme'] ) ) {
                $data['error'] = sprintf( esc_html__( 'The theme %s is active.', 'mainwp' ), $information['error']['is_activated_theme'] );
            }

            if ( 'activate' === $action && isset( $information['other_data']['theme_deactivate_data'] ) ) {
                $success           = 1;
                $act_slug          = 'deactivate';
                $data[ $act_slug ] = array();
                $action_data       = $information['other_data']['theme_deactivate_data'];
                foreach ( $action_data as $item ) {
                    $success = true;
                    $item    = MainWP_Utility::instance()->sanitize_data( $item );
                    if ( ! empty( $item ) && isset( $item['name'] ) ) {
                        $data[ $act_slug ] = array(
                            'name'    => $item['name'],
                            'version' => $item['version'],
                            'slug'    => $item['slug'],
                        );
                    }
                }
            }

            if ( in_array( $action, array( 'activate', 'delete' ) ) && isset( $information['other_data']['theme_action_data'] ) ) {
                $success = 1;
                if ( 'activate' === $action ) {
                    $act_slug = 'activate';
                } else {
                    $act_slug = 'delete';
                }
                $data[ $act_slug ] = array();
                $action_data       = $information['other_data']['theme_action_data'];
                foreach ( $action_data as $item ) {
                    $success = true;
                    $item    = MainWP_Utility::instance()->sanitize_data( $item );
                    if ( ! empty( $item ) && isset( $item['name'] ) ) {
                        $data[ $act_slug ] = array(
                            'name'    => $item['name'],
                            'version' => $item['version'],
                            'slug'    => $item['slug'],
                        );
                    }
                }
            }

            return array(
                'success' => $success,
                'data'    => $data,
            );

        } catch ( \Exception $e ) {
            return new WP_Error( "mainwp_rest_{$action}_plugins_action", $e->getMessage() );
        }
    }


    /**
     * Activate themes of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function activate_themes_of_site( $request ) {
        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }

        $slugs = isset( $request['slug'] ) && is_string( $request['slug'] ) ? trim( $request['slug'] ) : '';
        if ( empty( $slugs ) ) {
            return new WP_Error( 'mainwp_rest_invalid_themes_slugs', __( 'Theme slug is empty or invalid.', 'mainwp' ), 400 );
        }

        $result = $this->handle_theme_actions_of_site( $website, 'activate', $slugs );

        if ( is_wp_error( $result ) ) {
            return $result;
        }
        $resp_data = array(
            'success' => ! empty( $result['success'] ) ? 1 : 0,
            'data'    => ! empty( $result['data'] ) ? $result['data'] : array(),
            'site'    => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );

        return rest_ensure_response( $resp_data );
    }


    /**
     * Delete themes of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function delete_themes_of_site( $request ) {

        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }

        $slugs = isset( $request['slug'] ) ? array_map( 'trim', wp_parse_list( $request['slug'] ) ) : array();
        if ( empty( $slugs ) ) {
            return new WP_Error( 'mainwp_rest_invalid_themes_slugs', __( 'Theme slug is empty or invalid.', 'mainwp' ), 400 );
        }

        $result = $this->handle_theme_actions_of_site( $website, 'delete', implode( '||', $slugs ) );

        if ( is_wp_error( $result ) ) {
            return $result;
        }
        $resp_data = array(
            'success' => ! empty( $result['success'] ) ? 1 : 0,
            'data'    => ! empty( $result['data'] ) ? $result['data'] : array(),
            'site'    => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );

        return rest_ensure_response( $resp_data );
    }


    /**
     * Get abandoned themes of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function get_abandoned_themes_of_site( $request ) {

        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }

        // get data.
        $data = MainWP_DB::instance()->get_website_option( $website, 'themes_outdate_info' );
        $data = ! empty( $data ) ? json_decode( $data, true ) : array();

        $resp_data = array(
            'success' => 1,
            'total'   => is_array( $data ) ? count( $data ) : 0,
            'data'    => $data,
            'site'    => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );

        return rest_ensure_response( $resp_data );
    }

    /**
     * Get non-mainwp changes of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function get_non_mainwp_changes_of_site( $request ) { //phpcs:ignore -- NOSONAR -complex.

        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }

        $args = $this->prepare_objects_query( $request );

        $params = array(
            'wpid'        => $website->id,
            'where_extra' => ' AND dismiss = 0 ',
            'order'       => ! empty( $args['order'] ) ? sanitize_text_field( wp_unslash( $args['order'] ) ) : '',
            'order_by'    => ! empty( $args['orderby'] ) ? sanitize_text_field( wp_unslash( $args['orderby'] ) ) : '',
            'source'      => ! empty( $request['source'] ) ? sanitize_text_field( wp_unslash( $request['source'] ) ) : 'wpadmin',
        );

        if ( ! empty( $args['paged'] ) && ! empty( $args['items_per_page'] ) ) {
            $params['rowcount'] = intval( $args['items_per_page'] );
            $params['offset']   = ( (int) ( $args['paged'] ) - 1 ) * $params['rowcount'];
        } else {
            // support compatible api param.
            $limit              = ! empty( $args['limit'] ) ? (int) ( $args['limit'] ) : 200;
            $params['rowcount'] = $limit;
            $params['offset']   = 0;
        }

        $params['actions']     = ! empty( $request['actions'] ) ? sanitize_text_field( wp_unslash( $request['actions'] ) ) : '';
        $params['contexts']    = ! empty( $request['contexts'] ) ? sanitize_text_field( wp_unslash( $request['contexts'] ) ) : '';
        $params['total_count'] = ! empty( $request['total_count'] ) ? mainwp_string_to_bool( $request['total_count'] ) : false;

        $data = MainWP_DB_Site_Actions::instance()->get_wp_actions( $params, $website );

        if ( $params['total_count'] ) {
            $total = $data;
            $data  = array( 'total' => $total );
        } else {
            $total = is_array( $data ) ? count( $data ) : 0;
        }

        $resp_data = array(
            'success' => 1,
            'total'   => $total,
            'data'    => $data,
            'site'    => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );
        return rest_ensure_response( $resp_data );
    }

    /**
     * Sync all sites.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function sync_items( $request ) {

        $args   = $this->prepare_objects_query( $request );
        $params = array(
            'exclude' => isset( $args['exclude'] ) && ! empty( $args['exclude'] ) ? $args['exclude'] : array(),
            'include' => isset( $args['include'] ) && ! empty( $args['include'] ) ? $args['include'] : array(),
        );

        $data     = array();
        $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user( false, null, 'wp.url', false, false, null, false, array( 'favi_icon' ), 'no', $params ) );
        while ( $websites && ( $website  = MainWP_DB::fetch_object( $websites ) ) ) {
            try {
                $ret = MainWP_Sync::sync_site( $website );
            } catch ( \Exception $e ) {
                $ret = false;
            }
            $item                 = $this->filter_response_data_by_allowed_fields( $this->prepare_item_for_response( $website, $request ), 'view' );
            $data[ $website->id ] = array_merge( array( 'result' => $ret ? 'success' : 'failed' ), $item );
        }
        MainWP_DB::free_result( $websites );
        update_option( 'mainwp_last_synced_all_sites', time() );
        return rest_ensure_response(
            array(
                'total' => count( $data ),
                'data'  => $data,
            )
        );
    }

    /**
     * Reconnect site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function reconnect_item( $request ) {
        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }
        $resp_data = array();
        try {
            $ret                  = MainWP_Manage_Sites_View::m_reconnect_site( $website );
            $resp_data['success'] = $ret ? 1 : 0;
        } catch ( \Exception $e ) {
            // failed.
            return new \WP_Error( 'mainwp_rest_reconnect_site_error', sprintf( esc_html__( 'Reconnect Site "%d" error:', 'mainwp' ), $website->id ) . ': ' . $e->getMessage() );
        }
        $website           = $this->get_site_by( 'id', $website->id );
        $resp_data['data'] = $this->filter_response_data_by_allowed_fields( $website, 'simple_view' );
        return rest_ensure_response( $resp_data );
    }

    /**
     * Reconnect sites.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function reconnect_items( $request ) {

        $args   = $this->prepare_objects_query( $request );
        $params = array(
            'exclude' => isset( $args['exclude'] ) && ! empty( $args['exclude'] ) ? $args['exclude'] : array(),
            'include' => isset( $args['include'] ) && ! empty( $args['include'] ) ? $args['include'] : array(),
        );

        $data     = array();
        $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user( false, null, 'wp.url', false, false, null, false, array( 'favi_icon' ), 'no', $params ) );
        while ( $websites && ( $website  = MainWP_DB::fetch_object( $websites ) ) && '' !== $website->sync_errors ) {
            $ret = false;
            try {
                $ret = MainWP_Manage_Sites_View::m_reconnect_site( $website );
            } catch ( \Exception $e ) {
                // failed.
            }
            $data[ $website->id ] = $ret ? 'success' : 'failed';
        }
        MainWP_DB::free_result( $websites );
        return rest_ensure_response(
            array(
                'total' => count( $data ),
                'data'  => $data,
            )
        );
    }


    /**
     * Disconnect site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return array|mixed Response data, ready for insertion into collection data.
     */
    public function disconnect_site( $request ) {

        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }

        $data = $this->filter_response_data_by_allowed_fields( $website, 'simple_view' );

        $success = 0;
        $error   = '';
        try {
            $info    = MainWP_Connect::fetch_url_authed( $website, 'disconnect' );
            $success = is_array( $info ) && isset( $info['result'] ) && 'success' === $info['result'] ? 1 : 0;
            $error   = is_array( $info ) && ! empty( $info['error'] ) ? $info['error'] : '';
        } catch ( \Exception $e ) {
            return new \WP_Error( 'mainwp_rest_disconnect_site_error', sprintf( esc_html__( 'Disconnect Site "%d" error:', 'mainwp' ), $website->id ) . ': ' . $e->getMessage() );
        }
        $resp_data = array(
            'success' => $success,
            'data'    => $data,
        );
        if ( ! empty( $error ) ) {
            $resp_data['error'] = $error;
        }
        return rest_ensure_response( $resp_data );
    }


    /**
     * Suspend site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return array|mixed Response data, ready for insertion into collection data.
     */
    public function suspend_item( $request ) {
        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }
        $suspended = 1;
        if ( $website && ! $website->suspended ) { //phpcs:ignore -- to valid.
            $newValues = array(
                'suspended' => $suspended,
            );

            MainWP_DB::instance()->update_website_values( $website->id, $newValues );
            /**
             * Fires immediately after website suspended/unsuspend.
             *
             * @since 4.5.2
             *
             * @param object $website  website data.
             * @param int $suspended The new suspended value.
             */
            do_action( 'mainwp_site_suspended', $website, $suspended );
        }

        $resp_data = array(
            'success'   => 1,
            'suspended' => $suspended,
            'data'      => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );

        return rest_ensure_response( $resp_data );
    }


    /**
     * Unsuspend site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return array|mixed Response data, ready for insertion into collection data.
     */
    public function unsuspend_item( $request ) {
        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }
        $suspended = 0;
        if ( $website && $website->suspended ) { //phpcs:ignore -- to valid.
            $newValues = array(
                'suspended' => $suspended,
            );

            MainWP_DB::instance()->update_website_values( $website->id, $newValues );
            /**
             * Fires immediately after website suspended/unsuspend.
             *
             * @since 4.5.2
             *
             * @param object $website  website data.
             * @param int $suspended The new suspended value.
             */
            do_action( 'mainwp_site_suspended', $website, $suspended );
        }
        $resp_data = array(
            'success'   => 1,
            'suspended' => $suspended,
            'data'      => $this->filter_response_data_by_allowed_fields( $website, 'simple_view' ),
        );
        return rest_ensure_response( $resp_data );
    }

    /**
     * Disconnect sites.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function disconnect_sites( $request ) {

        $args     = $this->prepare_objects_query( $request );
        $params   = array(
            'view'    => 'base_view',
            'exclude' => isset( $args['exclude'] ) && ! empty( $args['exclude'] ) ? $args['exclude'] : array(),
            'include' => isset( $args['include'] ) && ! empty( $args['include'] ) ? $args['include'] : array(),
        );
        $data     = array();
        $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user_by_params( $params ) );
        while ( $websites && ( $website  = MainWP_DB::fetch_object( $websites ) ) ) {
            $info = false;
            try {
                $info = MainWP_Connect::fetch_url_authed( $website, 'disconnect' );
            } catch ( \Exception $e ) {
                // ok.
            }
            $success = 0;
            if ( is_array( $info ) ) {
                $success = isset( $info['result'] ) ? 1 : 0;
            }
            $data[ $website->id ] = $success ? 'success' : 'failed';
        }
        MainWP_DB::free_result( $websites );
        return rest_ensure_response(
            array(
                'total' => count( $data ),
                'data'  => $data,
            )
        );
    }

    /**
     * Check site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function check_item( $request ) {

        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }

        $error = '';
        try {
            $ret = MainWP_Monitoring_Handler::handle_check_website( $website );
        } catch ( \Exception $e ) {
            $ret   = false;
            $error = $e->getMessage();
        }

        $resp_data = array( 'success' => $ret ? 1 : 0 );
        $new_code  = is_array( $ret ) && isset( $ret['httpCode'] ) ? $ret['httpCode'] : false;

        if ( ! empty( $error ) ) {
            $resp_data ['error'] = esc_html( $result );
        }

        $data = $this->filter_response_data_by_allowed_fields( $website, 'simple_view' );

        if ( false !== $new_code ) {
            if ( is_array( $result ) && isset( $result['new_uptime_status'] ) ) {
                $data['status'] = $result['new_uptime_status'];
            } else {
                $data['status'] = MainWP_Monitoring_Handler::get_site_checking_status( $new_code );
            }
            $data['http_code'] = $new_code;
        }

        $resp_data['data'] = $data;

        return rest_ensure_response( $resp_data );
    }

    /**
     * Check sites.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function check_items( $request ) {
        $args     = $this->prepare_objects_query( $request );
        $params   = array(
            'exclude' => isset( $args['exclude'] ) && ! empty( $args['exclude'] ) ? $args['exclude'] : array(),
            'include' => isset( $args['include'] ) && ! empty( $args['include'] ) ? $args['include'] : array(),
        );
        $data     = array();
        $websites = MainWP_DB::instance()->query( MainWP_DB::instance()->get_sql_websites_for_current_user( false, null, 'wp.url', false, false, null, false, array( 'favi_icon' ), 'no', $params ) );
        while ( $websites && ( $website  = MainWP_DB::fetch_object( $websites ) ) ) {
            try {
                $ret = MainWP_Monitoring_Handler::handle_check_website( $website );
            } catch ( \Exception $e ) {
                $ret = false;
            }
            $item                 = $this->filter_response_data_by_allowed_fields( $this->prepare_item_for_response( $website, $request ), 'view' );
            $data[ $website->id ] = array_merge( array( 'result' => $ret ? 'success' : 'failed' ), $item );
        }
        MainWP_DB::free_result( $websites );
        return rest_ensure_response(
            array(
                'total' => count( $data ),
                'data'  => $data,
            )
        );
    }

    /**
     * Remove site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function delete_item( $request ) {

        $website = $this->get_request_item( $request );

        if ( is_wp_error( $website ) ) {
            return $website;
        }

        $error  = '';
        $result = false;

        try {
            $result = MainWP_Manage_Sites_Handler::remove_wp_site( $website->id );
        } catch ( MainWP_Extra_Exception $e ) {
            $error = $e->getMessage();
        }

        $success = ( is_array( $result ) && isset( $result['result'] ) && ( 'success' === $result['result'] || 'removed' === $result['result'] ) ) ? 1 : 0;

        $resp_data = array(
            'success' => $success,
        );

        if ( is_array( $result ) && ! empty( $result['result'] ) ) {
            if ( 'success' === $result['result'] ) {
                $message = esc_html__( 'The site has been removed and the MainWP Child plugin has been disabled.', 'mainwp' );
            } else {
                $message = esc_html__( 'The site has been removed. Please make sure that the MainWP Child plugin has been deactivated properly.', 'mainwp' );
            }
            $resp_data['message'] = $message;
        }

        if ( ! empty( $error ) ) {
            $resp_data['error'] = $error;
        }

        $resp_data['data'] = $this->filter_response_data_by_allowed_fields( $website, 'simple_view' );

        return rest_ensure_response( $resp_data );
    }

    /**
     * Get client of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function get_client_site( $request ) {
        $website = $this->get_request_item( $request );

        if ( is_wp_error( $website ) ) {
            return $website;
        }

        $client = false;
        if ( $website->client_id ) {
            $client = MainWP_DB_Client::instance()->get_wp_client_by( 'client_id', $website->client_id );
        }

        $resp_data = array(
            'success' => $client ? 1 : 0,
        );

        if ( empty( $client ) ) {
            $resp_data['error'] = esc_html__( 'Client is not set or not found.', 'mainwp' );
        } else {
            $resp_data['data'] = $client;
        }

        return rest_ensure_response( $resp_data );
    }

    /**
     * Get costs of site.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function get_costs_site( $request ) {
        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }
        $resp_data = array(
            'success' => 1,
        );
        $costs     = Cost_Tracker_DB::get_instance()->get_cost_tracker_by( 'site_id', $website->id );
        if ( $costs ) {
            $data               = Cost_Tracker_Rest_Api_Handle_V1::instance()->prepare_api_costs_data( $costs );
            $resp_data['total'] = is_array( $data ) ? count( $data ) : 0;
            $resp_data['data']  = $data;
        } else {
            $resp_data['message'] = esc_html__( 'Cost not found.', 'mainwp' );
            $resp_data['data']    = array();
        }
        return rest_ensure_response( $resp_data );
    }

    /**
     * Get site by.
     *
     * @param WP_REST_Request $request Full details about the request.
     *
     * @return WP_Error|Object Item.
     */
    public function get_request_item( $request ) {
        return $this->get_site_item( $request );
    }


    /**
     * Get the location schema, conforming to JSON Schema.
     *
     * @since  3.5.0
     * @return array
     */
    public function get_item_schema() { //phpcs:ignore -- NOSONAR - long function.
        return array(
            '$schema'    => 'http://json-schema.org/draft-04/schema#',
            'title'      => 'sites',
            'type'       => 'object',
            'properties' => array(
                'id'                     => array(
                    'type'        => 'integer',
                    'description' => __( 'Site ID.', 'mainwp' ),
                    'context'     => array( 'view', 'edit', 'simple_view' ),
                    'arg_options' => array(
                        'sanitize_callback' => 'wp_parse_id_list',
                    ),
                ),
                'name'                   => array(
                    'type'        => 'string',
                    'description' => __( 'Site name.', 'mainwp' ),
                    'context'     => array( 'view', 'edit', 'simple_view' ),
                    'arg_options' => array(
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                ),
                'url'                    => array(
                    'type'        => 'string',
                    'description' => __( 'Site url.', 'mainwp' ),
                    'context'     => array( 'view', 'edit', 'simple_view' ),
                    'arg_options' => array(
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                ),
                'tags'                   => array( // response as tags.
                    'type'        => 'string',
                    'description' => __( 'Site tags.', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'note'                   => array(
                    'type'        => 'string',
                    'description' => __( 'Site note.', 'mainwp' ),
                    'context'     => array( 'view', 'edit' ),
                ),
                'ip'                     => array(
                    'type'        => 'string',
                    'description' => __( 'Site IP.', 'mainwp' ),
                    'context'     => array( 'view' ),
                    'arg_options' => array(
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                ),
                'client_id'              => array(
                    'type'        => 'integer',
                    'default'     => 0,
                    'description' => __( 'Client id', 'mainwp' ),
                    'context'     => array( 'view', 'simple_view' ),
                ),
                'is_staging'             => array(
                    'type'        => 'integer',
                    'default'     => 0,
                    'description' => __( 'is staging', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'wp_version'             => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'wp version', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'php_version'            => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'php version', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'child_version'          => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'child version', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'mysql_version'          => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'mysql version', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'memory_limit'           => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'memory limit', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'database_size'          => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Database size', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'active_theme'           => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Active theme', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'status'                 => array(
                    'type'        => array( 'string', 'array' ),
                    'default'     => '',
                    'description' => __( 'Status', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'sync_errors'            => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Sync errors', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'http_status'            => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Http status', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'health_status'          => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Health status', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'health_score'           => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Health score', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'icon'                   => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Icon', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'last_sync'              => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Last sync', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'plugins'                => array(
                    'type'        => array( 'string', 'array' ),
                    'default'     => '',
                    'description' => __( 'Plugins', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'themes'                 => array(
                    'type'        => array( 'string', 'array' ),
                    'default'     => '',
                    'description' => __( 'Themes', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'last_post_time'         => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Last post time', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'recent_posts'           => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Recent posts', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'recent_pages'           => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Recent pages', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'recent_comments'        => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Recent comments', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'categories'             => array(
                    'type'        => 'string',
                    'default'     => '',
                    'description' => __( 'Categories', 'mainwp' ),
                    'context'     => array( 'view' ),
                ),
                'wp_upgrades'            => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'plugin_upgrades'        => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'premium_upgrades'       => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'theme_upgrades'         => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'translation_upgrades'   => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'ignored_plugins'        => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'ignored_themes'         => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'automatic_update'       => array(
                    'type'        => 'integer',
                    'default'     => 0,
                    'description' => __( 'Automatic update', 'mainwp' ),
                    'context'     => array( 'edit' ),
                    'enum'        => array( 0, 1 ),
                    'arg_options' => array(
                        'sanitize_callback' => 'absint',
                    ),
                ),
                'http_user'              => array(
                    'type'        => 'string',
                    'description' => __( 'HTTP user', 'mainwp' ),
                    'context'     => array( 'view', 'edit' ),
                    'arg_options' => array(
                        'sanitize_callback' => 'sanitize_text_field',
                    ),
                ),
                'http_pass'              => array(
                    'type'        => 'string',
                    'description' => __( 'HTTP password', 'mainwp' ),
                    'context'     => array( 'view', 'edit' ), // no need to sanitize pass.
                ),
                'uniqueId'               => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'disable_health_check'   => array(
                    'type'        => 'integer',
                    'default'     => 0,
                    'description' => __( 'Disable health check', 'mainwp' ),
                    'context'     => array( 'edit' ),
                    'enum'        => array( 0, 1 ),
                    'arg_options' => array(
                        'sanitize_callback' => 'absint',
                    ),
                ),
                'health_threshold'       => array(
                    'type'        => 'integer',
                    'default'     => 0,
                    'description' => __( 'Health threshold', 'mainwp' ),
                    'context'     => array( 'edit' ),
                    'arg_options' => array(
                        'sanitize_callback' => 'absint',
                    ),
                ),
                'is_ignoreCoreUpdates'   => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'is_ignorePluginUpdates' => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'is_ignoreThemeUpdates'  => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'verify_certificate'     => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'force_use_ipv4'         => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'ssl_version'            => array(
                    'type'    => 'string',
                    'default' => '',
                    'context' => array( 'view' ),
                ),
                'suspended'              => array(
                    'type'        => 'integer',
                    'default'     => 0,
                    'description' => __( 'Suspended', 'mainwp' ),
                    'context'     => array( 'view', 'edit' ),
                    'enum'        => array( 0, 1 ),
                    'arg_options' => array(
                        'sanitize_callback' => 'absint',
                    ),
                ),

            ),
        );
    }


    /**
     * Prepare a single order for create or update.
     *
     * @throws MainWP_Rest_Data_Exception When fails to set any item.
     * @param  WP_REST_Request $request Request object.
     * @return array
     */
    protected function prepare_object_for_database( $request ) {
        $item_fields                   = array();
        $item_fields['url']            = isset( $request['url'] ) ? sanitize_text_field( wp_unslash( $request['url'] ) ) : '';
        $item_fields['name']           = isset( $request['name'] ) ? sanitize_text_field( wp_unslash( $request['name'] ) ) : '';
        $item_fields['wpadmin']        = isset( $request['admin'] ) ? sanitize_text_field( wp_unslash( $request['admin'] ) ) : '';
        $item_fields['adminpwd']       = isset( $request['adminpassword'] ) ? wp_unslash( $request['adminpassword'] ) : '';
        $item_fields['unique_id']      = isset( $request['uniqueid'] ) ? sanitize_text_field( wp_unslash( $request['uniqueid'] ) ) : '';
        $item_fields['ssl_verify']     = empty( $request['ssl_verify'] ) ? false : intval( $request['ssl_verify'] );
        $item_fields['force_use_ipv4'] = isset( $request['force_use_ipv4'] ) && mainwp_string_to_bool( $request['force_use_ipv4'] ) ? 1 : 0;
        $item_fields['http_user']      = isset( $request['http_user'] ) ? sanitize_text_field( wp_unslash( $request['http_user'] ) ) : '';
        $item_fields['http_pass']      = isset( $request['http_pass'] ) ? wp_unslash( $request['http_pass'] ) : '';
        $item_fields['groupids']       = isset( $request['groupids'] ) && ! empty( $request['groupids'] ) ? explode( ',', sanitize_text_field( wp_unslash( $request['groupids'] ) ) ) : array();

        /**
         * Filters an object before it is inserted via the REST API.
         *
         * @since 5.2
         *
         * @param array         $item_fields    Site data.
         * @param WP_REST_Request $request  Request object.
         */
        return apply_filters( 'mainwp_rest_pre_insert_site_item', $item_fields, $request );
    }

    /**
     * Prepare a single order for create or update.
     *
     * @param  WP_REST_Request $request Request object.
     * @return array
     */
    protected function prepare_object_for_update( $request ) {

        $map_fields_update = array(
            'http_user'              => 'http_user',
            'http_pass'              => 'http_pass',
            'name'                   => 'name',
            'adminname'              => 'admin',
            'ssl_version'            => 'sslversion',
            'uniqueId'               => 'uniqueid',
            'protocol'               => 'protocol',
            'disable_health_check'   => 'disablehealthchecking',
            'health_threshold'       => 'healththreshold',
            'suspended'              => 'suspended',
            'groupids'               => 'groupids',
            'automatic_update'       => 'automatic_update',
            'backup_before_upgrade'  => 'backup_before_upgrade',
            'force_use_ipv4'         => 'force_use_ipv4',
            'is_ignoreCoreUpdates'   => 'ignore_core_updates',
            'is_ignorePluginUpdates' => 'ignore_plugin_updates',
            'is_ignoreThemeUpdates'  => 'ignore_theme_updates',
            'monitoring_emails'      => 'monitoring_emails',
        );

        $data = array();
        foreach ( $map_fields_update as $field ) {
            if ( isset( $request[ $field ] ) ) {
                $data[ $field ] = $request[ $field ];
            }
        }

        /**
         * Filters an object before it is inserted via the REST API.
         *
         * @since 5.2
         *
         * @param array         $item_fields    Site data.
         * @param WP_REST_Request $request  Request object.
         */
        return apply_filters( 'mainwp_rest_pre_update_site_item', $data, $request );
    }

    /**
     * Get formatted item object.
     *
     * @since  5.2
     * @param  object $site_object Site object.
     * @param  array  $args Request args.
     *
     * @return array
     */
    protected function get_pre_formatted_item_data( $site_object, $args = array() ) {

        $fields = false;
        // Determine if the response fields were specified.
        if ( ! empty( $this->request['_fields'] ) ) {
            $fields = wp_parse_list( $this->request['_fields'] );

            if ( 0 === count( $fields ) ) {
                $fields = false;
            } else {
                $fields = array_map( 'trim', $fields );
            }
        }

        $extra_fields = array();
        $extra_fields = false === $fields ? $extra_fields : array_intersect( $extra_fields, $fields );

        $formatted_data = array(
            'id'        => $site_object->id,
            'url'       => $site_object->url,
            'name'      => $site_object->name,
            'client_id' => $site_object->client_id,
        );

        if ( ! empty( $args['selectgroups'] ) ) {
            $formatted_data['wpgroups'] = $site_object->wpgroups;
        }

        if ( ! empty( $args['full_data'] ) ) {
            $formatted_extra = array(
                'id'                   => $site_object->id,
                'url'                  => $site_object->url,
                'name'                 => $site_object->name,
                'offline_checks_last'  => $site_object->offline_checks_last,
                'offline_check_result' => $site_object->offline_check_result, // 1 - online, -1 offline.
                'http_response_code'   => $site_object->http_response_code,
                'disable_health_check' => $site_object->disable_health_check,
                'health_threshold'     => $site_object->health_threshold,
                'note'                 => $site_object->note,
                'plugin_upgrades'      => $site_object->plugin_upgrades,
                'theme_upgrades'       => $site_object->theme_upgrades,
                'translation_upgrades' => $site_object->translation_upgrades,
                'securityIssues'       => $site_object->securityIssues,
                'themes'               => $site_object->themes,
                'plugins'              => $site_object->plugins,
                'automatic_update'     => ! empty( $site_object->automatic_update ) ? $site_object->automatic_update : 0,
                'sync_errors'          => $site_object->sync_errors,
                'last_post_gmt'        => $site_object->last_post_gmt,
                'health_value'         => $site_object->health_value,
                'phpversion'           => $site_object->phpversion,
                'wp_upgrades'          => $site_object->wp_upgrades,
                'security_stats'       => $site_object->security_stats,
                'client_id'            => $site_object->client_id,
                'adminname'            => $site_object->adminname,
                'http_user'            => $site_object->http_user,
                'http_pass'            => $site_object->http_pass,
                'ssl_version'          => $site_object->ssl_version,
                'signature_algo'       => $site_object->signature_algo,
                'verify_method'        => $site_object->verify_method,
                'verify_certificate'   => $site_object->verify_certificate,
            );

            $format_date = array( 'dtsAutomaticSync', 'dtsAutomaticSyncStart', 'dtsSync', 'dtsSyncStart' );
            // Format date values.
            foreach ( $format_date as $key ) {
                // Date created is stored UTC, date modified is stored WP local time.
                $datetime                = get_date_from_gmt( gmdate( 'Y-m-d H:i:s', $site_object->$key ) );
                $formatted_extra[ $key ] = mainwp_rest_prepare_date_response( $datetime, false );
            }

            $formatted_data = array_merge( $formatted_data, $formatted_extra );
        }

        return $formatted_data;
    }

    /**
     * Prepare a single product review output for response.
     *
     * @param object          $item site object.
     * @param WP_REST_Request $request Request object.
     * @param array           $args args.
     *
     * @return WP_REST_Response $response Response data.
     */
    public function prepare_item_for_response( $item, $request, $args = array() ) { //phpcs:ignore -- NOSONAR - complex.

        if ( ! is_object( $item ) ) {
            $item = new \stdClass();
        }

        $fields = $this->get_fields_for_response( $request );

        if ( ! is_array( $fields ) ) {
            $fields = array();
        }

        $context = ! empty( $request['context'] ) ? $request['context'] : 'view';

        $data = $this->filter_response_by_context( $item, $context );

        if ( is_object( $data ) ) {
            $_data = array();
            foreach ( $data as $field => $value ) {
                $_data[ $field ] = $value;
            }
            $data = $_data;
        }

        if ( in_array( 'tags', $fields ) && property_exists( $item, 'wpgroups' ) && property_exists( $item, 'wpgroupids' ) ) {
            $wpgroupids = ! empty( $item->wpgroupids ) ? explode( ',', $item->wpgroupids ) : array();
            $wpgroups   = ! empty( $item->wpgroups ) ? explode( ',', $item->wpgroups ) : array();

            $tags = array();
            if ( is_array( $wpgroupids ) ) {
                foreach ( $wpgroupids as $gidx => $groupid ) {
                    if ( $groupid && ! isset( $tags[ $groupid ] ) ) {
                        $tags[ $groupid ] = isset( $wpgroups[ $gidx ] ) ? $wpgroups[ $gidx ] : '';
                    }
                }
            }
            $data['tags'] = $tags;
        }

        $map_fields = array(
            'database_size'  => 'dbsize',
            'http_status'    => 'http_response_code',
            'health_score'   => 'health_value',
            'icon'           => 'cust_site_icon_info',
            'last_sync'      => 'dtsSync',
            'last_post_time' => 'last_post_gmt',
        );

        if ( is_array( $data ) ) {
            foreach ( $map_fields as $field1 => $field2 ) {
                if ( in_array( $field1, $fields ) && property_exists( $item, $field2 ) ) {
                    $data[ $field1 ] = $item->{$field2};
                }
            }
        }

        $website_info = MainWP_DB::instance()->get_website_option( $item->id, 'site_info' );
        $website_info = ! empty( $website_info ) ? json_decode( $website_info, true ) : array();

        if ( is_array( $website_info ) && property_exists( $item, 'http_response_code' ) ) {
            $code        = $item->http_response_code;
            $code_string = MainWP_Utility::get_http_codes( $code );
            if ( ! empty( $code_string ) ) {
                $code .= ' - ' . $code_string;
            }
            $website_info['http_status'] = $code;
        }

        $map_meta_fields = array(
            'wp_version'    => 'wpversion',
            'php_version'   => 'phpversion',
            'child_version' => 'child_version',
            'mysql_version' => 'mysql_version',
            'memory_limit'  => 'memory_limit',
            'http_status'   => 'http_status',
        );

        foreach ( $map_meta_fields as $_field1 => $_field2 ) {
            if ( in_array( $_field1, $fields ) ) {
                $data[ $_field1 ] = isset( $website_info[ $_field2 ] ) ? $website_info[ $_field2 ] : '';
            }
        }

        if ( in_array( 'active_theme', $fields ) ) {
            $active_theme = array();
            if ( ! empty( $item->themes ) ) {
                $themes = json_decode( $item->themes, 1 );
                if ( is_array( $themes ) && ! empty( $themes ) ) {
                    foreach ( $themes as $theme ) {
                        if ( ! empty( $theme['active'] ) ) {
                            $active_theme = $theme;
                            break;
                        }
                    }
                }
            }
            $data['active_theme'] = is_array( $active_theme ) && ! empty( $active_theme['name'] ) ? esc_html( $active_theme['name'] . ' ' . $active_theme['version'] ) : '';
        }

        if ( in_array( 'status', $fields ) ) {
            $data['status'] = ! empty( $item->sync_errors ) ? 'disconnected' : 'connected';
            if ( $item->suspended ) {
                $data['status'] = 'suspended';
            }
        }

        if ( is_array( $fields ) && ! empty( $fields ) ) {
            $_data = array();
            foreach ( $data as $field => $value ) {
                if ( in_array( $field, $fields ) ) {
                    $_data[ $field ] = $value;
                }
            }
            $data = $_data;
        }

        if ( isset( $data['last_sync'] ) ) {
            $data['last_sync'] = mainwp_rest_prepare_date_response( $data['last_sync'] );
        }

        /**
         * Filterobject returned from the REST API.
         *
         * @param array $data The object.
         * @param mixed       $item   The object used to create response.
         * @param WP_REST_Request  $request  Request object.
         */
        return apply_filters( 'mainwp_rest_prepare_site', $data, $item, $request );
    }

    /**
     * Add Site.
     *
     * @since  5.2
     * @throws Exception But all errors are validated before returning any data.
     *
     * @param  WP_REST_Request $request  Full details about the request.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function create_item( $request ) {  //phpcs:ignore -- NOSONAR - complex.
        $resp_data            = array();
        $resp_data['success'] = 0;
        $site_id              = 0;
        $url                  = '';
        $data                 = array(); //phpcs:ignore -- NOSONAR - not used data.
        $found_id             = 0;
        try {
            $item = $this->prepare_object_for_database( $request );

            if ( empty( $item['name'] ) && ! empty( $item['url'] ) ) {
                $item['name'] = MainWP_Utility::remove_http_prefix( $item['url'], true );
                $item['name'] = rtrim( $item['name'], '/' );
            }

            $url     = $item['url'];
            $website = MainWP_DB::instance()->get_websites_by_url( $item['url'] );
            list( $message, $error, $site_id, $found_id ) = MainWP_Manage_Sites_View::add_wp_site( $website, $item );

            if ( ! empty( $site_id ) ) {
                $site                 = MainWP_DB::instance()->get_website_by_id( $site_id );
                $resp_data['success'] = 1;
                $resp_data['data']    = $this->filter_response_data_by_allowed_fields( $site, 'simple_view' );

                if ( ! empty( $message ) ) {
                    $resp_data['message'] = wp_strip_all_tags( $message );
                }
            } elseif ( ! empty( $error ) ) {
                $resp_data['error'] = wp_strip_all_tags( $error );
            } else {
                $resp_data['error'] = esc_html__( 'Add site failed. Please try again.', 'mainwp' );
            }
        } catch ( Exception $e ) {
            $resp_data['error'] = wp_strip_all_tags( $e->getMessage() );
        }

        $user                 = $this->get_rest_api_user();
        $is_dashboard_connect = ! empty( $user ) && 1 === (int) $user->key_type ? true : false;

        if ( $is_dashboard_connect ) {
            if ( ! empty( $resp_data['error'] ) ) {
                MainWP_Logger::instance()->log_action( 'Dashboard Connect add Site :: [url=' . $url . '] :: [result=Failed] :: [error=' . esc_html( $resp_data['error'] ) . ']', MainWP_Logger::CONNECT_LOG_PRIORITY );
            } elseif ( ! empty( $resp_data['success'] ) ) {
                MainWP_Logger::instance()->log_action( 'Dashboard Connect add Site :: [url=' . $url . '] :: [result=Success]', MainWP_Logger::CONNECT_LOG_PRIORITY );
            }
        }

        if ( ! empty( $found_id ) ) {
            $resp_data['found_id'] = $found_id;
            // if found connected and is dashboard connect request then try to reconnect to prevent incorrect connection.
            if ( $is_dashboard_connect ) {
                $reconnect = false;
                $site      = MainWP_DB::instance()->get_website_by_id( $found_id );
                try {
                    $reconnect                      = MainWP_Manage_Sites_View::m_reconnect_site( $site );
                    $resp_data['reconnect_success'] = $reconnect ? 1 : 0;
                } catch ( \Exception $e ) {
                    // failed.
                    $resp_data['reconnect_error'] = $e->getMessage();
                }
                MainWP_Logger::instance()->log_action( 'Dashboard Connect reconnect site :: [url=' . $url . '] :: [result=' . ( $reconnect ? 'success' : 'failed' ) . ']', MainWP_Logger::CONNECT_LOG_PRIORITY );
            }
        }

        return rest_ensure_response( $resp_data );
    }

    /**
     * Update site.
     *
     * @param  WP_REST_Request $request Request object.
     *
     * @return WP_Error|WP_REST_Response
     */
    public function update_item( $request ) {
        $website = $this->get_request_item( $request );
        if ( is_wp_error( $website ) ) {
            return $website;
        }
        $resp_data            = array();
        $resp_data['success'] = 0;
        try {
            $item   = $this->prepare_object_for_update( $request );
            $result = MainWP_DB_Common::instance()->rest_api_update_website( $website->id, $item );
            if ( is_array( $result ) && ! empty( $result['success'] ) ) {
                    $resp_data['success'] = 1;
                    $params               = array(
                        'full_data'    => true,
                        'selectgroups' => true,
                        'include'      => array( $website->id ),
                        'fields'       => $this->get_fields_for_response( $request ),
                    );
                    $websites             = MainWP_DB::instance()->get_websites_for_current_user( $params );
                    $data                 = $websites ? current( $websites ) : array();
                    $resp_data['data']    = $this->filter_response_data_by_allowed_fields( $this->prepare_item_for_response( $data, $request ), 'view' );
            } else {
                $resp_data['error'] = esc_html__( 'Update site failed. Please try again.', 'mainwp' );
            }
        } catch ( \Exception $e ) {
            $resp_data['error'] = $e->getMessage();
        }
        return rest_ensure_response( $resp_data );
    }
}
