# frozen_string_literal: true

require "csv"
require "net/http"

require "provider/adapters/adapter"

class Provider
  module Adapters
    # Banca d'Italia. Publishes daily exchange rates for 150+ currencies against the euro via the "terze valute"
    # (third currencies) portal. Uses the dailyRates endpoint with currencyIsoCode=EUR to get all currencies quoted
    # against EUR for a single date.
    class BDI < Adapter
      URL = "https://tassidicambio.bancaditalia.it/terzevalute-wf-web/rest/v1.0/dailyRates"

      class << self
        def backfill_range = 30
      end

      def fetch(after: nil, upto: nil)
        end_date = upto || Date.today
        dataset = []

        first = true
        (after..end_date).each do |date|
          next if date.saturday? || date.sunday?

          sleep(0.3) unless first
          first = false

          dataset.concat(fetch_date(date))
        end

        dataset
      end

      def parse(csv)
        rows = CSV.parse(csv, headers: true)

        rows.filter_map do |row|
          code = row["ISO Code"]
          next unless code&.match?(/\A[A-Z]{3}\z/)

          rate_str = row["Rate"]
          next if rate_str.nil? || rate_str.strip == "N.A."

          rate_value = Float(rate_str)
          next if rate_value.zero?

          date_str = row["Reference date (CET)"]
          next unless date_str

          date = Date.parse(date_str)

          { date:, base: "EUR", quote: code, rate: rate_value }
        end
      end

      private

      def fetch_date(date)
        url = URI(URL)
        url.query = URI.encode_www_form(
          referenceDate: date.strftime("%Y-%m-%d"),
          currencyIsoCode: "EUR",
          lang: "en",
        )
        response = Net::HTTP.get(url)
        parse(response)
      end
    end
  end
end
