<?php
/**
 * Permission Controller
 * REST API endpoints for permission checking and management.
 * @package FleekDash\API
 */

namespace FleekDash\API;

use FleekDash\Core\PermissionManager;
use FleekDash\Core\PermissionMiddleware;
use FleekDash\Core\PermissionRegistry;
use FleekDash\Core\PermissionTree;

class PermissionController extends \WP_REST_Controller {
    /**
     * Namespace for REST routes
     */
    protected $namespace = 'fleekdash/v1';

    /**
     * Register routes
     *
     * @return void
     */
    public function register_routes(): void {
        // Check single permission
        register_rest_route($this->namespace, '/permissions/check', [
            'methods' => 'POST',
            'callback' => [$this, 'check_permission'],
            'permission_callback' => [$this, 'check_permissions'],
            'args' => [
                'permission' => [
                    'required' => true,
                    'type' => 'string',
                    'description' => 'Permission ID to check',
                    'validate_callback' => function($param) {
                        return !empty($param) && is_string($param);
                    },
                ],
                'check_hierarchy' => [
                    'default' => true,
                    'type' => 'boolean',
                    'description' => 'Check parent permissions in hierarchy',
                ],
            ],
        ]);

        // Check multiple permissions (batch)
        register_rest_route($this->namespace, '/permissions/batch', [
            'methods' => 'POST',
            'callback' => [$this, 'check_batch'],
            'permission_callback' => [$this, 'check_permissions'],
            'args' => [
                'permissions' => [
                    'required' => true,
                    'type' => 'array',
                    'description' => 'Array of permission IDs to check',
                    'validate_callback' => function($param) {
                        return is_array($param) && !empty($param);
                    },
                ],
            ],
        ]);

        // Get permission tree
        register_rest_route($this->namespace, '/permissions/tree', [
            'methods' => 'GET',
            'callback' => [$this, 'get_tree'],
            'permission_callback' => [$this, 'check_permissions'],
            'args' => [
                'root_id' => [
                    'default' => null,
                    'type' => 'string',
                    'description' => 'Root permission ID (optional)',
                ],
            ],
        ]);

        // Get permission details
        register_rest_route($this->namespace, '/permissions/(?P<id>[a-zA-Z0-9_.-]+)', [
            'methods' => 'GET',
            'callback' => [$this, 'get_permission'],
            'permission_callback' => [$this, 'check_permissions'],
            'args' => [
                'id' => [
                    'required' => true,
                    'type' => 'string',
                    'description' => 'Permission ID',
                ],
            ],
        ]);

        // Get registry statistics
        register_rest_route($this->namespace, '/permissions/stats', [
            'methods' => 'GET',
            'callback' => [$this, 'get_stats'],
            'permission_callback' => [$this, 'check_admin_permissions'],
        ]);
    }

    /**
     * Check single permission
     * @param \WP_REST_Request $request Request object
     * @return \WP_REST_Response Response object
     */
    public function check_permission(\WP_REST_Request $request): \WP_REST_Response {
        $permission_id = $request->get_param('permission');

        $result = PermissionManager::checkWithOverride($permission_id);

        return rest_ensure_response([
            'success' => true,
            'permission' => $permission_id,
            'result' => $result,
        ]);
    }

    /**
     * Check multiple permissions (batch)
     *
     * @param \WP_REST_Request $request Request object
     * @return \WP_REST_Response Response object
     */
    public function check_batch(\WP_REST_Request $request): \WP_REST_Response {
        $permission_ids = $request->get_param('permissions');
        
        // Rate limiting - max 50 permissions per request
        if (!is_array($permission_ids) || count($permission_ids) > 50) {
            return rest_ensure_response([
                'success' => false,
                'message' => 'Too many permissions requested. Maximum 50 per batch.',
            ]);
        }
        
        $results = [];

        foreach ($permission_ids as $id) {
            $results[$id] = PermissionManager::checkWithOverride($id);
        }

        return rest_ensure_response([
            'success' => true,
            'results' => $results,
        ]);
    }

    /**
     * Get permission tree
     *
     * @param \WP_REST_Request $request Request object
     * @return \WP_REST_Response Response object
     */
    public function get_tree(\WP_REST_Request $request): \WP_REST_Response {
        $root_id = $request->get_param('root_id');

        $tree = PermissionTree::getTree($root_id);

        return rest_ensure_response([
            'success' => true,
            'tree' => $tree,
        ]);
    }

    /**
     * Get permission details
     *
     * @param \WP_REST_Request $request Request object
     * @return \WP_REST_Response Response object
     */
    public function get_permission(\WP_REST_Request $request): \WP_REST_Response {
        $permission_id = $request->get_param('id');

        if (!PermissionManager::has($permission_id)) {
            return rest_ensure_response([
                'success' => false,
                'message' => 'Permission not found',
                'permission_id' => $permission_id,
            ]);
        }

        $permission = PermissionManager::get($permission_id);
        $check_result = PermissionManager::checkWithOverride($permission_id);

        return rest_ensure_response([
            'success' => true,
            'permission' => array_merge($permission, [
                'currentUserAllowed' => $check_result['allowed'],
                'reason' => $check_result['reason'],
                'metadata' => $check_result['metadata'],
            ]),
        ]);
    }

    /**
     * Get registry statistics
     *
     * @param \WP_REST_Request $request Request object
     * @return \WP_REST_Response Response object
     */
    public function get_stats(\WP_REST_Request $request): \WP_REST_Response {
        $stats = PermissionRegistry::getStats();

        return rest_ensure_response([
            'success' => true,
            'stats' => $stats,
        ]);
    }

    /**
     * Check permissions for endpoints
     *
     * @return bool Whether user is logged in
     */
    public function check_permissions(): bool {
        // All logged-in users can check their own permissions
        return \is_user_logged_in();
    }

    /**
     * Check admin permissions
     *
     * @return bool Whether user is admin
     */
    public function check_admin_permissions(): bool {
        return \current_user_can('manage_options');
    }
}
