defmodule ScrabblexWeb.UserRegistrationLive do
  use ScrabblexWeb, :live_view

  alias Scrabblex.Accounts
  alias Scrabblex.Accounts.User

  def render(assigns) do
    ~H"""
    <div class="p-10">
      <div class="mx-auto max-w-lg rounded-xl bg-white p-10">
        <h1 class="text-3xl font-bold text-center">Register for an account</h1>

        <.simple_form
          for={@form}
          id="registration_form"
          phx-submit="save"
          phx-change="validate"
          phx-trigger-action={@trigger_submit}
          action={~p"/users/log_in?_action=registered"}
          method="post"
        >
          <.error :if={@check_errors}>
            Oops, something went wrong! Please check the errors below.
          </.error>

          <.input field={@form[:email]} type="email" label="Email" required />
          <.input field={@form[:password]} type="password" label="Password" required />
          <.input field={@form[:name]} type="text" label="Username" required />

          <:actions>
            <.button phx-disable-with="Creating account..." class="w-full">Create an account</.button>
          </:actions>
        </.simple_form>

        <div class="relative mt-6">
          <div class="absolute flex items-center inset-0">
            <div class="w-full border-t border-gray-200"></div>
          </div>
          <div class="flex relative justify-center leading-6">
            <span class="px-4 bg-white">or continue with</span>
          </div>
        </div>

        <.button class="w-full mt-6">
          <.link href={~p"/auth/github"} class="inline-flex items-baseline">
            <img src={~p"/images/github-mark-white.svg"} class="w-6 mr-2 self-center" />
            <span>Login with Github</span>
          </.link>
        </.button>
      </div>

      <div class="text-center mt-10 text-sm">
        Already registered?
        <.link navigate={~p"/users/log_in"} class="font-semibold text-brand hover:underline">
          Log in
        </.link>
        to your account now.
      </div>
    </div>
    """
  end

  def mount(_params, _session, socket) do
    changeset = Accounts.change_user_registration(%User{})

    socket =
      socket
      |> assign(trigger_submit: false, check_errors: false)
      |> assign_form(changeset)

    {:ok, socket, temporary_assigns: [form: nil]}
  end

  def handle_event("save", %{"user" => user_params}, socket) do
    case Accounts.register_user(user_params) do
      {:ok, user} ->
        {:ok, _} =
          Accounts.deliver_user_confirmation_instructions(
            user,
            &url(~p"/users/confirm/#{&1}")
          )

        changeset = Accounts.change_user_registration(user)
        {:noreply, socket |> assign(trigger_submit: true) |> assign_form(changeset)}

      {:error, %Ecto.Changeset{} = changeset} ->
        {:noreply, socket |> assign(check_errors: true) |> assign_form(changeset)}
    end
  end

  def handle_event("validate", %{"user" => user_params}, socket) do
    changeset = Accounts.change_user_registration(%User{}, user_params)
    {:noreply, assign_form(socket, Map.put(changeset, :action, :validate))}
  end

  defp assign_form(socket, %Ecto.Changeset{} = changeset) do
    form = to_form(changeset, as: "user")

    if changeset.valid? do
      assign(socket, form: form, check_errors: false)
    else
      assign(socket, form: form)
    end
  end
end
