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

  alias SimpleshopTheme.Orders
  alias SimpleshopTheme.Cart

  @impl true
  def mount(%{"id" => id}, _session, socket) do
    case Orders.get_order(id) do
      nil ->
        socket =
          socket
          |> put_flash(:error, "Order not found")
          |> push_navigate(to: ~p"/admin/orders")

        {:ok, socket}

      order ->
        socket =
          socket
          |> assign(:page_title, order.order_number)
          |> assign(:order, order)

        {:ok, socket}
    end
  end

  @impl true
  def render(assigns) do
    ~H"""
    <.header>
      <.link
        navigate={~p"/admin/orders"}
        class="text-sm font-normal text-base-content/60 hover:underline"
      >
        &larr; Orders
      </.link>
      <div class="flex items-center gap-3 mt-1">
        <span class="text-2xl font-bold">{@order.order_number}</span>
        <.status_badge status={@order.payment_status} />
      </div>
    </.header>

    <div class="grid gap-6 mt-6 lg:grid-cols-2">
      <%!-- order info --%>
      <div class="card bg-base-100 shadow-sm border border-base-200">
        <div class="card-body">
          <h3 class="card-title text-base">Order details</h3>
          <.list>
            <:item title="Date">{format_date(@order.inserted_at)}</:item>
            <:item title="Customer">{@order.customer_email || "—"}</:item>
            <:item title="Payment status">
              <.status_badge status={@order.payment_status} />
            </:item>
            <:item :if={@order.stripe_payment_intent_id} title="Stripe payment">
              <code class="text-xs">{@order.stripe_payment_intent_id}</code>
            </:item>
            <:item title="Currency">{String.upcase(@order.currency)}</:item>
          </.list>
        </div>
      </div>

      <%!-- shipping address --%>
      <div class="card bg-base-100 shadow-sm border border-base-200">
        <div class="card-body">
          <h3 class="card-title text-base">Shipping address</h3>
          <%= if @order.shipping_address != %{} do %>
            <.list>
              <:item :if={@order.shipping_address["name"]} title="Name">
                {@order.shipping_address["name"]}
              </:item>
              <:item :if={@order.shipping_address["line1"]} title="Address">
                {@order.shipping_address["line1"]}
                <span :if={@order.shipping_address["line2"]}>
                  <br />{@order.shipping_address["line2"]}
                </span>
              </:item>
              <:item :if={@order.shipping_address["city"]} title="City">
                {@order.shipping_address["city"]}
              </:item>
              <:item :if={@order.shipping_address["state"] not in [nil, ""]} title="State">
                {@order.shipping_address["state"]}
              </:item>
              <:item :if={@order.shipping_address["postal_code"]} title="Postcode">
                {@order.shipping_address["postal_code"]}
              </:item>
              <:item :if={@order.shipping_address["country"]} title="Country">
                {@order.shipping_address["country"]}
              </:item>
            </.list>
          <% else %>
            <p class="text-base-content/60 text-sm">No shipping address provided</p>
          <% end %>
        </div>
      </div>
    </div>

    <%!-- fulfilment --%>
    <div class="card bg-base-100 shadow-sm border border-base-200 mt-6">
      <div class="card-body">
        <div class="flex items-center justify-between">
          <h3 class="card-title text-base">Fulfilment</h3>
          <.fulfilment_badge status={@order.fulfilment_status} />
        </div>
        <.list>
          <:item :if={@order.provider_order_id} title="Provider order ID">
            <code class="text-xs">{@order.provider_order_id}</code>
          </:item>
          <:item :if={@order.provider_status} title="Provider status">
            {@order.provider_status}
          </:item>
          <:item :if={@order.submitted_at} title="Submitted">
            {format_date(@order.submitted_at)}
          </:item>
          <:item :if={@order.tracking_number} title="Tracking">
            <%= if @order.tracking_url do %>
              <a href={@order.tracking_url} target="_blank" class="link link-primary">
                {@order.tracking_number}
              </a>
            <% else %>
              {@order.tracking_number}
            <% end %>
          </:item>
          <:item :if={@order.shipped_at} title="Shipped">
            {format_date(@order.shipped_at)}
          </:item>
          <:item :if={@order.delivered_at} title="Delivered">
            {format_date(@order.delivered_at)}
          </:item>
          <:item :if={@order.fulfilment_error} title="Error">
            <span class="text-error text-sm">{@order.fulfilment_error}</span>
          </:item>
        </.list>
        <div class="flex gap-2 mt-4">
          <button
            :if={can_submit?(@order)}
            phx-click="submit_to_provider"
            class="btn btn-primary btn-sm"
          >
            <.icon name="hero-paper-airplane-mini" class="size-4" />
            {if @order.fulfilment_status == "failed",
              do: "Retry submission",
              else: "Submit to provider"}
          </button>
          <button
            :if={can_refresh?(@order)}
            phx-click="refresh_status"
            class="btn btn-ghost btn-sm"
          >
            <.icon name="hero-arrow-path-mini" class="size-4" /> Refresh status
          </button>
        </div>
      </div>
    </div>

    <%!-- line items --%>
    <div class="card bg-base-100 shadow-sm border border-base-200 mt-6">
      <div class="card-body">
        <h3 class="card-title text-base">Items</h3>
        <table class="table table-zebra">
          <thead>
            <tr>
              <th>Product</th>
              <th>Variant</th>
              <th class="text-right">Qty</th>
              <th class="text-right">Unit price</th>
              <th class="text-right">Total</th>
            </tr>
          </thead>
          <tbody>
            <tr :for={item <- @order.items}>
              <td>{item.product_name}</td>
              <td>{item.variant_title}</td>
              <td class="text-right">{item.quantity}</td>
              <td class="text-right">{Cart.format_price(item.unit_price)}</td>
              <td class="text-right">{Cart.format_price(item.unit_price * item.quantity)}</td>
            </tr>
          </tbody>
          <tfoot>
            <tr>
              <td colspan="4" class="text-right font-medium">Subtotal</td>
              <td class="text-right font-medium">{Cart.format_price(@order.subtotal)}</td>
            </tr>
            <tr class="text-lg">
              <td colspan="4" class="text-right font-bold">Total</td>
              <td class="text-right font-bold">{Cart.format_price(@order.total)}</td>
            </tr>
          </tfoot>
        </table>
      </div>
    </div>
    """
  end

  @impl true
  def handle_event("submit_to_provider", _params, socket) do
    order = socket.assigns.order

    case Orders.submit_to_provider(order) do
      {:ok, updated} ->
        socket =
          socket
          |> assign(:order, updated)
          |> put_flash(:info, "Order submitted to provider")

        {:noreply, socket}

      {:error, _reason} ->
        order = Orders.get_order(order.id)

        socket =
          socket
          |> assign(:order, order)
          |> put_flash(:error, order.fulfilment_error || "Submission failed")

        {:noreply, socket}
    end
  end

  def handle_event("refresh_status", _params, socket) do
    order = socket.assigns.order

    case Orders.refresh_fulfilment_status(order) do
      {:ok, updated} ->
        socket =
          socket
          |> assign(:order, updated)
          |> put_flash(:info, "Status refreshed")

        {:noreply, socket}

      {:error, reason} ->
        {:noreply, put_flash(socket, :error, "Failed to refresh: #{inspect(reason)}")}
    end
  end

  defp can_submit?(order) do
    order.payment_status == "paid" and order.fulfilment_status in ["unfulfilled", "failed"]
  end

  defp can_refresh?(order) do
    not is_nil(order.provider_order_id) and
      order.fulfilment_status in ["submitted", "processing", "shipped"]
  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 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
end
