 
   require Ueberauth
   use Phoenix.Controller
-  alias Plug.Conn
-  alias Sentinel.AfterRegistrator
+  alias Sentinel.Controllers.Json
+  alias Sentinel.Controllers.Html
   alias Sentinel.Config
-  alias Sentinel.Ueberauthenticator
-  alias Sentinel.UserHelper
-  alias Sentinel.Util
-  alias Ueberauth.Strategy.Helpers
 
   plug Ueberauth
   plug Guardian.Plug.VerifyHeader when action in [:delete]


  #FIXME wtf does this do in the example app
  def request(conn, _params) do
    json conn, %{callback_url: Helpers.callback_url(conn)}
  end

  def callback(%{assigns: %{ueberauth_failure: _fails}} = conn, _params) do
    failed_to_authenticate(conn)
  end
  def callback(%{assigns: %{ueberauth_auth: auth}} = conn, _params) do
    case Ueberauthenticator.ueberauthenticate(auth) do
      {:ok, %{user: user, confirmation_token: confirmation_token}} ->
        new_user(conn, user, confirmation_token)
      {:ok, user} -> existing_user(conn, user)
      {:error, errors} ->
        failed_to_authenticate(conn)
    end
  end

  defp failed_to_authenticate(conn) do
    if conn.private.phoenix_format == "json" do
      Util.send_error(conn, %{error: "Failed to authenticate"}, 401)
    else
      changeset = Sentinel.Session.changeset(%Sentinel.Session{})
      conn
      |> put_status(401)
      |> put_flash(:error, "Failed to authenticate")
      |> render(Sentinel.SessionView, "new.html", %{conn: conn, changeset: changeset, providers: Config.ueberauth_providers})
    end
  end

  defp new_user(conn, user, confirmation_token) do
    {:ok, user} = AfterRegistrator.confirmable_and_invitable(user, confirmation_token)

    if conn.private.phoenix_format == "json" do
      conn
      |> put_status(201)
      |> json Config.user_view.render("show.json", %{user: user})
    else
      ueberauth = Config.repo.get_by(Sentinel.Ueberauth, provider: "identity", user_id: user.id)

      if is_nil(ueberauth.hashed_password) do
        conn
        |> put_flash(:info, "Successfully invited user")
        |> redirect(to: Config.router_helper.user_path(Config.endpoint, :new))
      else
        conn
        |> Guardian.Plug.sign_in(user)
        |> put_flash(:info, "Signed up")
        |> redirect(to: Config.router_helper.account_path(Config.endpoint, :edit))
      end
    end
  end

  defp existing_user(conn, user) do
    if conn.private.phoenix_format == "json" do
      permissions = UserHelper.model.permissions(user.id)

      case Guardian.encode_and_sign(user, :token, permissions) do
        {:ok, token, _encoded_claims} ->
          conn
          |> put_status(201)
          |> json %{token: token}
          {:error, :token_storage_failure} -> Util.send_error(conn, %{error: "Failed to store session, please try to login again using your new password"})
          {:error, reason} -> Util.send_error(conn, %{error: reason})
      end
    else
      conn
      |> Guardian.Plug.sign_in(user)
      |> put_flash(:info, "Logged in")
      |> redirect(to: Config.router_helper.account_path(Config.endpoint, :edit))
    end
  end


  Destroy the active session.
  Will delete the authentication token from the user table.
  """
  def delete(conn, params) do
    if conn.private.phoenix_format == "json" do
      Json.AuthController.delete(conn, params)
    else
      Html.AuthController.delete(conn, params)
    end
  end

  @doc """
  Log in as an existing user.
  """
  def create(conn, params) do
    if conn.private.phoenix_format == "json" do
      Json.AuthController.create(conn, params)
    else
      Html.AuthController.create(conn, params)
    end
  end
end
