<?php

// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedNamespaceFound -- APD is the established namespace shared with the Pro add-on and retained for backward compatibility.
namespace APD\Support;

use APD\PostTypes\UserDesignPostType;
use APD\Repositories\UserDesignRepository;

defined('ABSPATH') || exit;

class UserDesignAccess
{
    public static function canManage() : bool
    {
        return current_user_can(Capabilities::MANAGE) || current_user_can('manage_options');
    }

    public static function canAccessItem(array $item, string $resumeToken = '') : bool
    {
        if ($item === []) {
            return false;
        }

        if (self::canManage()) {
            return true;
        }

        $currentUserId = get_current_user_id();
        if ($currentUserId > 0) {
            $itemUserId = absint($item['userId'] ?? 0);
            $authorId = absint($item['authorId'] ?? 0);
            if (($itemUserId > 0 && $itemUserId === $currentUserId) || ($authorId > 0 && $authorId === $currentUserId)) {
                return true;
            }
        }

        $resumeToken = self::sanitizeToken($resumeToken);
        $storedToken = self::sanitizeToken((string) ($item['accessToken'] ?? ''));

        return $resumeToken !== '' && $storedToken !== '' && hash_equals($storedToken, $resumeToken);
    }

    public static function canAccessPost(int $postId) : bool
    {
        return self::canAccessPostForUser($postId, get_current_user_id());
    }

    public static function canAccessPostForUser(int $postId, int $userId = 0) : bool
    {
        if ($postId <= 0 || get_post_type($postId) !== UserDesignPostType::TYPE) {
            return false;
        }

        if (self::canManage() || current_user_can('edit_post', $postId) || current_user_can('read_post', $postId)) {
            return true;
        }

        $post = get_post($postId);
        if (! $post) {
            return false;
        }

        return $userId > 0 && (int) $post->post_author === $userId;
    }

    public static function findAccessibleItem(int $postId, string $resumeToken = '') : array
    {
        $item = (new UserDesignRepository())->find($postId);
        return self::canAccessItem($item, $resumeToken) ? $item : [];
    }

    public static function sanitizeToken(string $token) : string
    {
        $token = preg_replace('/[^A-Za-z0-9_-]/', '', $token) ?: '';
        return substr($token, 0, 128);
    }
}
