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

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

  alias Berrypod.ActivityLog

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

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

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

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

      assert html =~ "Activity"
      assert html =~ "No activity to show"
    end

    test "renders activity entries", %{conn: conn} do
      ActivityLog.log_event("order.created", "Order placed")
      ActivityLog.log_event("order.shipped", "Order shipped")

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

      assert html =~ "Order placed"
      assert html =~ "Order shipped"
    end

    test "links to order when order_id present", %{conn: conn} do
      order = order_fixture(payment_status: "paid")

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

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

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

    test "filters by attention tab", %{conn: conn} do
      ActivityLog.log_event("sync.completed", "Sync OK")
      ActivityLog.log_event("order.submission_failed", "Submission failed", level: "error")

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

      html = render_click(view, "tab", %{"tab" => "attention"})

      assert html =~ "Submission failed"
      refute html =~ "Sync OK"
    end

    test "filters by category", %{conn: conn} do
      ActivityLog.log_event("sync.completed", "Sync done")
      ActivityLog.log_event("order.created", "Order placed")

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

      # Enable system events so sync.completed is visible
      render_click(view, "toggle_system")
      html = render_click(view, "category", %{"category" => "syncs"})

      assert html =~ "Sync done"
      refute html =~ "Order placed"
    end

    test "searches by order number", %{conn: conn} do
      order = order_fixture(payment_status: "paid")
      _other_order = order_fixture(payment_status: "paid")

      ActivityLog.log_event("order.created", "First order", order_id: order.id)

      ActivityLog.log_event("sync.completed", "Sync done")

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

      html =
        render_submit(view, "search", %{"search" => %{"query" => order.order_number}})

      assert html =~ "First order"
      refute html =~ "Sync done"
    end

    test "dismisses a warning entry", %{conn: conn} do
      {:ok, entry} =
        ActivityLog.log_event("order.cancelled", "Order cancelled", level: "warning")

      {:ok, view, html} = live(conn, ~p"/admin/activity?tab=attention")

      assert html =~ "Order cancelled"
      assert html =~ "Dismiss"

      render_click(view, "resolve", %{"id" => entry.id})

      {:ok, _view, html} = live(conn, ~p"/admin/activity?tab=attention")
      refute html =~ "Order cancelled"
    end

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

      ActivityLog.log_event("order.submission_failed", "Submission failed",
        level: "error",
        order_id: order.id
      )

      {:ok, _view, html} = live(conn, ~p"/admin/activity?tab=attention")

      assert html =~ "Retry submission"
    end

    test "shows retry sync button for failed syncs", %{conn: conn} do
      ActivityLog.log_event("sync.failed", "Sync failed",
        level: "error",
        payload: %{connection_id: Ecto.UUID.generate()}
      )

      {:ok, view, _html} = live(conn, ~p"/admin/activity?tab=attention")

      # sync.failed is a system event, hidden by default
      render_click(view, "toggle_system")
      html = render(view)

      assert html =~ "Retry sync"
    end

    test "updates via PubSub", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/admin/activity")

      ActivityLog.log_event("order.created", "New order arrived")

      html = render(view)
      assert html =~ "New order arrived"
    end

    test "system events hidden by default, shown after toggle", %{conn: conn} do
      ActivityLog.log_event("sync.completed", "Sync done")
      ActivityLog.log_event("order.created", "Order placed")

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

      # System events hidden by default
      refute html =~ "Sync done"
      assert html =~ "Order placed"

      # Toggle shows system events
      html = render_click(view, "toggle_system")
      assert html =~ "Sync done"
      assert html =~ "Order placed"
    end
  end

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

    test "shows badge when attention items exist", %{conn: conn} do
      ActivityLog.log_event("order.submission_failed", "Something broke", level: "error")

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

      # The nav badge should show the count
      assert html =~ "admin-badge-warning"
    end

    test "hides badge when no attention items", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/admin/activity")

      # No badge should be rendered
      refute html =~ "admin-badge-warning"
    end
  end
end
