<?php

namespace WPQT\Permission;

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

use WPQT\Services\ServiceLocator;

if (!class_exists('WPQT\Permission\PermissionService')) {
    class PermissionService
    {
        /**
         * Checks if the current user has the required permissions to access the private API.
         *
         * @return bool Returns true if the current user has the required permissions, false otherwise.
         */
        public static function hasRequiredPermissionsForPrivateAPI()
        {
            return current_user_can(WP_QUICKTASKER_ADMIN_ROLE);
        }

        /**
         * Checks if the current user has the required permissions to access public API delete endpoints.
         *
         * This function verifies if the current user has the necessary permissions defined by the
         * WP_QUICKTASKER_ADMIN_ROLE_ALLOW_DELETE capability.
         *
         * @return bool True if the user has the required permissions, false otherwise.
         */
        public static function hasRequiredPermissionsForPrivateAPIDeleteEndpoints()
        {
            return current_user_can(WP_QUICKTASKER_ADMIN_ROLE_ALLOW_DELETE) && self::hasRequiredPermissionsForPrivateAPI();
        }

        /**
         * Check if the current user has the required permissions for private API user endpoints.
         *
         * This function verifies if the current user has the capability defined by the
         * WP_QUICKTASKER_ADMIN_ROLE_MANAGE_USERS constant.
         *
         * @return bool True if the user has the required permissions, false otherwise.
         */
        public static function hasRequiredParmissionsForPrivateAPIUsersEndpoints()
        {
            return current_user_can(WP_QUICKTASKER_ADMIN_ROLE_MANAGE_USERS) && self::hasRequiredPermissionsForPrivateAPI();
        }

        /**
         * Checks if the current user has the required permissions to manage private API settings endpoints.
         *
         * This function verifies if the current user has the capability defined by the constant
         * `WP_QUICKTASKER_ADMIN_ROLE_MANAGE_SETTINGS`.
         *
         * @return bool True if the current user has the required permissions, false otherwise.
         */
        public static function hasRequiredPermissionsForPrivateAPISettingsEndpoints()
        {
            return current_user_can(WP_QUICKTASKER_ADMIN_ROLE_MANAGE_SETTINGS) && self::hasRequiredPermissionsForPrivateAPI();
        }

        /**
         * Checks if the current user has the required permissions for private API archive endpoints.
         *
         * This function verifies if the current user has the capability defined by the
         * WP_QUICKTASKER_ADMIN_ROLE_MANAGE_ARCHIVE constant.
         *
         * @return bool True if the user has the required permissions, false otherwise.
         */
        public static function hasRequiredPermissionsForPrivateAPIArchiveEndpoints()
        {
            return current_user_can(WP_QUICKTASKER_ADMIN_ROLE_MANAGE_ARCHIVE) && self::hasRequiredPermissionsForPrivateAPI();
        }

        /**
         * Checks if the current user has the required permissions to access the user page app.
         *
         * This function verifies if the current user has the capability defined by the constant
         * WP_QUICKTASKER_ACCESS_USER_PAGE_APP.
         *
         * @return bool True if the user has the required permissions, false otherwise.
         */
        public static function hasRequiredPermissionsForUserPageApp()
        {
            return current_user_can(WP_QUICKTASKER_ACCESS_USER_PAGE_APP);
        }

        /**
         * Checks if the current user has the required permissions to manage QuickTasker sessions.
         *
         * This function verifies if the current user has the capability defined by the
         * WP_QUICKTASKER_ADMIN_ROLE_MANAGE_QUICKTASKER_SESSIONS constant.
         *
         * @return bool True if the user has the required permissions, false otherwise.
         */
        public static function hasRequiredPermissionsForManagingQuickTaskerSessions()
        {
            return current_user_can(WP_QUICKTASKER_ADMIN_ROLE_MANAGE_QUICKTASKER_SESSIONS) && self::hasRequiredPermissionsForPrivateAPI();
        }

        /**
         * Checks if the current user has the required permissions to view the My Tasks page.
         *
         * @return bool True if the user has the required permissions, false otherwise.
         */
        public static function hasRequiredPermissionsForMyTasks()
        {
            return current_user_can(WP_QUICKTASKER_VIEW_MY_TASKS);
        }

        /**
         * Checks if a user is allowed to view a task.
         *
         * @param int $userId The ID of the user.
         * @param int $taskId The ID of the task.
         * @param string $userType The type of user (default is WP_QT_QUICKTASKER_USER_TYPE).
         * @return bool Returns true if the user is allowed to view the task, false otherwise.
         */
        public function checkIfUserIsAllowedToViewTask($userId, $taskId, $userType = WP_QT_QUICKTASKER_USER_TYPE)
        {
            global $wpdb;

            $task = ServiceLocator::get('TaskRepository')->getTaskById($taskId);

            if ('1' === $task->is_archived) {
                return false;
            }

            $assignedUsers = [];

            if (WP_QT_QUICKTASKER_USER_TYPE === $userType) {
                $assignedUsers = ServiceLocator::get('UserRepository')->getAssignedUsersByTaskId($taskId);
            } else {
                $assignedUsers = ServiceLocator::get('UserRepository')->getAssignedWPUsersByTaskIds([$taskId]);
            }

            $isAssignedToTask = false;

            foreach ($assignedUsers as $user) {
                if ((int) $user->id === (int) $userId) {
                    $isAssignedToTask = true;
                    break;
                }
            }

            if (true === $isAssignedToTask || ('1' === $task->free_for_all && 0 === count($assignedUsers))) {
                return true;
            } else {
                return false;
            }
        }

        /**
         * Check whether a WordPress user has a personal stake in a task (they
         * created it, or are assigned to it). Used to authorize per-task access
         * from the MyTasks endpoints.
         *
         * @param int $userId The WP user ID.
         * @param object $task The task object (must include id, created_by_id, created_by_type).
         * @return bool
         */
        public function checkIfWPUserCanAccessMyTasksTask($userId, $task)
        {
            $isCreator = (int) $task->created_by_id === (int) $userId
                && WP_QT_WORDPRESS_USER_TYPE === $task->created_by_type;

            if ($isCreator) {
                return true;
            }

            return ServiceLocator::get('UserRepository')->checkIfUserHasAssignedToTask(
                $userId,
                $task->id,
                WP_QT_WORDPRESS_USER_TYPE
            );
        }

        /**
         * Checks if a user can be assigned to a specific task.
         *
         * This method verifies whether a user can be assigned to a task based on the task's
         * properties and the current assigned users. If the task is marked as 'free for all'
         * and there are no users currently assigned, the user can be assigned to the task.
         *
         * @param int $userId The ID of the user to check.
         * @param int $taskId The ID of the task to check.
         * @return bool True if the user can be assigned to the task, false otherwise.
         */
        public function checkIfUserCanBeAssignedToTask($userId, $taskId)
        {
            global $wpdb;

            $task = ServiceLocator::get('TaskRepository')->getTaskById($taskId);

            if ('1' === $task->is_archived) {
                return false;
            }

            $assignedUsers = ServiceLocator::get('UserRepository')->getAssignedUsersByTaskId($taskId);

            if ('1' === $task->free_for_all && 0 === count($assignedUsers)) {
                return true;
            } else {
                return false;
            }
        }

        /**
         * Check if a user page user is allowed to edit a task.
         *
         * @param int $userId The ID of the user.
         * @param int $taskId The ID of the task.
         * @param string $userType The type of user (default is WP_QT_QUICKTASKER_USER_TYPE).
         * @return bool Returns true if the user is allowed to edit the task, false otherwise.
         */
        public function checkIfUserIsAllowedToEditTask($userId, $taskId, $userType = WP_QT_QUICKTASKER_USER_TYPE)
        {
            global $wpdb;

            $task = ServiceLocator::get('TaskRepository')->getTaskById($taskId);

            if ('1' === $task->is_archived) {
                return false;
            }

            $isAssignedToUser = ServiceLocator::get('UserRepository')->checkIfUserHasAssignedToTask($userId, $taskId, $userType);

            return $isAssignedToUser;
        }
    }
}
