defmodule BerrypodWeb.Admin.Providers.Index do
  use BerrypodWeb, :live_view

  alias Berrypod.Products
  alias Berrypod.Products.ProviderConnection
  alias Berrypod.Providers.Provider

  @impl true
  def mount(_params, _session, socket) do
    connections = Products.list_provider_connections()

    {:ok,
     socket
     |> assign(:page_title, "Provider connections")
     |> assign(:available_providers, Provider.available())
     |> stream(:connections, connections)}
  end

  @impl true
  def handle_event("delete", %{"id" => id}, socket) do
    connection = Products.get_provider_connection!(id)
    {:ok, _} = Products.delete_provider_connection(connection)

    {:noreply,
     socket
     |> stream_delete(:connections, connection)
     |> put_flash(:info, "Provider connection deleted")}
  end

  @impl true
  def handle_event("sync", %{"id" => id}, socket) do
    connection = Products.get_provider_connection!(id)

    case Products.enqueue_sync(connection) do
      {:ok, _job} ->
        # Update the connection status in the stream
        updated = %{connection | sync_status: "syncing"}

        {:noreply,
         socket
         |> stream_insert(:connections, updated)
         |> put_flash(:info, "Sync started for #{connection.name}")}

      {:error, _reason} ->
        {:noreply, put_flash(socket, :error, "Failed to start sync")}
    end
  end

  # Function components for the template

  attr :status, :string, required: true
  attr :enabled, :boolean, required: true

  defp status_indicator(assigns) do
    ~H"""
    <span class={[
      "admin-provider-dot",
      cond do
        not @enabled -> "admin-provider-dot-idle"
        @status == "syncing" -> "admin-provider-dot-syncing"
        @status == "completed" -> "admin-provider-dot-ok"
        @status == "failed" -> "admin-provider-dot-error"
        true -> "admin-provider-dot-idle"
      end
    ]} />
    """
  end

  attr :connection, ProviderConnection, required: true

  defp connection_info(assigns) do
    product_count = Products.count_products_for_connection(assigns.connection.id)
    assigns = assign(assigns, :product_count, product_count)

    ~H"""
    <span>
      <.icon name="hero-cube" class="size-4 inline" />
      {@product_count} {if @product_count == 1, do: "product", else: "products"}
    </span>
    <span :if={@connection.last_synced_at}>
      <.icon name="hero-clock" class="size-4 inline" />
      Last synced {format_relative_time(@connection.last_synced_at)}
    </span>
    <span :if={!@connection.last_synced_at} class="admin-text-warning">
      <.icon name="hero-exclamation-triangle" class="size-4 inline" /> Never synced
    </span>
    """
  end

  defp provider_name(type) do
    case Provider.get(type) do
      %{name: name} -> name
      nil -> String.capitalize(type)
    end
  end

  defp format_relative_time(datetime) do
    diff = DateTime.diff(DateTime.utc_now(), datetime, :second)

    cond do
      diff < 60 -> "just now"
      diff < 3600 -> "#{div(diff, 60)} min ago"
      diff < 86400 -> "#{div(diff, 3600)} hours ago"
      true -> "#{div(diff, 86400)} days ago"
    end
  end
end
