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

  alias Berrypod.Orders
  alias Berrypod.Cart

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

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

    {:ok, socket}
  end

  @impl true
  def handle_params(params, _uri, socket) do
    page_num = Berrypod.Pagination.parse_page(params)
    page = Orders.list_orders_paginated(status: socket.assigns.status_filter, page: page_num)

    socket =
      socket
      |> assign(:pagination, page)
      |> assign(:order_count, page.total_count)
      |> stream(:orders, page.items, reset: true)

    {:noreply, socket}
  end

  @impl true
  def handle_event("filter", %{"status" => status}, socket) do
    {:noreply,
     socket
     |> assign(:status_filter, status)
     |> push_patch(to: ~p"/admin/orders")}
  end

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

    <div class="admin-filter-row">
      <.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>

    <.admin_pagination :if={@order_count > 0} page={@pagination} patch={~p"/admin/orders"} />

    <div :if={@order_count == 0} class="admin-empty-state">
      <.icon name="hero-inbox" class="admin-empty-state-icon" />
      <p class="admin-empty-state-title">No orders yet</p>
      <p class="admin-empty-state-text">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={[
        "admin-btn admin-btn-sm",
        @active && "admin-btn-primary",
        !@active && "admin-btn-ghost"
      ]}
    >
      {@label}
      <span :if={@count > 0} class="admin-badge admin-badge-sm admin-badge-count">
        {@count}
      </span>
    </button>
    """
  end

  defp status_badge(assigns) do
    {color, icon} =
      case assigns.status do
        "paid" -> {"green", "hero-check-circle-mini"}
        "pending" -> {"amber", "hero-clock-mini"}
        "failed" -> {"red", "hero-x-circle-mini"}
        "refunded" -> {"zinc", "hero-arrow-uturn-left-mini"}
        _ -> {"zinc", "hero-question-mark-circle-mini"}
      end

    assigns = assign(assigns, color: color, icon: icon)

    ~H"""
    <span class={["admin-status-pill", "admin-status-pill-#{@color}"]}>
      <.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
    {color, icon} =
      case assigns.status do
        "submitted" -> {"blue", "hero-paper-airplane-mini"}
        "processing" -> {"amber", "hero-cog-6-tooth-mini"}
        "shipped" -> {"purple", "hero-truck-mini"}
        "delivered" -> {"green", "hero-check-circle-mini"}
        "failed" -> {"red", "hero-x-circle-mini"}
        "cancelled" -> {"zinc", "hero-no-symbol-mini"}
        _ -> {"zinc", "hero-minus-circle-mini"}
      end

    assigns = assign(assigns, color: color, icon: icon)

    ~H"""
    <span class={["admin-status-pill", "admin-status-pill-#{@color}"]}>
      <.icon name={@icon} class="size-3" /> {@status}
    </span>
    """
  end

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