defmodule ToweropsWeb.UserResetPasswordLive do
  @moduledoc """
  LiveView for resetting user password with HIBP password breach checking.
  """
  use ToweropsWeb, :live_view

  alias Towerops.Accounts
  alias Towerops.Accounts.HIBP

  def mount(%{"token" => token}, _session, socket) do
    case Accounts.get_user_by_reset_password_token(token) do
      nil ->
        {:ok,
         socket
         |> put_flash(:error, "Reset password link is invalid or has expired.")
         |> redirect(to: ~p"/users/log-in")}

      user ->
        changeset = Accounts.change_user_password(user)

        {:ok,
         socket
         |> assign(:form, to_form(changeset))
         |> assign(:token, token)
         |> assign(:user, user)
         |> assign(:password_breach_count, nil)}
    end
  end

  def handle_event("check_password_breach", %{"value" => password}, socket)
      when is_binary(password) and byte_size(password) > 0 do
    case HIBP.check_password(password) do
      {:ok, count} when is_integer(count) ->
        {:noreply, assign(socket, :password_breach_count, count)}

      {:ok, :unknown} ->
        {:noreply, assign(socket, :password_breach_count, nil)}
    end
  end

  def handle_event("check_password_breach", _params, socket) do
    {:noreply, socket}
  end

  def handle_event("validate", %{"user" => user_params}, socket) do
    changeset =
      socket.assigns.user
      |> Accounts.change_user_password(user_params)
      |> Map.put(:action, :validate)

    {:noreply, assign(socket, :form, to_form(changeset))}
  end

  def handle_event("save", %{"user" => user_params}, socket) do
    case Accounts.reset_user_password(socket.assigns.user, user_params) do
      {:ok, {updated_user, _expired_tokens}} ->
        {:noreply,
         socket
         |> put_flash(:info, "Password reset successfully.")
         |> redirect(to: ~p"/users/log-in?email=#{updated_user.email}")}

      {:error, changeset} ->
        {:noreply, assign(socket, :form, to_form(changeset))}
    end
  end

  def render(assigns) do
    ~H"""
    <Layouts.app flash={@flash}>
      <div class="mx-auto max-w-sm">
        <div class="text-center">
          <.header>
            Reset password
            <:subtitle>
              Enter your new password below.
            </:subtitle>
          </.header>
        </div>

        <div class="mt-8">
          <.form for={@form} phx-change="validate" phx-submit="save">
            <.input
              field={@form[:password]}
              type="password"
              label="New password"
              autocomplete="new-password"
              phx-blur="check_password_breach"
              phx-mounted={JS.focus()}
              required
            />

            <%= if @password_breach_count && @password_breach_count > 0 do %>
              <div class="mt-2 rounded-md bg-yellow-50 dark:bg-yellow-900/20 p-4">
                <div class="flex">
                  <div class="flex-shrink-0">
                    <.icon name="hero-exclamation-triangle" class="h-5 w-5 text-yellow-400" />
                  </div>
                  <div class="ml-3">
                    <h3 class="text-sm font-medium text-yellow-800 dark:text-yellow-200">
                      Password found in data breaches
                    </h3>
                    <div class="mt-2 text-sm text-yellow-700 dark:text-yellow-300">
                      <p>
                        This password has appeared {@password_breach_count}
                        {if @password_breach_count == 1, do: "time", else: "times"} in known data breaches. We strongly recommend choosing a different,
                        more unique password to protect your account.
                      </p>
                    </div>
                  </div>
                </div>
              </div>
            <% end %>

            <.input
              field={@form[:password_confirmation]}
              type="password"
              label="Confirm new password"
              autocomplete="new-password"
              required
            />
            <div class="mt-6">
              <.button phx-disable-with="Resetting password..." class="w-full" variant="primary">
                Reset password
              </.button>
            </div>
          </.form>

          <div class="mt-6 text-center">
            <.link
              navigate={~p"/users/log-in"}
              class="text-sm font-semibold text-blue-600 hover:text-blue-700 dark:text-blue-400 dark:hover:text-blue-300"
            >
              Back to log in
            </.link>
          </div>
        </div>
      </div>
    </Layouts.app>
    """
  end
end
