<?php

/**
 * Notifications Feed REST API Controller
 *
 * @package ProRank\SEO\Core\RestApi
 * @since   0.1.0
 */

declare(strict_types=1);

namespace ProRank\SEO\Core\RestApi;

use ProRank\SEO\Core\Notifications\NotificationsFeed;
use WP_REST_Controller;
use WP_REST_Server;
use WP_REST_Request;
use WP_REST_Response;
use WP_Error;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}


/**
 * Class NotificationsFeedController
 * 
 * Handles REST API endpoints for notifications feed
 */


class NotificationsFeedController extends WP_REST_Controller {
    /**
     * Namespace
     *
     * @var string
     */
    protected $namespace = 'prorank-seo/v1';

    /**
     * Rest base
     *
     * @var string
     */
    protected $rest_base = 'notifications';

    /**
     * Notification manager instance
     *
     * @var NotificationsFeed
     */
    private NotificationsFeed $notification_manager;

    /**
     * Constructor
     *
     * @param NotificationsFeed $notification_manager Notification manager instance
     */
    public function __construct(NotificationsFeed $notification_manager) {
        $this->notification_manager = $notification_manager;
    }

    /**
     * Register routes
     *
     * @return void
     */
    public function register_routes(): void {
        // Get notifications
        register_rest_route($this->namespace, '/' . $this->rest_base, [
            [
                'methods'             => WP_REST_Server::READABLE,
                'callback'            => [$this, 'get_notifications'],
                'permission_callback' => [$this, 'get_notifications_permissions_check'],
                'args'                => [
                    'type' => [
                        'description'       => __('Filter by notification type', 'prorank-seo'),
                        'type'              => 'string',
                        'enum'              => ['info', 'warning', 'error', 'success', 'tip', 'update', 'promo'],
                        'sanitize_callback' => 'sanitize_text_field',
                    ],
                    'priority' => [
                        'description'       => __('Filter by priority', 'prorank-seo'),
                        'type'              => 'string',
                        'enum'              => ['low', 'medium', 'high', 'critical'],
                        'sanitize_callback' => 'sanitize_text_field',
                    ],
                    'refresh' => [
                        'description'       => __('Force refresh remote notifications before returning the feed.', 'prorank-seo'),
                        'type'              => 'boolean',
                        'sanitize_callback' => 'rest_sanitize_boolean',
                    ],
                ],
            ],
            'schema' => [$this, 'get_public_item_schema'],
        ]);

        // Get notification counts
        register_rest_route($this->namespace, '/' . $this->rest_base . '/counts', [
            'methods'             => WP_REST_Server::READABLE,
            'callback'            => [$this, 'get_notification_counts'],
            'permission_callback' => [$this, 'get_notifications_permissions_check'],
        ]);

        // Dismiss notification
        register_rest_route($this->namespace, '/' . $this->rest_base . '/(?P<id>[a-zA-Z0-9-]+)/dismiss', [
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => [$this, 'dismiss_notification'],
            'permission_callback' => [$this, 'dismiss_notification_permissions_check'],
            'args'                => [
                'id' => [
                    'description'       => __('Notification ID', 'prorank-seo'),
                    'type'              => 'string',
                    'required'          => true,
                    'sanitize_callback' => 'sanitize_text_field',
                ],
            ],
        ]);

        // Clear cache (admin only)
        register_rest_route($this->namespace, '/' . $this->rest_base . '/cache/clear', [
            'methods'             => WP_REST_Server::DELETABLE,
            'callback'            => [$this, 'clear_cache'],
            'permission_callback' => [$this, 'clear_cache_permissions_check'],
        ]);
    }

    /**
     * Get notifications
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
     */
    public function get_notifications($request) {
        if ((bool) $request->get_param('refresh')) {
            $this->notification_manager->clear_cache();
        }

        $filters = [];

        if ($request->has_param('type')) {
            $filters['type'] = $request->get_param('type');
        }

        if ($request->has_param('priority')) {
            $filters['priority'] = $request->get_param('priority');
        }

        $notifications = $this->notification_manager->get_notifications($filters);

        return new WP_REST_Response([
            'notifications' => $notifications,
            'count' => count($notifications),
        ], 200);
    }

