defmodule Tarakan.Billing.Stripe.API do
  @moduledoc """
  Req-based Stripe REST implementation.

  Authenticates with the `:stripe_secret_key` application env as a bearer
  token. POST/DELETE bodies are form-encoded, as the Stripe API expects.
  """

  @behaviour Tarakan.Billing.Stripe

  @base_url "https://api.stripe.com"

  @impl true
  def request(method, path, body_or_params \\ nil) do
    req = Req.new(base_url: @base_url, auth: {:bearer, secret_key()})

    opts =
      case {method, body_or_params} do
        {:get, params} when not is_nil(params) -> [params: params]
        {_method, nil} -> []
        {_method, body} -> [form: body]
      end

    case Req.request(req, [method: method, url: path] ++ opts) do
      {:ok, %Req.Response{status: status, body: body}} when status in 200..299 ->
        {:ok, body}

      {:ok, %Req.Response{status: status, body: body}} ->
        {:error, {:stripe_error, status, body}}

      {:error, reason} ->
        {:error, reason}
    end
  end

  defp secret_key, do: Application.get_env(:tarakan, :stripe_secret_key)
end
