<?php
namespace EasyChat\Library\Messenger;








final class WildberriesTokenInspector {
    private const MAX_TOKEN_BYTES = 8192;

    private const TYPES = [
        1 => ['code' => 'base', 'label' => 'Базовый'],
        2 => ['code' => 'test', 'label' => 'Тестовый'],
        3 => ['code' => 'personal', 'label' => 'Персональный'],
        4 => ['code' => 'service', 'label' => 'Сервисный'],
    ];

    private const PERMISSIONS = [
        7 => ['code' => 'feedbacks', 'label' => 'Вопросы и отзывы'],
        9 => ['code' => 'buyer_chat', 'label' => 'Чаты с покупателями'],
        11 => ['code' => 'returns', 'label' => 'Возвраты'],
    ];

    public static function inspect(string $token): array {
        $token = preg_replace('/^Bearer\s+/i', '', trim($token));
        if ($token === '' || strlen($token) > self::MAX_TOKEN_BYTES) {
            return ['success' => false, 'error' => 'wb_token_format_invalid'];
        }
        $parts = explode('.', $token);
        if (count($parts) !== 3 || $parts[1] === '') {
            return ['success' => false, 'error' => 'wb_token_format_invalid'];
        }
        $payload = self::base64UrlDecode($parts[1]);
        if ($payload === '') {
            return ['success' => false, 'error' => 'wb_token_format_invalid'];
        }
        $decoded = json_decode($payload, true, 12);
        if (!is_array($decoded)) {
            return ['success' => false, 'error' => 'wb_token_format_invalid'];
        }

        $account_type = (int)($decoded['acc'] ?? 0);
        $type = self::TYPES[$account_type] ?? ['code' => 'unknown', 'label' => 'Не удалось определить'];
        $mask = is_numeric($decoded['s'] ?? null) ? (int)$decoded['s'] : 0;
        $permissions = [];
        foreach (self::PERMISSIONS as $bit => $definition) {
            if (($mask & (1 << $bit)) !== 0) {
                $permissions[] = $definition;
            }
        }
        $expires = is_numeric($decoded['exp'] ?? null) ? (int)$decoded['exp'] : 0;
        $seller_id = self::safeIdentifier($decoded['sid'] ?? $decoded['sellerId'] ?? $decoded['sub'] ?? '');

        return [
            'success' => true,
            'token_type' => $type['code'],
            'token_type_label' => $type['label'],
            'seller_id' => $seller_id,
            'expires_at' => $expires > 0 ? gmdate('Y-m-d\TH:i:s\Z', $expires) : '',
            'expired' => $expires > 0 && $expires <= time(),
            'read_only' => ($mask & (1 << 30)) !== 0,
            'permissions' => $permissions,
            'permission_codes' => array_column($permissions, 'code'),
            'signature_verified' => false,
        ];
    }

     
    public static function publicMetadata(array $inspection): array {
        if (empty($inspection['success'])) {
            return [
                'success' => false,
                'error' => (string)($inspection['error'] ?? 'wb_token_format_invalid'),
            ];
        }
        return [
            'success' => true,
            'token_type' => (string)($inspection['token_type'] ?? 'unknown'),
            'token_type_label' => (string)($inspection['token_type_label'] ?? ''),
            'expires_at' => (string)($inspection['expires_at'] ?? ''),
            'expired' => !empty($inspection['expired']),
            'read_only' => !empty($inspection['read_only']),
            'permissions' => array_values(is_array($inspection['permissions'] ?? null) ? $inspection['permissions'] : []),
        ];
    }

    private static function base64UrlDecode(string $value): string {
        if (preg_match('/^[A-Za-z0-9_-]+$/', $value) !== 1) {
            return '';
        }
        $value = strtr($value, '-_', '+/');
        $value .= str_repeat('=', (4 - strlen($value) % 4) % 4);
        $decoded = base64_decode($value, true);
        return is_string($decoded) ? $decoded : '';
    }

    private static function safeIdentifier($value): string {
        if (!is_scalar($value)) {
            return '';
        }
        $value = trim((string)$value);
        return strlen($value) <= 128 && preg_match('/^[A-Za-z0-9:_-]+$/', $value) === 1 ? $value : '';
    }
}
