<?php
namespace EasyChat\Library\Messenger\Marketplace;

use EasyChat\Library\Messenger\WildberriesProvider;
use EasyChat\Library\Messenger\WildberriesTokenInspector;
use EasyChat\Model\Marketplace as MarketplaceModel;







final class MarketplaceRateBudget {
    private $model;

    public function __construct($registry, MarketplaceModel $model = null) {
        $this->model = $model ?: new MarketplaceModel($registry);
    }

    public function reserve(array $stream_row, array $credentials): array {
        $policy = $this->policy($stream_row, $credentials);
        if (empty($policy['managed'])) {
            return ['allowed' => true, 'delay_seconds' => 0] + $policy;
        }

        $scope = $this->scopeHash($stream_row, $policy);
        $reserved = $this->model->reserveRateBudget(
            (string)$stream_row['provider'],
            $scope,
            (string)$policy['credential_class'],
            (string)$policy['api_group'],
            (int)$policy['minimum_interval'],
            (int)($stream_row['channel_id'] ?? 0),
            (string)($stream_row['stream'] ?? '')
        );
        return $reserved + $policy + ['scope_hash' => $scope];
    }

    public function deferFromProvider(array $stream_row, array $credentials, int $retry_after): void {
        $policy = $this->policy($stream_row, $credentials);
        if (empty($policy['managed']) || $retry_after <= 0) {
            return;
        }
        $this->model->deferRateBudget(
            (string)$stream_row['provider'],
            $this->scopeHash($stream_row, $policy),
            (string)$policy['credential_class'],
            (string)$policy['api_group'],
            min(21600, $retry_after)
        );
    }

    public function policy(array $stream_row, array $credentials): array {
        $provider = strtolower((string)($stream_row['provider'] ?? ''));
        $stream = MarketplaceStream::normalize((string)($stream_row['stream'] ?? ''));
        if ($provider !== WildberriesProvider::PROVIDER || $stream === '') {
            return [
                'managed' => false,
                'credential_class' => 'standard',
                'api_group' => $stream,
                'minimum_interval' => 0,
            ];
        }

        $inspection = WildberriesTokenInspector::inspect((string)($credentials['api_token'] ?? ''));
        $token_type = !empty($inspection['success']) ? (string)$inspection['token_type'] : 'unknown';
        $is_restricted = in_array($token_type, ['base', 'test', 'unknown'], true);
        $group = in_array($stream, [MarketplaceStream::QUESTION, MarketplaceStream::REVIEW], true)
            ? 'feedbacks'
            : $stream;

        if ($is_restricted) {
             
             
             
            $intervals = [
                MarketplaceStream::BUYER_CHAT => 3660,
                'feedbacks' => 735,
                MarketplaceStream::RETURN_CLAIM => 3660,
            ];
        } else {
             
             
             
            $intervals = [
                MarketplaceStream::BUYER_CHAT => 15,
                'feedbacks' => 30,
                MarketplaceStream::RETURN_CLAIM => 60,
            ];
        }

        return [
            'managed' => true,
            'credential_class' => $token_type,
            'api_group' => $group,
            'minimum_interval' => (int)($intervals[$group] ?? 60),
        ];
    }

    private function scopeHash(array $stream_row, array $policy): string {
         
         
        return hash(
            'sha256',
            strtolower((string)($stream_row['provider'] ?? '')) . '|'
            . trim((string)($stream_row['external_account_id'] ?? '')) . '|'
            . (string)($policy['credential_class'] ?? 'unknown')
        );
    }
}
