defmodule BerrypodWeb.Admin.OrdersTest do
  use BerrypodWeb.ConnCase, async: false

  import Phoenix.LiveViewTest
  import Berrypod.AccountsFixtures
  import Berrypod.OrdersFixtures

  setup do
    user = user_fixture()
    %{user: user}
  end

  describe "unauthenticated" do
    test "redirects to login", %{conn: conn} do
      {:error, redirect} = live(conn, ~p"/admin/orders")
      assert {:redirect, %{to: path}} = redirect
      assert path == ~p"/users/log-in"
    end
  end

  describe "order list" do
    setup %{conn: conn, user: user} do
      conn = log_in_user(conn, user)
      %{conn: conn}
    end

    test "renders empty state when no orders", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/orders")

      assert html =~ "No orders yet"
      assert html =~ "Orders"
    end

    test "renders orders table", %{conn: conn} do
      order = order_fixture(payment_status: "paid", customer_email: "test@shop.com")

      {:ok, _view, html} = live(conn, ~p"/admin/orders")

      assert html =~ order.order_number
      assert html =~ "test@shop.com"
      assert html =~ "paid"
    end

    test "filters by status", %{conn: conn} do
      paid = order_fixture(payment_status: "paid")
      _pending = order_fixture()

      {:ok, view, _html} = live(conn, ~p"/admin/orders")

      html = render_click(view, "filter", %{"status" => "paid"})

      assert html =~ paid.order_number
    end

    test "navigates to order detail", %{conn: conn} do
      order = order_fixture(payment_status: "paid")

      {:ok, _view, html} = live(conn, ~p"/admin/orders")

      assert html =~ ~p"/admin/orders/#{order}"
    end
  end

  describe "order detail" do
    setup %{conn: conn, user: user} do
      conn = log_in_user(conn, user)
      %{conn: conn}
    end

    test "renders order details", %{conn: conn} do
      order = order_fixture(payment_status: "paid", customer_email: "buyer@example.com")

      {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")

      assert html =~ order.order_number
      assert html =~ "buyer@example.com"
      assert html =~ "paid"
      assert html =~ "Order details"
    end

    test "shows line items", %{conn: conn} do
      order = order_fixture(product_name: "Cool T-shirt", variant_title: "Blue / XL")

      {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")

      assert html =~ "Cool T-shirt"
      assert html =~ "Blue / XL"
    end

    test "shows shipping address", %{conn: conn} do
      order = order_fixture(payment_status: "paid")

      {:ok, updated_order} =
        Berrypod.Orders.update_order(order, %{
          shipping_address: %{
            "name" => "Jane Doe",
            "line1" => "42 Test Street",
            "city" => "London",
            "postal_code" => "SW1A 1AA",
            "country" => "GB"
          }
        })

      {:ok, _view, html} = live(conn, ~p"/admin/orders/#{updated_order}")

      assert html =~ "Jane Doe"
      assert html =~ "42 Test Street"
      assert html =~ "London"
      assert html =~ "SW1A 1AA"
    end

    test "redirects when order not found", %{conn: conn} do
      fake_id = Ecto.UUID.generate()

      {:error, {:live_redirect, %{to: "/admin/orders"}}} =
        live(conn, ~p"/admin/orders/#{fake_id}")
    end

    test "shows timeline card", %{conn: conn} do
      order = order_fixture(payment_status: "paid")

      {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")

      assert html =~ "Timeline"
      assert html =~ "unfulfilled"
    end

    test "shows submit button for paid unfulfilled orders", %{conn: conn} do
      order = order_fixture(payment_status: "paid")

      {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")

      assert html =~ "Submit to provider"
    end

    test "shows retry button for failed fulfilment", %{conn: conn} do
      order = order_fixture(payment_status: "paid")

      {:ok, order} =
        Berrypod.Orders.update_fulfilment(order, %{fulfilment_status: "failed"})

      {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")

      assert html =~ "Retry submission"
    end

    test "shows refresh button for submitted orders", %{conn: conn} do
      {order, _v, _p, _c} =
        Berrypod.OrdersFixtures.submitted_order_fixture()

      {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")

      assert html =~ "Refresh status"
    end

    test "shows tracking info when available", %{conn: conn} do
      {order, _v, _p, _c} =
        Berrypod.OrdersFixtures.submitted_order_fixture()

      {:ok, order} =
        Berrypod.Orders.update_fulfilment(order, %{
          fulfilment_status: "shipped",
          tracking_number: "TRACK123",
          tracking_url: "https://track.example.com/TRACK123",
          shipped_at: DateTime.utc_now() |> DateTime.truncate(:second)
        })

      {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")

      assert html =~ "TRACK123"
      assert html =~ "https://track.example.com/TRACK123"
    end
  end

  describe "order timeline" do
    setup %{conn: conn, user: user} do
      conn = log_in_user(conn, user)
      %{conn: conn}
    end

    test "renders timeline entries for an order", %{conn: conn} do
      order = order_fixture(payment_status: "paid")

      Berrypod.ActivityLog.log_event("order.created", "Order placed", order_id: order.id)

      Berrypod.ActivityLog.log_event("order.submitted", "Submitted to provider",
        order_id: order.id
      )

      {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")

      assert html =~ "Order placed"
      assert html =~ "Submitted to provider"
    end

    test "shows empty state when no timeline entries", %{conn: conn} do
      order = order_fixture(payment_status: "paid")

      {:ok, _view, html} = live(conn, ~p"/admin/orders/#{order}")

      assert html =~ "No activity recorded yet"
    end

    test "updates timeline via PubSub", %{conn: conn} do
      order = order_fixture(payment_status: "paid")

      {:ok, view, _html} = live(conn, ~p"/admin/orders/#{order}")

      Berrypod.ActivityLog.log_event("order.submitted", "Submitted to provider",
        order_id: order.id
      )

      html = render(view)
      assert html =~ "Submitted to provider"
    end
  end

  describe "order list fulfilment column" do
    setup %{conn: conn, user: user} do
      conn = log_in_user(conn, user)
      %{conn: conn}
    end

    test "shows fulfilment badge in table", %{conn: conn} do
      order_fixture(payment_status: "paid")

      {:ok, _view, html} = live(conn, ~p"/admin/orders")

      assert html =~ "Fulfilment"
      assert html =~ "unfulfilled"
    end
  end
end
