# frozen_string_literal: true

require "net/http"
require "ox"

require "provider/adapters/adapter"

class Provider
  module Adapters
    # National Bank of Romania. Publishes daily reference rates for ~35
    # currencies against the Romanian leu (RON). Yearly XML archives back to
    # 2005 are kept current within the year. The 10-day feed is a redundant
    # window over the same data, so we always use the yearly archive.
    class BNR < Adapter
      BASE_URL = "https://www.bnr.ro"

      class << self
        def backfill_range = 365
      end

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

        records = if after.nil? || after.year == end_date.year
          fetch_year(after&.year || end_date.year)
        else
          (after.year..end_date.year).flat_map { |year| fetch_year(year) }
        end

        records.select { |r| (after.nil? || r[:date] > after) && r[:date] <= end_date }
      end

      def parse(xml)
        doc = Ox.load(xml)

        doc.locate("DataSet/Body/Cube").flat_map do |cube|
          date = Date.parse(cube[:date])
          cube.locate("Rate").filter_map do |rate_node|
            currency = rate_node[:currency]
            next unless currency&.match?(/\A[A-Z]{3}\z/)

            multiplier = rate_node[:multiplier]&.to_i || 1
            rate_value = Float(rate_node.text, exception: false)
            next unless rate_value

            rate_value /= multiplier if multiplier > 1
            rate_value *= GRAMS_PER_TROY_OUNCE if currency == "XAU"
            next if rate_value.zero?

            { date:, base: currency, quote: "RON", rate: rate_value }
          end
        end
      end

      private

      def fetch_year(year)
        parse(Net::HTTP.get(URI("#{BASE_URL}/files/xml/years/nbrfxrates#{year}.xml")))
      end
    end
  end
end
