<?php

namespace App\HttpClients\Clients;

use App\HttpClients\Contracts\TipoCambioClient;
use App\HttpClients\DTOs\TipoCambioResponse;
use Illuminate\Support\Facades\Http;

class BCCRTipoCambioClient implements TipoCambioClient
{
    private $apiKey;

    public function __construct()
    {
        $this->apiKey = config('services.bccr.ssde.key');
    }

    public function getActual(string $moneda): TipoCambioResponse
    {
        $moneda = strtoupper(trim($moneda));
        if ($moneda !== 'USD') {
            throw new \InvalidArgumentException("BCCR client solo soporta USD. Moneda solicitada: {$moneda}");
        }

        $date = new \DateTimeImmutable('today', new \DateTimeZone('America/Costa_Rica'));

        $response = Http::withToken($this->apiKey)
            ->withOptions(['verify' => false])
            ->acceptJson()
            ->throw()
            ->get('https://apim.bccr.fi.cr/sddE/api/Bccr.Ge.SDDE.Publico.Indicadores.API/cuadro/1/series', [
                'idioma' => 'ES',
                'fechaInicio' => $date->format('Y/m/d'),
                'fechaFin'    => $date->format('Y/m/d'),
            ]);

        $raw = (string) $response->body();
        $data = json_decode($raw, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            throw new \RuntimeException("No valid data from BCCR");
        }

        $compra = $this->getValorDatoPorPeriodo($data, "317");
        $venta  = $this->getValorDatoPorPeriodo($data, "318");

        return new TipoCambioResponse(
            moneda: 'USD',
            compra: $compra,
            venta: $venta,
            fecha: $date,
            rawResponse: $raw,
            fuente: 'bccr'
        );
    }

    protected function getValorDatoPorPeriodo(array $data, string $codigoIndicador): ?float
    {
        if (!isset($data['datos'][0]['indicadores'])) {
            return null;
        }

        foreach ($data['datos'][0]['indicadores'] as $indicador) {
            if (($indicador['codigoIndicador'] ?? null) === $codigoIndicador) {
                return isset($indicador['series'][0]['valorDatoPorPeriodo'])
                    ? (float) $indicador['series'][0]['valorDatoPorPeriodo']
                    : null;
            }
        }

        return null;
    }
}
