<?php
namespace Bot\Services;

use Bot\Config;
use Bot\Database;
use PDO;

class RateService
{
    private PDO $pdo;
    /** @var string[] */
    private array $supportedCurrencies;

    public function __construct()
    {
        $this->pdo = Database::connection();
        $this->supportedCurrencies = array_map('strtoupper', Config::get()->getValue('supported_currencies', ['USDT']));
    }

    public function getSupportedCurrencies(): array
    {
        return $this->supportedCurrencies;
    }

    /**
     * @return array{rate_buy:float,rate_sell:float}|null
     */
    public function getRates(string $currency): ?array
    {
        $stmt = $this->pdo->prepare('SELECT rate_buy, rate_sell FROM rates WHERE currency = ?');
        $stmt->execute([strtoupper($currency)]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$row) {
            return null;
        }
        return [
            'rate_buy'  => (float) $row['rate_buy'],
            'rate_sell' => (float) $row['rate_sell'],
        ];
    }

    /**
     * @return array{service_fee_percent:float,network_fee_flat:float}
     */
    public function getFees(string $currency): array
    {
        $stmt = $this->pdo->prepare('SELECT service_fee_percent, network_fee_flat FROM fees WHERE currency = ?');
        $stmt->execute([strtoupper($currency)]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$row) {
            return [
                'service_fee_percent' => 0.0,
                'network_fee_flat'    => 0.0,
            ];
        }
        return [
            'service_fee_percent' => (float) $row['service_fee_percent'],
            'network_fee_flat'    => (float) $row['network_fee_flat'],
        ];
    }

    public function setRate(string $currency, string $side, float $price): void
    {
        $currency = strtoupper($currency);
        if (!in_array($currency, $this->supportedCurrencies, true)) {
            throw new \InvalidArgumentException("Unsupported currency {$currency}");
        }
        $column = $side === 'sell' ? 'rate_sell' : 'rate_buy';
        $existing = $this->getRates($currency);
        $stmt = $this->pdo->prepare(
            "INSERT INTO rates (currency, rate_buy, rate_sell, created_at, updated_at)
             VALUES (:currency, :rate_buy, :rate_sell, NOW(), NOW())
             ON DUPLICATE KEY UPDATE {$column} = VALUES({$column}), updated_at = NOW()"
        );
        $rateBuy  = $column === 'rate_buy' ? $price : ($existing['rate_buy'] ?? $price);
        $rateSell = $column === 'rate_sell' ? $price : ($existing['rate_sell'] ?? $price);
        $stmt->execute([
            ':currency' => $currency,
            ':rate_buy' => $rateBuy,
            ':rate_sell'=> $rateSell,
        ]);
    }

    public function setFees(string $currency, float $servicePercent, float $networkFlat): void
    {
        $currency = strtoupper($currency);
        if (!in_array($currency, $this->supportedCurrencies, true)) {
            throw new \InvalidArgumentException("Unsupported currency {$currency}");
        }
        $stmt = $this->pdo->prepare(
            "INSERT INTO fees (currency, service_fee_percent, network_fee_flat, created_at, updated_at)
             VALUES (:currency, :service_fee_percent, :network_fee_flat, NOW(), NOW())
             ON DUPLICATE KEY UPDATE service_fee_percent = VALUES(service_fee_percent),
             network_fee_flat = VALUES(network_fee_flat), updated_at = NOW()"
        );
        $stmt->execute([
            ':currency'            => $currency,
            ':service_fee_percent' => $servicePercent,
            ':network_fee_flat'    => $networkFlat,
        ]);
    }
}
