defmodule SimpleshopThemeWeb.Admin.Orders do
  use SimpleshopThemeWeb, :live_view

  alias SimpleshopTheme.Orders
  alias SimpleshopTheme.Cart

  @impl true
  def mount(_params, _session, socket) do
    counts = Orders.count_orders_by_status()
    orders = Orders.list_orders()

    socket =
      socket
      |> assign(:page_title, "Orders")
      |> assign(:status_filter, "all")
      |> assign(:status_counts, counts)
      |> assign(:order_count, length(orders))
      |> stream(:orders, orders)

    {:ok, socket}
  end

  @impl true
  def handle_event("filter", %{"status" => status}, socket) do
    orders = Orders.list_orders(status: status)

    socket =
      socket
      |> assign(:status_filter, status)
      |> assign(:order_count, length(orders))
      |> stream(:orders, orders, reset: true)

    {:noreply, socket}
  end

  @impl true
  def render(assigns) do
    ~H"""
    <.header>
      Orders
    </.header>

    <div class="flex gap-2 mt-6 mb-4 flex-wrap">
      <.filter_tab
        status="all"
        label="All"
        count={total_count(@status_counts)}
        active={@status_filter}
      />
      <.filter_tab
        status="paid"
        label="Paid"
        count={@status_counts["paid"]}
        active={@status_filter}
      />
      <.filter_tab
        status="pending"
        label="Pending"
        count={@status_counts["pending"]}
        active={@status_filter}
      />
      <.filter_tab
        status="failed"
        label="Failed"
        count={@status_counts["failed"]}
        active={@status_filter}
      />
      <.filter_tab
        status="refunded"
        label="Refunded"
        count={@status_counts["refunded"]}
        active={@status_filter}
      />
    </div>

    <.table
      :if={@order_count > 0}
      id="orders"
      rows={@streams.orders}
      row_item={fn {_id, order} -> order end}
      row_click={fn {_id, order} -> JS.navigate(~p"/admin/orders/#{order}") end}
    >
      <:col :let={order} label="Order">{order.order_number}</:col>
      <:col :let={order} label="Date">{format_date(order.inserted_at)}</:col>
      <:col :let={order} label="Customer">{order.customer_email || "—"}</:col>
      <:col :let={order} label="Total">{Cart.format_price(order.total)}</:col>
      <:col :let={order} label="Status"><.status_badge status={order.payment_status} /></:col>
      <:col :let={order} label="Fulfilment">
        <.fulfilment_badge status={order.fulfilment_status} />
      </:col>
    </.table>

    <div :if={@order_count == 0} class="text-center py-12 text-base-content/60">
      <.icon name="hero-inbox" class="size-12 mx-auto mb-4" />
      <p class="text-lg font-medium">No orders yet</p>
      <p class="text-sm mt-1">Orders will appear here once customers check out.</p>
    </div>
    """
  end

  defp filter_tab(assigns) do
    count = assigns[:count] || 0
    active = assigns.active == assigns.status

    assigns = assign(assigns, count: count, active: active)

    ~H"""
    <button
      phx-click="filter"
      phx-value-status={@status}
      class={[
        "btn btn-sm",
        @active && "btn-primary",
        !@active && "btn-ghost"
      ]}
    >
      {@label}
      <span :if={@count > 0} class="badge badge-sm ml-1">{@count}</span>
    </button>
    """
  end

  defp status_badge(assigns) do
    {bg, text, ring, icon} =
      case assigns.status do
        "paid" ->
          {"bg-green-50", "text-green-700", "ring-green-600/20", "hero-check-circle-mini"}

        "pending" ->
          {"bg-amber-50", "text-amber-700", "ring-amber-600/20", "hero-clock-mini"}

        "failed" ->
          {"bg-red-50", "text-red-700", "ring-red-600/20", "hero-x-circle-mini"}

        "refunded" ->
          {"bg-base-200/50", "text-base-content/60", "ring-base-content/10",
           "hero-arrow-uturn-left-mini"}

        _ ->
          {"bg-base-200/50", "text-base-content/60", "ring-base-content/10",
           "hero-question-mark-circle-mini"}
      end

    assigns = assign(assigns, bg: bg, text: text, ring: ring, icon: icon)

    ~H"""
    <span class={[
      "inline-flex items-center gap-1 rounded-full px-2 py-1 text-xs font-medium ring-1 ring-inset",
      @bg,
      @text,
      @ring
    ]}>
      <.icon name={@icon} class="size-3" /> {@status}
    </span>
    """
  end

  defp format_date(datetime) do
    Calendar.strftime(datetime, "%d %b %Y %H:%M")
  end

  defp fulfilment_badge(assigns) do
    {bg, text, ring, icon} =
      case assigns.status do
        "submitted" ->
          {"bg-blue-50", "text-blue-700", "ring-blue-600/20", "hero-paper-airplane-mini"}

        "processing" ->
          {"bg-amber-50", "text-amber-700", "ring-amber-600/20", "hero-cog-6-tooth-mini"}

        "shipped" ->
          {"bg-purple-50", "text-purple-700", "ring-purple-600/20", "hero-truck-mini"}

        "delivered" ->
          {"bg-green-50", "text-green-700", "ring-green-600/20", "hero-check-circle-mini"}

        "failed" ->
          {"bg-red-50", "text-red-700", "ring-red-600/20", "hero-x-circle-mini"}

        "cancelled" ->
          {"bg-base-200/50", "text-base-content/60", "ring-base-content/10",
           "hero-no-symbol-mini"}

        _ ->
          {"bg-base-200/50", "text-base-content/60", "ring-base-content/10",
           "hero-minus-circle-mini"}
      end

    assigns = assign(assigns, bg: bg, text: text, ring: ring, icon: icon)

    ~H"""
    <span class={[
      "inline-flex items-center gap-1 rounded-full px-2 py-1 text-xs font-medium ring-1 ring-inset",
      @bg,
      @text,
      @ring
    ]}>
      <.icon name={@icon} class="size-3" /> {@status}
    </span>
    """
  end

  defp total_count(counts) do
    counts |> Map.values() |> Enum.sum()
  end
end
