defmodule BerrypodWeb.Auth.Login do
  use BerrypodWeb, :live_view

  alias Berrypod.{Accounts, Mailer}

  @impl true
  def render(assigns) do
    ~H"""
    <Layouts.app flash={@flash} current_scope={@current_scope}>
      <div class="setup-page">
        <div class="setup-header">
          <.header>
            Log in
            <:subtitle>
              <%= if @current_scope do %>
                You need to reauthenticate to perform sensitive actions on your account.
              <% else %>
                Log in with your admin credentials.
              <% end %>
            </:subtitle>
          </.header>
        </div>

        <div :if={local_mail_adapter?()} class="admin-alert admin-alert-info">
          <.icon name="hero-information-circle" class="size-6 shrink-0" />
          <div>
            <p>You are running the local mail adapter.</p>
            <p>
              To see sent emails, visit <.link href="/dev/mailbox" class="admin-link">the mailbox page</.link>.
            </p>
          </div>
        </div>

        <%= if @email_configured do %>
          <.form
            :let={f}
            for={@form}
            id="login_form_magic"
            action={~p"/users/log-in"}
            phx-submit="submit_magic"
          >
            <input :if={@return_to} type="hidden" name="return_to" value={@return_to} />
            <.input
              readonly={!!@current_scope}
              field={f[:email]}
              type="email"
              label="Email"
              autocomplete="email"
              required
              phx-mounted={JS.focus()}
            />
            <.button variant="primary" class="admin-btn-block">
              Log in with email <span aria-hidden="true">&rarr;</span>
            </.button>
          </.form>

          <div class="admin-divider">or</div>
        <% end %>

        <.form
          :let={f}
          for={@form}
          id="login_form_password"
          action={~p"/users/log-in"}
          phx-submit="submit_password"
          phx-trigger-action={@trigger_submit}
        >
          <input :if={@return_to} type="hidden" name="return_to" value={@return_to} />
          <.input
            readonly={!!@current_scope}
            field={f[:email]}
            type="email"
            label="Email"
            autocomplete="email"
            required
          />
          <.input
            field={@form[:password]}
            type="password"
            label="Password"
            autocomplete="current-password"
          />
          <.button
            variant="primary"
            class="admin-btn-block"
            name={@form[:remember_me].name}
            value="true"
          >
            Log in and stay logged in <span aria-hidden="true">&rarr;</span>
          </.button>
          <.button class="admin-btn-block">
            Log in only this time
          </.button>
        </.form>

        <p :if={!@email_configured} class="setup-footer">
          Locked out?
          <.link navigate={~p"/recover"} class="admin-link">
            Recover with setup secret
          </.link>
        </p>
      </div>
    </Layouts.app>
    """
  end

  @impl true
  def mount(params, _session, socket) do
    email =
      Phoenix.Flash.get(socket.assigns.flash, :email) ||
        get_in(socket.assigns, [:current_scope, Access.key(:user), Access.key(:email)])

    form = to_form(%{"email" => email}, as: "user")
    return_to = params["return_to"]

    {:ok,
     assign(socket,
       form: form,
       trigger_submit: false,
       email_configured: Mailer.email_verified?(),
       return_to: return_to
     )}
  end

  @impl true
  def handle_event("submit_password", _params, socket) do
    {:noreply, assign(socket, :trigger_submit, true)}
  end

  def handle_event("submit_magic", %{"user" => %{"email" => email}}, socket) do
    if user = Accounts.get_user_by_email(email) do
      Accounts.deliver_login_instructions(
        user,
        &url(~p"/users/log-in/#{&1}")
      )
    end

    info =
      "If your email is in our system, you will receive instructions for logging in shortly."

    {:noreply,
     socket
     |> put_flash(:info, info)
     |> push_navigate(to: ~p"/users/log-in")}
  end

  defp local_mail_adapter? do
    Application.get_env(:berrypod, Berrypod.Mailer)[:adapter] ==
      Swoosh.Adapters.Local
  end
end