    /**
     * Get notification counts
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
     */
    public function get_notification_counts($request) {
        $counts = $this->notification_manager->get_notification_counts();

        return new WP_REST_Response($counts, 200);
    }

    /**
     * Dismiss a notification
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
     */
    public function dismiss_notification($request) {
        $notification_id = $request->get_param('id');
        
        if (empty($notification_id)) {
            return new WP_Error(
                'prorank_invalid_notification_id',
                __('Invalid notification ID.', 'prorank-seo'),
                ['status' => 400]
            );
        }

        $result = $this->notification_manager->dismiss_notification($notification_id);

        if (!$result) {
            return new WP_Error(
                'prorank_dismiss_failed',
                __('Failed to dismiss notification.', 'prorank-seo'),
                ['status' => 500]
            );
        }

        return new WP_REST_Response([
            'success' => true,
            'notification_id' => $notification_id,
        ], 200);
    }

    /**
     * Clear notifications cache
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
     */
    public function clear_cache($request) {
        $this->notification_manager->clear_cache();

        return new WP_REST_Response([
            'success' => true,
            'message' => __('Notifications cache cleared successfully.', 'prorank-seo'),
        ], 200);
    }

    /**
     * Check if a given request has access to get notifications
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return true|WP_Error True if the request has read access, WP_Error object otherwise.
     */
    public function get_notifications_permissions_check($request) {
        return current_user_can('edit_posts');
    }

    /**
     * Check if a given request has access to dismiss notifications
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return true|WP_Error True if the request has access to dismiss notifications, WP_Error object otherwise.
     */
    public function dismiss_notification_permissions_check($request) {
        return current_user_can('edit_posts');
    }

    /**
     * Check if a given request has access to clear cache
     *
     * @param WP_REST_Request $request Full details about the request.
     * @return true|WP_Error True if the request has access to clear cache, WP_Error object otherwise.
     */
    public function clear_cache_permissions_check($request) {
        return current_user_can('manage_options');
    }

    /**
     * Get schema for notifications
     *
     * @return array
     */
    public function get_item_schema(): array {
        if ($this->schema) {
            return $this->add_additional_fields_schema($this->schema);
        }

        $schema = [
            '$schema'    => 'http://json-schema.org/draft-04/schema#',
            'title'      => 'notification',
            'type'       => 'object',
            'properties' => [
                'id' => [
                    'description' => __('Unique notification identifier.', 'prorank-seo'),
                    'type'        => 'string',
                    'context'     => ['view'],
                    'readonly'    => true,
                ],
                'type' => [
                    'description' => __('Notification type.', 'prorank-seo'),
                    'type'        => 'string',
                    'enum'        => ['info', 'warning', 'error', 'success', 'tip', 'update', 'promo'],
                    'context'     => ['view'],
                    'readonly'    => true,
                ],
                'priority' => [
                    'description' => __('Notification priority.', 'prorank-seo'),
                    'type'        => 'string',
                    'enum'        => ['low', 'medium', 'high', 'critical'],
                    'context'     => ['view'],
                    'readonly'    => true,
                ],
                'title' => [
                    'description' => __('Notification title.', 'prorank-seo'),
                    'type'        => 'string',
                    'context'     => ['view'],
                    'readonly'    => true,
                ],
                'message' => [
                    'description' => __('Notification message.', 'prorank-seo'),
                    'type'        => 'string',
                    'context'     => ['view'],
                    'readonly'    => true,
                ],
                'action' => [
                    'description' => __('Call to action details.', 'prorank-seo'),
                    'type'        => 'object',
                    'context'     => ['view'],
                    'readonly'    => true,
                    'properties' => [
                        'label' => [
                            'type' => 'string',
                        ],
                        'url' => [
                            'type' => 'string',
                            'format' => 'uri',
                        ],
                    ],
                ],
                'dismissible' => [
                    'description' => __('Whether notification can be dismissed.', 'prorank-seo'),
                    'type'        => 'boolean',
                    'context'     => ['view'],
                    'readonly'    => true,
                ],
                'timestamp' => [
                    'description' => __('Notification timestamp.', 'prorank-seo'),
                    'type'        => 'integer',
                    'context'     => ['view'],
                    'readonly'    => true,
                ],
            ],
        ];

        $this->schema = $schema;

        return $this->add_additional_fields_schema($this->schema);
    }
}
