<?php

declare(strict_types=1);

namespace App\Services\External;

use App\Services\Supplier\PlaywrightBridge;
use Illuminate\Support\Facades\DB;

/**
 * Баланс кабинета поставщика лидов (crm.bp-gr.ru). У кабинета нет JSON-эндпоинта
 * баланса → читаем со страницы через headless Playwright (тот же логин-флоу, что
 * RefreshSupplierSessionJob). Селектор/URL баланса калибруются разведкой на проде
 * (см. план Task 6 Step 1); до калибровки скрипт вернёт exit 2 → fail «баланс не найден».
 */
class SupplierBalanceProvider implements BalanceProvider
{
    public function __construct(private readonly PlaywrightBridge $bridge) {}

    public function serviceKey(): string
    {
        return 'supplier';
    }

    public function fetch(): BalanceReading
    {
        try {
            $login = (string) config('services.supplier.login');
            $password = (string) config('services.supplier.password');
            if ($login === '' || $password === '') {
                return BalanceReading::fail('supplier', 'Доступ к кабинету поставщика не настроен');
            }
            $out = $this->bridge->run([
                'script' => 'supplier-balance.js',
                'login' => $login,
                'password' => $password,
                'url' => (string) config('services.supplier.portal_url'),
            ]);
            // У кабинета не деньги, а остаток НОМЕРОВ («Баланс ГЦК»). Деньги = номера × цена.
            if (! isset($out['numbers']) || ! is_numeric($out['numbers'])) {
                return BalanceReading::fail('supplier', 'Остаток номеров не найден в кабинете');
            }
            $numbers = (int) $out['numbers'];
            $price = (float) config('services.supplier.number_price_rub', 20);

            return BalanceReading::ok(
                'supplier',
                $numbers * $price,
                'RUB',
                $this->dailySpend(),
            );
        } catch (\Throwable $e) {
            return BalanceReading::fail('supplier', $e->getMessage());
        }
    }

    /**
     * Оценка расхода/день: лиды за 7д ÷ 7 × средняя цена лида (из конфига).
     * Best-effort — нет цены или ошибка подсчёта → null (светофор только по порогам).
     */
    private function dailySpend(): ?float
    {
        try {
            $price = (float) config('services.supplier.avg_lead_price_rub', 0);
            if ($price <= 0) {
                return null;
            }
            $leads7d = DB::table('supplier_leads')
                ->where('received_at', '>=', now()->subDays(7))
                ->count();
            if ($leads7d === 0) {
                return null;
            }

            return round(($leads7d / 7) * $price, 2);
        } catch (\Throwable) {
            return null;
        }
    }
}
