require "uri"

module ActiveHarness
  module Providers
    # Google Gemini — OpenAI-compatible endpoint (beta).
    # https://ai.google.dev/gemini-api/docs/openai
    class Gemini < Base
      def call(model:, messages:, temperature: 0.7, stream: nil)
        headers = { "Content-Type" => "application/json", "Authorization" => "Bearer #{api_key}" }
        body    = { model: model, messages: messages, temperature: temperature }

        return call_streaming(url: config.gemini_api_url, headers: headers, body: body, stream: stream, provider: :gemini, model: model) if stream

        raw  = post_json(URI(config.gemini_api_url), headers: headers, body: body)
        data = parse!(raw)
        handle_error!(data)

        { content: data.dig("choices", 0, "message", "content").to_s.strip, provider: :gemini, model: data["model"] || model, usage: extract_usage_openai(data) }
      end

      private

      def api_key
        key = config.gemini_api_key.to_s
        raise Errors::InvalidApiKeyError, "gemini_api_key is not configured" if key.empty?
        key
      end

      def handle_error!(data)
        return unless data["error"]

        msg      = data.dig("error", "message").to_s
        code     = data.dig("error", "code").to_s
        status   = data.dig("error", "status").to_s
        metadata = data["error"].reject { |k, _| %w[message code status].include?(k) }
        metadata = nil if metadata.empty?

        case status
        when "UNAUTHENTICATED"
          raise Errors::InvalidApiKeyError.new(msg,       error_code: code, metadata: metadata)
        when "RESOURCE_EXHAUSTED"
          raise Errors::RateLimitError.new(msg,           error_code: code, metadata: metadata)
        when "UNAVAILABLE"
          raise Errors::ProviderUnavailableError.new(msg, error_code: code, metadata: metadata)
        when "INTERNAL"
          raise Errors::ServerError.new(msg,              error_code: code, metadata: metadata)
        else
          raise Errors::InvalidRequestError.new(msg,      error_code: code, metadata: metadata)
        end
      end
    end
  end
end
