defmodule PrymnWeb.ServerLive.NewServer do
  use PrymnWeb, :live_component

  alias Prymn.Servers
  require Logger

  @impl true
  def render(assigns) do
    ~H"""
    <div>
      <.header>
        Add a new server
        <:subtitle>Connect your server to Prymn!</:subtitle>
      </.header>

      <.error :if={assigns[:error]}>There were some errors.</.error>

      <.simple_form
        id="server-form"
        for={@form}
        phx-change="validate"
        phx-submit="connect"
        phx-target={@myself}
      >
        <.input field={@form[:name]} label="Server Name" phx-debounce={1000} />
        <.input
          field={@form[:provider]}
          label="Provider"
          type="select"
          prompt="Select a provider"
          options={Ecto.Enum.mappings(Servers.Server, :provider)}
        />
        <.provider id="provider" provider={@form[:provider]} />
        <:actions>
          <Button.primary>Connect</Button.primary>
        </:actions>
      </.simple_form>
    </div>
    """
  end

  @impl true
  def update(assigns, socket) do
    changeset = Servers.change_server(%Servers.Server{})

    socket =
      socket
      |> assign(assigns)
      |> assign(:form, to_form(changeset))

    {:ok, socket}
  end

  @impl true
  def handle_event("validate", %{"server" => params}, socket) do
    form =
      %Servers.Server{}
      |> Servers.change_server(params)
      |> Map.put(:action, :validate)
      |> to_form()

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

  @impl true
  def handle_event("connect", %{"server" => params}, socket) do
    socket =
      case Servers.create_server(params) do
        {:ok, server} ->
          # Notify parent
          send(self(), {:connect, server})

          socket
          |> put_flash(:info, "Starting new server connection...")
          |> push_patch(to: ~p"/servers")

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

    {:noreply, socket}
  end

  defp provider(%{provider: %{value: :Custom}} = assigns) do
    ~H"""
    <p>
      <bold class="font-bold">Manual installation:</bold>
      To connect, you must have root SSH access to your server. When you click
      connect, you will be prompted to execute a command on your server to
      complete the installation.
    </p>
    """
  end

  defp provider(assigns), do: ~H""
end