<?php

/**
 * REST API
 * Handles all REST API requests for admin area
 *
 * @since 1.1.0
 * @package RVIOR
 */

// Namespace.
namespace RVIOR\Admin;

// Exit if accessed directly.
defined('ABSPATH') || exit(1);

if ( ! class_exists(__NAMESPACE__ . '\RestAPI') ) {
    /**
     * REST API
     *
     * @since 1.1.0
     */
    class RestAPI extends \RVIOR\Base\Controller {


        // Use utilities trait.
        use \RVIOR\Traits\Utilities;

        /**
         * API namespace
         *
         * @var string
         */
        protected $namespace = 'rvior/v1';

        /**
         * Registers all REST API endpoints
         *
         * @return void
         */
        public function register_hooks() {
            add_action('rest_api_init', [ $this, 'register_routes' ]);
        }

        /**
         * Register all REST routes
         *
         * @return void
         */
        public function register_routes() {
            $routes = [
                'update_access_token'  => [
                    'methods'             => \WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'update_access_token' ],
                    'permission_callback' => [ $this, 'admin_permissions_check' ],
                    'args'                => [
                        'access_token' => [
                            'required' => true,
                        ],
                    ],
                ],
                'update_accessibility' => [
                    'methods'             => \WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'update_accessibility' ],
                    'permission_callback' => [ $this, 'admin_permissions_check' ],
                    'args'                => [
                        'is_pro' => [
                            'required' => true,
                        ],
                    ],
                ],
                'get_settings'         => [
                    'methods'             => \WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'get_settings' ],
                    'permission_callback' => [ $this, 'admin_permissions_check' ],
                ],
                'update_settings'      => [
                    'methods'             => \WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'update_settings' ],
                    'permission_callback' => [ $this, 'admin_permissions_check' ],
                ],
                'reset_settings'       => [
                    'methods'             => \WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'reset_settings' ],
                    'permission_callback' => [ $this, 'admin_permissions_check' ],
                ],
                'hide_notices'         => [
                    'methods'             => \WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'hide_notices' ],
                    'permission_callback' => [ $this, 'admin_permissions_check' ],
                    'args'                => [
                        'id'        => [
                            'required' => true,
                        ],
                        'transient' => [
                            'default' => 7,
                        ],
                    ],
                ],
                'get_pages'            => [
                    'methods'             => \WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'get_pages' ],
                    'permission_callback' => [ $this, 'admin_permissions_check' ],
                ],
                'user_auth_key'        => [
                    'methods'             => \WP_REST_Server::READABLE,
                    'callback'            => [ $this, 'user_auth_key' ],
                    'permission_callback' => [ $this, 'admin_permissions_check' ],
                ],
                'upload_floating_icon' => [
                    'methods'             => \WP_REST_Server::CREATABLE,
                    'callback'            => [ $this, 'upload_floating_icon' ],
                    'permission_callback' => [ $this, 'admin_permissions_check' ],
                ],
            ];

            foreach ( $routes as $route => $args ) {
                register_rest_route($this->namespace, '/' . $route, $args);
            }
        }

        /**
         * Check if the user has admin permissions
         *
         * @return bool
         */
        public function admin_permissions_check() {
            return current_user_can('manage_options');
        }

        /**
         * Format the API response
         *
         * @param bool   $success Whether the request was successful.
         * @param string $message Response message.
         * @param array  $data    Response data.
         * @return \WP_REST_Response
         */
        private function format_response( $success, $message, $data = [] ) {
            return new \WP_REST_Response([
                'success' => $success,
                'message' => $message,
                'data'    => $data,
            ], $success ? 200 : 400);
        }

        /**
         * Updates access token
         *
         * @param \WP_REST_Request $request Request object.
         * @return \WP_REST_Response
         */
        public function update_access_token( $request ) {
            $access_token = sanitize_text_field($request->get_param('access_token'));

            $this->option()->update('access_token', $access_token);

            return $this->format_response(true, __('Access token updated', 'revio-reviews'));
        }

        /**
         * Updates accessibility
         *
         * @param \WP_REST_Request $request Request object.
         * @return \WP_REST_Response
         */
        public function update_accessibility( $request ) {
            $is_pro = wp_validate_boolean($request->get_param('is_pro'));

            $this->option()->update('is_pro', $is_pro);

            return $this->format_response(true, __('Accessibility updated', 'revio-reviews'));
        }

        /**
         * Get user settings
         *
         * @param \WP_REST_Request $request Request object.
         * @return \WP_REST_Response
         */
        public function get_settings( $request ) {
            $options = $this->option()->get_all();

            return $this->format_response(true, __('Settings retrieved', 'revio-reviews'), $options);
        }

        /**
         * Updates user settings
         *
         * @param \WP_REST_Request $request Request object.
         * @return \WP_REST_Response
         */
        public function update_settings( $request ) {
            $default_options = $this->option()->get_defaults();
            $inputs          = $request->get_json_params();

            foreach ( $default_options as $key => $default ) {
                if ( isset($inputs[ $key ]) ) {
                    $new_value = $inputs[ $key ];
                    $this->option()->update($key, $new_value);
                }
            }

            return $this->format_response(true, __('Settings updated', 'revio-reviews'));
        }

        /**
         * Upload floating icon
         *
         * @param \WP_REST_Request $request Request object.
         * @return \WP_REST_Response
         */
        /**
         * Upload floating icon
         *
         * @param \WP_REST_Request $request Request object.
         * @return \WP_REST_Response
         */
        public function upload_floating_icon( $request ) {
            // Include the required file for wp_handle_upload function
            if ( ! function_exists('wp_handle_upload') ) {
                require_once ABSPATH . 'wp-admin/includes/file.php';
            }

            $files = $this->io()->sanitize($request->get_file_params());

            if ( ! isset($files['icon']) ) {
                return $this->format_response(false, __('No file uploaded', 'revio-reviews'));
            }

            $uploadedfile = $files['icon'];

            // Add file type validation for security
            $allowed_types = [ 'image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/svg+xml' ];
            if ( ! in_array($uploadedfile['type'], $allowed_types) ) {
                return $this->format_response(false, __('Invalid file type. Only images are allowed.', 'revio-reviews'));
            }

            // Add file size validation (e.g., 2MB limit)
            $max_size = 2 * 1024 * 1024; // 2MB in bytes
            if ( $uploadedfile['size'] > $max_size ) {
                return $this->format_response(false, __('File size too large. Maximum allowed size is 2MB.', 'revio-reviews'));
            }

            $upload_overrides = [
                'test_form' => false,
            ];

            $movefile = wp_handle_upload($uploadedfile, $upload_overrides);

            if ( isset($movefile['url']) && ! isset($movefile['error']) ) {
                return $this->format_response(true, __('Image uploaded successfully', 'revio-reviews'), [
                    'url'  => $movefile['url'],
                    'file' => $movefile['file'],
                ]);
            } else {
                $error_message = isset($movefile['error']) ? $movefile['error'] : __('Failed to upload image', 'revio-reviews');
                return $this->format_response(false, $error_message);
            }
        }

        /**
         * Reset user settings
         *
         * @param \WP_REST_Request $request Request object.
         * @return \WP_REST_Response
         */
        public function reset_settings( $request ) {
            // Reset settings.
            $this->option()->reset();

            return $this->format_response(true, __('Settings reset', 'revio-reviews'));
        }

        /**
         * Get all pages
         *
         * @param \WP_REST_Request $request Request object.
         * @return \WP_REST_Response
         */
        public function get_pages( $request ) {
            $pages = get_posts([
                'post_type'      => 'page',
                'post_status'    => 'publish',
                'posts_per_page' => -1,
                'orderby'        => 'title',
                'order'          => 'ASC',
                'fields'         => [ 'ID', 'post_title', 'post_name' ],
            ]);

            $pages = array_map(function ( $page ) {
                return [
                    'value' => $page->ID,
                    'label' => ! empty($page->post_title) ? $page->post_title : __('( no title )', 'revio-reviews'),
                    'slug'  => $page->post_name,
                ];
            }, $pages);

            return $this->format_response(true, __('Pages retrieved', 'revio-reviews'), $pages);
        }

        /**
         * Hide notices
         *
         * @param \WP_REST_Request $request Request object.
         * @return \WP_REST_Response
         */
        public function hide_notices( $request ) {
            $id        = sanitize_text_field($request->get_param('id'));
            $transient = absint($request->get_param('transient'));

            $key = wp_sprintf('show_%s_notice', $id);

            if ( 'hide' === $transient ) {
                // Hide key.
                $this->option()->update($key, 'hide');
            } else {
                // set transient value 'hide' for transient * days in seconds.
                $this->option()->set_transient($key, 'hide', $transient * DAY_IN_SECONDS);
            }

            return $this->format_response(true, __('Notice hidden', 'revio-reviews'), [
                'key'       => $key,
                'transient' => $transient,
            ]);
        }

        /**
         * Get user auth key
         *
         * @param \WP_REST_Request $request Request object.
         * @return \WP_REST_Response
         */
        public function user_auth_key( $request ) {
            $security_key = [ 'secure_auth_key' => SECURE_AUTH_KEY ];

            return $this->format_response(true, __('check response for auth key', 'revio-reviews'), $security_key);
        }
    }

    // Instantiate.
    RestAPI::init();
}
