<?php

declare(strict_types=1);

namespace ApiModel\Infrastructure\Persistence\Repositories;

use ApiModel\Domain\Repository\ExchangeRateRepositoryInterface;
use ApiModel\Infrastructure\Persistence\Database;
use PDO;

final class PdoExchangeRateRepository implements ExchangeRateRepositoryInterface
{
    public function __construct(private readonly PDO $pdo) {}

    public function findRate(string $companyId, string $date, string $fromCurrency, string $toCurrency): ?array
    {
        $st = $this->pdo->prepare(
            'SELECT * FROM exchange_rates
             WHERE company_id = ? AND rate_date = ? AND from_currency = ? AND to_currency = ?
             LIMIT 1'
        );
        $st->execute([$companyId, $date, $fromCurrency, $toCurrency]);
        $row = $st->fetch();

        return $row !== false ? $row : null;
    }

    public function upsert(string $companyId, string $date, string $fromCurrency, string $toCurrency, string $rate): void
    {
        $existing = $this->findRate($companyId, $date, $fromCurrency, $toCurrency);
        if ($existing !== null) {
            $this->pdo->prepare(
                'UPDATE exchange_rates SET rate = ? WHERE id = ?'
            )->execute([$rate, $existing['id']]);

            return;
        }

        $this->pdo->prepare(
            'INSERT INTO exchange_rates (id, company_id, rate_date, from_currency, to_currency, rate)
             VALUES (?, ?, ?, ?, ?, ?)'
        )->execute([Database::uuid(), $companyId, $date, $fromCurrency, $toCurrency, $rate]);
    }

    public function listByCompany(string $companyId): array
    {
        $st = $this->pdo->prepare(
            'SELECT * FROM exchange_rates WHERE company_id = ? ORDER BY rate_date DESC, created_at DESC'
        );
        $st->execute([$companyId]);

        return $st->fetchAll(PDO::FETCH_ASSOC);
    }

    public function findById(string $id): ?array
    {
        $st = $this->pdo->prepare('SELECT * FROM exchange_rates WHERE id = ? LIMIT 1');
        $st->execute([$id]);
        $row = $st->fetch(PDO::FETCH_ASSOC);

        return $row !== false ? $row : null;
    }

    public function delete(string $id): void
    {
        $this->pdo->prepare('DELETE FROM exchange_rates WHERE id = ?')->execute([$id]);
    }
}
