defmodule BerrypodWeb.Shop.SearchIntegrationTest do
  use BerrypodWeb.ConnCase, async: false

  import Phoenix.LiveViewTest
  import Berrypod.AccountsFixtures
  import Berrypod.ProductsFixtures

  alias Berrypod.Search

  setup do
    user_fixture()
    {:ok, _} = Berrypod.Settings.set_site_live(true)

    pc = provider_connection_fixture()

    mountain =
      product_fixture(%{
        provider_connection: pc,
        title: "Mountain Sunrise Print",
        description: "A landscape scene at dawn",
        category: "Art Prints"
      })

    product_variant_fixture(%{product: mountain, title: "8x10", price: 1999})
    Berrypod.Products.recompute_cached_fields(mountain)

    ocean =
      product_fixture(%{
        provider_connection: pc,
        title: "Ocean Waves Notebook",
        description: "Spiral-bound notebook with ocean art",
        category: "Stationery"
      })

    product_variant_fixture(%{product: ocean, title: "A5", price: 1299})
    Berrypod.Products.recompute_cached_fields(ocean)

    Search.rebuild_index()

    %{mountain: mountain, ocean: ocean}
  end

  describe "search event" do
    test "returns matching products", %{conn: conn, mountain: mountain} do
      {:ok, view, _html} = live(conn, ~p"/")

      html = render_hook(view, "search", %{"value" => "mountain"})

      assert html =~ mountain.title
      assert html =~ ~p"/products/#{mountain.slug}"
    end

    test "shows no results message for unmatched query", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/")

      html = render_hook(view, "search", %{"value" => "xyznonexistent"})

      assert html =~ "No products found"
    end

    test "ignores short queries", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/")

      html = render_hook(view, "search", %{"value" => "a"})

      refute html =~ "No products found"
      refute html =~ ~s(role="option")
    end
  end

  describe "clear_search event" do
    test "resets search state", %{conn: conn, mountain: mountain} do
      {:ok, view, _html} = live(conn, ~p"/")

      # First search to get results
      html = render_hook(view, "search", %{"value" => "mountain"})
      assert html =~ mountain.title

      # Clear search
      html = render_hook(view, "clear_search", %{})

      refute html =~ ~s(No products found)
      # Results list should be gone
      refute html =~ ~s(role="option")
    end
  end

  describe "search results rendering" do
    test "result links use patch for LiveView navigation", %{conn: conn, mountain: mountain} do
      {:ok, view, _html} = live(conn, ~p"/")

      html = render_hook(view, "search", %{"value" => "mountain"})

      assert html =~ ~s(href="/products/#{mountain.slug}")
      assert html =~ ~s(data-phx-link="patch")
    end

    test "results have ARIA listbox and option roles", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/")

      html = render_hook(view, "search", %{"value" => "mountain"})

      assert html =~ ~s(role="listbox")
      assert html =~ ~s(role="option")
    end

    test "search input has combobox ARIA attributes", %{conn: conn} do
      {:ok, _view, html} = live(conn, ~p"/")

      assert html =~ ~s(role="combobox")
      assert html =~ ~s(aria-autocomplete="list")
      assert html =~ ~s(aria-controls="search-results-list")
    end

    test "multiple results render in order", %{conn: conn, mountain: mountain, ocean: ocean} do
      {:ok, view, _html} = live(conn, ~p"/")

      html = render_hook(view, "search", %{"value" => "print notebook"})

      assert html =~ mountain.title || html =~ ocean.title
    end

    test "shows category and price in results", %{conn: conn} do
      {:ok, view, _html} = live(conn, ~p"/")

      html = render_hook(view, "search", %{"value" => "mountain"})

      assert html =~ "Art Prints"
    end
  end
end
