defmodule ToweropsWeb.Plugs.ApiAuth do
  @moduledoc """
  Plug for authenticating API requests using Bearer tokens.

  Expects the Authorization header to contain a Bearer token:
    Authorization: Bearer towerops_xxxxx

  Sets the following assigns on successful authentication:
  - :current_organization_id - The organization ID the token is scoped to
  - :api_authenticated - true

  Returns 401 Unauthorized if:
  - No Authorization header is present
  - Token is invalid or expired
  - Token format is incorrect
  """

  import Phoenix.Controller, only: [json: 2]
  import Plug.Conn

  alias Towerops.ApiTokens

  def init(opts), do: opts

  def call(conn, _opts) do
    case get_req_header(conn, "authorization") do
      ["Bearer " <> token] ->
        authenticate_with_token(conn, token)

      _ ->
        conn
        |> put_status(:unauthorized)
        |> json(%{error: "Missing or invalid Authorization header"})
        |> halt()
    end
  end

  defp authenticate_with_token(conn, token) do
    case ApiTokens.verify_token(token) do
      {:ok, organization_id, user} ->
        conn
        |> assign(:current_organization_id, organization_id)
        |> assign(:current_user, user)
        |> assign(:api_authenticated, true)

      {:error, :invalid_token} ->
        conn
        |> put_status(:unauthorized)
        |> json(%{error: "Invalid or expired API token"})
        |> halt()
    end
  end
end
