<?php

declare(strict_types=1);

namespace App\Services\External;

use Illuminate\Support\Facades\Http;

/**
 * Баланс биллинг-аккаунта Yandex Cloud (серверы + Managed PG).
 * Поток: OAuth-токен → IAM-токен (iam/v1/tokens) → billing/v1/billingAccounts/{id}.
 * Расход/день — оценка из конфига (месячный ÷ 30), уточняется по факту.
 */
class YandexCloudBalanceProvider implements BalanceProvider
{
    public function serviceKey(): string
    {
        return 'yandex_cloud';
    }

    public function fetch(): BalanceReading
    {
        try {
            $oauth = (string) config('services.yandex_cloud.oauth_token');
            $acc = (string) config('services.yandex_cloud.billing_account_id');
            if ($oauth === '' || $acc === '') {
                return BalanceReading::fail('yandex_cloud', 'YC доступ не настроен');
            }
            $iam = Http::timeout(10)->post((string) config('services.yandex_cloud.iam_url'), [
                'yandexPassportOauthToken' => $oauth,
            ]);
            if (! $iam->ok() || ! $iam->json('iamToken')) {
                return BalanceReading::fail('yandex_cloud', 'IAM exchange: HTTP '.$iam->status());
            }
            $resp = Http::timeout(10)
                ->withToken((string) $iam->json('iamToken'))
                ->get((string) config('services.yandex_cloud.billing_url').'/'.$acc);
            if (! $resp->ok()) {
                return BalanceReading::fail('yandex_cloud', 'Billing: HTTP '.$resp->status());
            }
            $balance = (float) ($resp->json('balance') ?? 0);
            $currency = (string) ($resp->json('currency') ?? 'RUB');
            $spend = ((float) config('services.yandex_cloud.daily_spend_rub')) ?: null;

            return BalanceReading::ok('yandex_cloud', $balance, $currency, $spend);
        } catch (\Throwable $e) {
            return BalanceReading::fail('yandex_cloud', $e->getMessage());
        }
    }
}
