<?php

declare(strict_types=1);

namespace Plugin\tnt_mcp\src\Mcp\OAuth\Entities;

use League\OAuth2\Server\Entities\UserEntityInterface;

/**
 * The resource owner of an issued token: the **backend admin who approved the consent**, identified
 * by their `tadminlogin.cLogin`. That value is what
 * {@see \Plugin\tnt_mcp\src\Mcp\OAuth\Repositories\AccessTokenRepository::persistNewAccessToken()}
 * writes to `tnt_mcp_oauth_access_token.cUserId` (AccessTokenRepository.php:51) and
 * {@see \Plugin\tnt_mcp\src\Mcp\OAuth\Repositories\AuthCodeRepository::persistNewAuthCode()} to
 * `tnt_mcp_oauth_auth_code.cUserId` (AuthCodeRepository.php:33) — so a token records *who*
 * authorised it, which is what decision Q1 needs to let the backend-action invoker act as that
 * admin ({@see \Plugin\tnt_mcp\src\Mcp\Backend\BackendIdentityFactory}).
 *
 * ⚠️ {@see self::IDENTIFIER} is the **legacy** value. Until admin-identity binding shipped, every
 * token carried the constant `'shop'` — recording that a consent happened but not who approved it.
 * Such tokens are rejected loudly by
 * {@see \Plugin\tnt_mcp\src\Mcp\Backend\BackendIdentityFactory::forTokenUser()}; they are never
 * resolved to a "default" admin, because that would hand an old token an identity nobody consented
 * to. Read-only MCP tooling that does not need a backend identity is unaffected.
 */
final class ShopUserEntity implements UserEntityInterface
{
    /**
     * Legacy resource-owner id used by every token issued before admin-identity binding. Kept only
     * so the invoker can recognise — and refuse — those tokens. Never mint it again.
     */
    public const string IDENTIFIER = 'shop';

    /** @param non-empty-string $login the approving admin's `tadminlogin.cLogin` */
    public function __construct(private readonly string $login)
    {
    }

    /** @return non-empty-string */
    public function getIdentifier(): string
    {
        return $this->login;
    }
}
