defmodule Berrypod.RedirectsIntegrationTest do
  # async: false because FTS5 search index is shared state
  use Berrypod.DataCase, async: false

  alias Berrypod.{Products, Redirects, Search}
  import Berrypod.ProductsFixtures

  setup do
    Redirects.create_table()
    :ok
  end

  describe "upsert_product/2 auto-redirect on slug change" do
    test "creates redirect when title changes" do
      conn = provider_connection_fixture(%{provider_type: "printify"})

      # Create product
      {:ok, product, :created} =
        Products.upsert_product(conn, %{
          title: "Classic Tee",
          provider_product_id: "slug-change-test",
          status: "active",
          visible: true,
          provider_data: %{"version" => 1}
        })

      assert product.slug == "classic-tee"

      # Update with different title (different checksum via provider_data)
      {:ok, updated, :updated} =
        Products.upsert_product(conn, %{
          title: "Classic Tee V2",
          provider_product_id: "slug-change-test",
          status: "active",
          visible: true,
          provider_data: %{"version" => 2}
        })

      assert updated.slug == "classic-tee-v2"

      # Redirect should exist
      assert {:ok, %{to_path: "/products/classic-tee-v2"}} =
               Redirects.lookup("/products/classic-tee")
    end

    test "does not create redirect when title is unchanged" do
      conn = provider_connection_fixture(%{provider_type: "printify"})

      {:ok, _product, :created} =
        Products.upsert_product(conn, %{
          title: "Unchanged Product",
          provider_product_id: "no-slug-change",
          status: "active",
          visible: true,
          provider_data: %{"version" => 1}
        })

      # Update with same title but different data
      {:ok, _updated, :updated} =
        Products.upsert_product(conn, %{
          title: "Unchanged Product",
          provider_product_id: "no-slug-change",
          status: "active",
          visible: true,
          description: "now with a description",
          provider_data: %{"version" => 2}
        })

      assert :not_found = Redirects.lookup("/products/unchanged-product")
    end
  end

  describe "delete_product/1 auto-redirect" do
    test "creates redirect to category collection page" do
      product = product_fixture(%{title: "Doomed Shirt", category: "T-Shirts"})

      {:ok, _} = Products.delete_product(product)

      assert {:ok, %{to_path: "/collections/t-shirts"}} =
               Redirects.lookup("/products/#{product.slug}")
    end

    test "creates redirect to / when no category" do
      product = product_fixture(%{title: "No Category Item", category: nil})

      {:ok, _} = Products.delete_product(product)

      assert {:ok, %{to_path: "/"}} =
               Redirects.lookup("/products/#{product.slug}")
    end
  end

  describe "attempt_auto_resolve/1" do
    test "creates redirect when FTS5 finds a single match" do
      # Product was renamed: "Classic Tee" -> "Classic Tee V2"
      # Old slug was "classic-tee", new slug is "classic-tee-v2"
      product =
        product_fixture(%{
          title: "Classic Tee V2",
          slug: "classic-tee-v2",
          category: "T-Shirts",
          visible: true,
          status: "active"
        })

      product_variant_fixture(%{product: product, title: "Medium / Black", price: 2500})
      Search.rebuild_index()

      # Record a broken URL for the old slug
      {:ok, _} = Redirects.record_broken_url("/products/classic-tee", 10)

      assert :resolved = Redirects.attempt_auto_resolve("/products/classic-tee")

      # Redirect should point to the matched product
      assert {:ok, %{to_path: "/products/classic-tee-v2"}} =
               Redirects.lookup("/products/classic-tee")

      # Broken URL should be marked resolved
      assert Redirects.list_broken_urls("pending") == []
    end

    test "returns :no_match when no search results" do
      Search.rebuild_index()

      assert :no_match = Redirects.attempt_auto_resolve("/products/totally-unique-nonexistent")
    end

    test "returns :no_match for non-product paths" do
      assert :no_match = Redirects.attempt_auto_resolve("/about")
      assert :no_match = Redirects.attempt_auto_resolve("/collections/old-category")
    end
  end
end
